Can now draw mesh hierarchies from gltf files (no textures, not yet animated)
parent
07fbfb3c8c
commit
eb189326b1
|
@ -558,6 +558,8 @@ void Renderer::RenderScene(RenderProgram &program, const Camera& camera) {
|
||||||
program.SetMat44("uModelMatrix", Matrix44f::Identity());
|
program.SetMat44("uModelMatrix", Matrix44f::Identity());
|
||||||
program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f));
|
program.SetVec4("uColor", Vector4f (1.0f, 1.0f, 1.0f, 1.0f));
|
||||||
gXZPlaneMesh.Draw(GL_TRIANGLES);
|
gXZPlaneMesh.Draw(GL_TRIANGLES);
|
||||||
|
|
||||||
|
gAssetFile.DrawModel(program);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::DrawGui() {
|
void Renderer::DrawGui() {
|
||||||
|
|
|
@ -554,7 +554,7 @@ void VertexArray::Bind() {
|
||||||
// Attribute 0: coords
|
// Attribute 0: coords
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
0,
|
VertexAttributePosition,
|
||||||
4,
|
4,
|
||||||
GL_FLOAT,
|
GL_FLOAT,
|
||||||
GL_FALSE,
|
GL_FALSE,
|
||||||
|
@ -564,7 +564,7 @@ void VertexArray::Bind() {
|
||||||
// Attribute 1: normals
|
// Attribute 1: normals
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
1,
|
VertexAttributeNormal,
|
||||||
3,
|
3,
|
||||||
GL_FLOAT,
|
GL_FLOAT,
|
||||||
GL_FALSE,
|
GL_FALSE,
|
||||||
|
@ -574,17 +574,17 @@ void VertexArray::Bind() {
|
||||||
// Attribute 2: texture coordinates
|
// Attribute 2: texture coordinates
|
||||||
glEnableVertexAttribArray(2);
|
glEnableVertexAttribArray(2);
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
2,
|
VertexAttributeTexCoord0,
|
||||||
2,
|
2,
|
||||||
GL_FLOAT,
|
GL_FLOAT,
|
||||||
GL_FALSE,
|
GL_FALSE,
|
||||||
(sizeof(VertexData)),
|
(sizeof(VertexData)),
|
||||||
(void*)(sizeof(float) * 7)
|
(void*)(sizeof(float) * 7)
|
||||||
);
|
);
|
||||||
// Attribute 1: color
|
// Attribute 3: color
|
||||||
glEnableVertexAttribArray(3);
|
glEnableVertexAttribArray(3);
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
3,
|
VertexAttributeColor,
|
||||||
4,
|
4,
|
||||||
GL_UNSIGNED_BYTE,
|
GL_UNSIGNED_BYTE,
|
||||||
GL_TRUE,
|
GL_TRUE,
|
||||||
|
@ -761,13 +761,22 @@ void AssetFile::LoadBuffers() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PrimitiveType {
|
VertexAttributeType AssetFile::GetVertexAttributeType(const std::string &attribute_string) const {
|
||||||
PrimitivePosition = 1,
|
VertexAttributeType attribute_type;
|
||||||
PrimitiveNormal,
|
if (attribute_string.compare("POSITION") == 0) {
|
||||||
PrimitiveTexCoord0
|
attribute_type = VertexAttributePosition;
|
||||||
};
|
} else if (attribute_string.compare("NORMAL") == 0) {
|
||||||
|
attribute_type = VertexAttributeNormal;
|
||||||
|
} else if (attribute_string.compare("TEXCOORD_0") == 0) {
|
||||||
|
attribute_type = VertexAttributeTexCoord0;
|
||||||
|
} else {
|
||||||
|
attribute_type = VertexAttributeTypeCount;
|
||||||
|
}
|
||||||
|
|
||||||
void AssetFile::DrawMesh(const tinygltf::Mesh &mesh, const Matrix44f& matrix) {
|
return attribute_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetFile::DrawMesh(const tinygltf::Mesh &mesh, const Matrix44f& matrix) const {
|
||||||
for (int i = 0, n = mesh.primitives.size(); i < n; ++i) {
|
for (int i = 0, n = mesh.primitives.size(); i < n; ++i) {
|
||||||
const tinygltf::Primitive& primitive = mesh.primitives[i];
|
const tinygltf::Primitive& primitive = mesh.primitives[i];
|
||||||
|
|
||||||
|
@ -792,35 +801,64 @@ void AssetFile::DrawMesh(const tinygltf::Mesh &mesh, const Matrix44f& matrix) {
|
||||||
default: assert(0); break;
|
default: assert(0); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrimitiveType primitive_type;
|
VertexAttributeType attribute_type = GetVertexAttributeType(it->first);
|
||||||
if (it->first.compare("POSITION") == 0) {
|
|
||||||
primitive_type = PrimitivePosition;
|
|
||||||
} else if (it->first.compare("NORMAL") == 0) {
|
|
||||||
primitive_type = PrimitiveNormal;
|
|
||||||
} else if (it->first.compare("TEXCOORD_0") == 0) {
|
|
||||||
primitive_type = PrimitiveTexCoord0;
|
|
||||||
} else {
|
|
||||||
gLog("Invalid primitive type: %s", it->first.c_str());
|
|
||||||
assert(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((it->first.compare("POSITION") == 0)
|
if (attribute_type != VertexAttributeTypeCount) {
|
||||||
|| (it->first.compare("NORMAL") == 0)
|
|
||||||
|| (it->first.compare("TEXCOORD_0") == 0)) {
|
|
||||||
int byte_stride = accessor.ByteStride(mGLTFModel.bufferViews[accessor.bufferView]);
|
int byte_stride = accessor.ByteStride(mGLTFModel.bufferViews[accessor.bufferView]);
|
||||||
assert(byte_stride != -1);
|
assert(byte_stride != -1);
|
||||||
|
|
||||||
|
glVertexAttribPointer(
|
||||||
|
attribute_type,
|
||||||
|
size,
|
||||||
|
accessor.componentType,
|
||||||
|
accessor.normalized ? GL_TRUE : GL_FALSE,
|
||||||
|
byte_stride,
|
||||||
|
(char *)NULL + accessor.byteOffset);
|
||||||
|
glEnableVertexAttribArray(attribute_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const tinygltf::Accessor& index_accessor = mGLTFModel.accessors[primitive.indices];
|
||||||
|
glBindBuffer(
|
||||||
|
GL_ELEMENT_ARRAY_BUFFER,
|
||||||
|
mBuffers[index_accessor.bufferView]
|
||||||
|
);
|
||||||
|
|
||||||
|
int mode = -1;
|
||||||
|
switch (primitive.mode) {
|
||||||
|
case TINYGLTF_MODE_TRIANGLES : mode = GL_TRIANGLES; break;
|
||||||
|
case TINYGLTF_MODE_TRIANGLE_STRIP: mode = GL_TRIANGLE_STRIP; break;
|
||||||
|
case TINYGLTF_MODE_TRIANGLE_FAN: mode = GL_TRIANGLE_FAN; break;
|
||||||
|
case TINYGLTF_MODE_POINTS: mode = GL_POINTS; break;
|
||||||
|
case TINYGLTF_MODE_LINE: mode = GL_LINES; break;
|
||||||
|
case TINYGLTF_MODE_LINE_LOOP: mode = GL_LINE_LOOP; break;
|
||||||
|
default: gLog("Invalid primitive mode: %d", primitive.mode); assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
glDrawElements(
|
||||||
|
mode,
|
||||||
|
index_accessor.count,
|
||||||
|
index_accessor.componentType,
|
||||||
|
(char *)NULL + index_accessor.byteOffset
|
||||||
|
);
|
||||||
|
|
||||||
|
for (; it != it_end; it++) {
|
||||||
|
VertexAttributeType attribute_type = GetVertexAttributeType(it->first);
|
||||||
|
if (attribute_type != VertexAttributeTypeCount) {
|
||||||
|
glDisableVertexAttribArray(attribute_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetFile::DrawNode(const tinygltf::Node &node, const Matrix44f& matrix) {
|
void AssetFile::DrawNode(RenderProgram &program, const tinygltf::Node &node, const Matrix44f& matrix) const {
|
||||||
Matrix44f local_matrix = matrix;
|
Matrix44f local_matrix = matrix;
|
||||||
if (node.matrix.size() == 16) {
|
if (node.matrix.size() == 16) {
|
||||||
|
// convert the matrix from double to float
|
||||||
Matrix44f mat;
|
Matrix44f mat;
|
||||||
memcpy(mat.data(), node.matrix.data(), sizeof(float) * 4);
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
mat.data()[i] = node.matrix.data()[i];
|
||||||
|
}
|
||||||
local_matrix *= mat;
|
local_matrix *= mat;
|
||||||
} else {
|
} else {
|
||||||
if (node.scale.size() == 3) {
|
if (node.scale.size() == 3) {
|
||||||
|
@ -836,20 +874,23 @@ void AssetFile::DrawNode(const tinygltf::Node &node, const Matrix44f& matrix) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (node.mesh >= 0) {
|
||||||
|
program.SetMat44("uModelMatrix", local_matrix);
|
||||||
DrawMesh (mGLTFModel.meshes[node.mesh], local_matrix);
|
DrawMesh (mGLTFModel.meshes[node.mesh], local_matrix);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < node.children.size(); ++i) {
|
for (int i = 0; i < node.children.size(); ++i) {
|
||||||
DrawNode(mGLTFModel.nodes[node.children[i]], matrix);
|
DrawNode(program, mGLTFModel.nodes[node.children[i]], local_matrix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetFile::DrawModel() {
|
void AssetFile::DrawModel(RenderProgram& program) const {
|
||||||
// todo: support non-default scenes
|
// todo: support non-default scenes
|
||||||
assert(mGLTFModel.defaultScene >= 0);
|
assert(mGLTFModel.defaultScene >= 0);
|
||||||
const tinygltf::Scene &scene = mGLTFModel.scenes[mGLTFModel.defaultScene];
|
const tinygltf::Scene &scene = mGLTFModel.scenes[mGLTFModel.defaultScene];
|
||||||
for (int i = 0; i < scene.nodes.size(); ++i) {
|
for (int i = 0; i < scene.nodes.size(); ++i) {
|
||||||
const tinygltf::Node &node = mGLTFModel.nodes[scene.nodes[i]];
|
const tinygltf::Node &node = mGLTFModel.nodes[scene.nodes[i]];
|
||||||
DrawNode(node, Matrix44f::Identity());
|
DrawNode(program, node, RotateMat44(90, 0.0, 0.0, 1.0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -289,6 +289,14 @@ struct Texture {
|
||||||
bool Load(const char* path, int num_components = 3);
|
bool Load(const char* path, int num_components = 3);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum VertexAttributeType {
|
||||||
|
VertexAttributePosition = 0,
|
||||||
|
VertexAttributeNormal = 1,
|
||||||
|
VertexAttributeTexCoord0 = 2,
|
||||||
|
VertexAttributeColor = 3,
|
||||||
|
VertexAttributeTypeCount
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage for (multiple) VertexArrayMeshes
|
* Storage for (multiple) VertexArrayMeshes
|
||||||
* Storage order is:
|
* Storage order is:
|
||||||
|
@ -422,9 +430,12 @@ struct AssetFile {
|
||||||
|
|
||||||
bool Load(const char* filename);
|
bool Load(const char* filename);
|
||||||
void LoadBuffers();
|
void LoadBuffers();
|
||||||
void DrawMesh(const tinygltf::Mesh &mesh, const Matrix44f &matrix);
|
VertexAttributeType GetVertexAttributeType(const std::string &attribute_string) const;
|
||||||
void DrawNode(const tinygltf::Node &node, const Matrix44f &matrix);
|
void DrawMesh(const tinygltf::Mesh &mesh, const Matrix44f &matrix) const;
|
||||||
void DrawModel();
|
void DrawNode(RenderProgram& program, const tinygltf::Node &node, const Matrix44f &matrix) const;
|
||||||
|
void DrawModel(RenderProgram& program) const;
|
||||||
|
|
||||||
|
// Debug UI
|
||||||
void DrawNodeGui(const tinygltf::Node& node);
|
void DrawNodeGui(const tinygltf::Node& node);
|
||||||
void DrawGui();
|
void DrawGui();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue