glview can now load static geometry modified by sparse accessor

This commit is contained in:
Arthur Brainville (Ybalrid) 2019-03-06 14:48:44 +00:00
parent 9223d3133a
commit 14d259f361

View File

@ -28,7 +28,6 @@
#include "tiny_gltf.h" #include "tiny_gltf.h"
#endif #endif
#define BUFFER_OFFSET(i) ((char *)NULL + (i)) #define BUFFER_OFFSET(i) ((char *)NULL + (i))
#define CheckGLErrors(desc) \ #define CheckGLErrors(desc) \
@ -55,7 +54,9 @@ float eye[3], lookat[3], up[3];
GLFWwindow *window; GLFWwindow *window;
typedef struct { GLuint vb; } GLBufferState; typedef struct {
GLuint vb;
} GLBufferState;
typedef struct { typedef struct {
std::vector<GLuint> diffuseTex; // for each primitive in mesh std::vector<GLuint> diffuseTex; // for each primitive in mesh
@ -254,6 +255,26 @@ void motionFunc(GLFWwindow *window, double mouse_x, double mouse_y) {
prevMouseY = mouse_y; prevMouseY = mouse_y;
} }
static size_t ComponentTypeByteSize(int type) {
switch (type) {
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
case TINYGLTF_COMPONENT_TYPE_BYTE:
return sizeof(char);
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
case TINYGLTF_COMPONENT_TYPE_SHORT:
return sizeof(short);
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
case TINYGLTF_COMPONENT_TYPE_INT:
return sizeof(int);
case TINYGLTF_COMPONENT_TYPE_FLOAT:
return sizeof(float);
case TINYGLTF_COMPONENT_TYPE_DOUBLE:
return sizeof(double);
default:
return 0;
}
}
static void SetupMeshState(tinygltf::Model &model, GLuint progId) { static void SetupMeshState(tinygltf::Model &model, GLuint progId) {
// Buffer // Buffer
{ {
@ -264,14 +285,117 @@ static void SetupMeshState(tinygltf::Model &model, GLuint progId) {
continue; // Unsupported bufferView. continue; // Unsupported bufferView.
} }
int sparse_accessor = -1;
for (size_t a_i = 0; a_i < model.accessors.size(); ++a_i) {
const auto &accessor = model.accessors[a_i];
if (accessor.bufferView == i) {
std::cout << i << " is used by accessor " << a_i << std::endl;
if (accessor.sparse.isSparse) {
std::cout
<< "WARN: this bufferView has at least one sparse accessor to "
"it. We are going to load the data as patched by this "
"sparse accessor, not the original data"
<< std::endl;
sparse_accessor = a_i;
break;
}
}
}
const tinygltf::Buffer &buffer = model.buffers[bufferView.buffer]; const tinygltf::Buffer &buffer = model.buffers[bufferView.buffer];
GLBufferState state; GLBufferState state;
glGenBuffers(1, &state.vb); glGenBuffers(1, &state.vb);
glBindBuffer(bufferView.target, state.vb); glBindBuffer(bufferView.target, state.vb);
std::cout << "buffer.size= " << buffer.data.size() std::cout << "buffer.size= " << buffer.data.size()
<< ", byteOffset = " << bufferView.byteOffset << std::endl; << ", byteOffset = " << bufferView.byteOffset << std::endl;
glBufferData(bufferView.target, bufferView.byteLength,
&buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW); if (sparse_accessor < 0)
glBufferData(bufferView.target, bufferView.byteLength,
&buffer.data.at(0) + bufferView.byteOffset,
GL_STATIC_DRAW);
else {
const auto accessor = model.accessors[sparse_accessor];
// copy the buffer to a temporary one for sparse patching
unsigned char *tmp_buffer = new unsigned char[bufferView.byteLength];
memcpy(tmp_buffer, buffer.data.data() + bufferView.byteOffset,
bufferView.byteLength);
const size_t size_of_object_in_buffer =
ComponentTypeByteSize(accessor.componentType);
const size_t size_of_sparse_indices =
ComponentTypeByteSize(accessor.sparse.indices.componentType);
const auto &indices_buffer_view =
model.bufferViews[accessor.sparse.indices.bufferView];
const auto &indices_buffer = model.buffers[indices_buffer_view.buffer];
const auto &values_buffer_view =
model.bufferViews[accessor.sparse.values.bufferView];
const auto &values_buffer = model.buffers[values_buffer_view.buffer];
for (size_t sparse_index = 0; sparse_index < accessor.sparse.count;
++sparse_index) {
int index = 0;
// std::cout << "accessor.sparse.indices.componentType = " <<
// accessor.sparse.indices.componentType << std::endl;
switch (accessor.sparse.indices.componentType) {
case TINYGLTF_COMPONENT_TYPE_BYTE:
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
index = (int)*(
unsigned char *)(indices_buffer.data.data() +
indices_buffer_view.byteOffset +
accessor.sparse.indices.byteOffset +
(sparse_index * size_of_sparse_indices));
break;
case TINYGLTF_COMPONENT_TYPE_SHORT:
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
index = (int)*(
unsigned short *)(indices_buffer.data.data() +
indices_buffer_view.byteOffset +
accessor.sparse.indices.byteOffset +
(sparse_index * size_of_sparse_indices));
break;
case TINYGLTF_COMPONENT_TYPE_INT:
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
index = (int)*(
unsigned int *)(indices_buffer.data.data() +
indices_buffer_view.byteOffset +
accessor.sparse.indices.byteOffset +
(sparse_index * size_of_sparse_indices));
break;
}
std::cout << "updating sparse data at index : " << index
<< std::endl;
// index is now the target of the sparse index to patch in
const unsigned char *read_from =
values_buffer.data.data() +
(values_buffer_view.byteOffset +
accessor.sparse.values.byteOffset) +
(sparse_index * (size_of_object_in_buffer * accessor.type));
/*
std::cout << ((float*)read_from)[0] << "\n";
std::cout << ((float*)read_from)[1] << "\n";
std::cout << ((float*)read_from)[2] << "\n";
*/
unsigned char *write_to =
tmp_buffer + index * (size_of_object_in_buffer * accessor.type);
memcpy(write_to, read_from, size_of_object_in_buffer * accessor.type);
}
// debug:
/*for(size_t p = 0; p < bufferView.byteLength/sizeof(float); p++)
{
float* b = (float*)tmp_buffer;
std::cout << "modified_buffer [" << p << "] = " << b[p] << '\n';
}*/
glBufferData(bufferView.target, bufferView.byteLength, tmp_buffer,
GL_STATIC_DRAW);
delete[] tmp_buffer;
}
glBindBuffer(bufferView.target, 0); glBindBuffer(bufferView.target, 0);
gBufferState[i] = state; gBufferState[i] = state;
@ -279,55 +403,55 @@ static void SetupMeshState(tinygltf::Model &model, GLuint progId) {
} }
#if 0 // TODO(syoyo): Implement #if 0 // TODO(syoyo): Implement
// Texture // Texture
{ {
for (size_t i = 0; i < model.meshes.size(); i++) { for (size_t i = 0; i < model.meshes.size(); i++) {
const tinygltf::Mesh &mesh = model.meshes[i]; const tinygltf::Mesh &mesh = model.meshes[i];
gMeshState[mesh.name].diffuseTex.resize(mesh.primitives.size()); gMeshState[mesh.name].diffuseTex.resize(mesh.primitives.size());
for (size_t primId = 0; primId < mesh.primitives.size(); primId++) { for (size_t primId = 0; primId < mesh.primitives.size(); primId++) {
const tinygltf::Primitive &primitive = mesh.primitives[primId]; const tinygltf::Primitive &primitive = mesh.primitives[primId];
gMeshState[mesh.name].diffuseTex[primId] = 0; gMeshState[mesh.name].diffuseTex[primId] = 0;
if (primitive.material < 0) { if (primitive.material < 0) {
continue; continue;
} }
tinygltf::Material &mat = model.materials[primitive.material]; tinygltf::Material &mat = model.materials[primitive.material];
// printf("material.name = %s\n", mat.name.c_str()); // printf("material.name = %s\n", mat.name.c_str());
if (mat.values.find("diffuse") != mat.values.end()) { if (mat.values.find("diffuse") != mat.values.end()) {
std::string diffuseTexName = mat.values["diffuse"].string_value; std::string diffuseTexName = mat.values["diffuse"].string_value;
if (model.textures.find(diffuseTexName) != model.textures.end()) { if (model.textures.find(diffuseTexName) != model.textures.end()) {
tinygltf::Texture &tex = model.textures[diffuseTexName]; tinygltf::Texture &tex = model.textures[diffuseTexName];
if (scene.images.find(tex.source) != model.images.end()) { if (scene.images.find(tex.source) != model.images.end()) {
tinygltf::Image &image = model.images[tex.source]; tinygltf::Image &image = model.images[tex.source];
GLuint texId; GLuint texId;
glGenTextures(1, &texId); glGenTextures(1, &texId);
glBindTexture(tex.target, texId); glBindTexture(tex.target, texId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Ignore Texture.fomat. // Ignore Texture.fomat.
GLenum format = GL_RGBA; GLenum format = GL_RGBA;
if (image.component == 3) { if (image.component == 3) {
format = GL_RGB; format = GL_RGB;
} }
glTexImage2D(tex.target, 0, tex.internalFormat, image.width, glTexImage2D(tex.target, 0, tex.internalFormat, image.width,
image.height, 0, format, tex.type, image.height, 0, format, tex.type,
&image.image.at(0)); &image.image.at(0));
CheckErrors("texImage2D"); CheckErrors("texImage2D");
glBindTexture(tex.target, 0); glBindTexture(tex.target, 0);
printf("TexId = %d\n", texId); printf("TexId = %d\n", texId);
gMeshState[mesh.name].diffuseTex[primId] = texId; gMeshState[mesh.name].diffuseTex[primId] = texId;
} }
} }
} }
} }
} }
} }
#endif #endif
glUseProgram(progId); glUseProgram(progId);
@ -348,164 +472,164 @@ static void SetupMeshState(tinygltf::Model &model, GLuint progId) {
#if 0 // TODO(syoyo): Implement #if 0 // TODO(syoyo): Implement
// Setup curves geometry extension // Setup curves geometry extension
static void SetupCurvesState(tinygltf::Scene &scene, GLuint progId) { static void SetupCurvesState(tinygltf::Scene &scene, GLuint progId) {
// Find curves primitive. // Find curves primitive.
{ {
std::map<std::string, tinygltf::Mesh>::const_iterator it( std::map<std::string, tinygltf::Mesh>::const_iterator it(
scene.meshes.begin()); scene.meshes.begin());
std::map<std::string, tinygltf::Mesh>::const_iterator itEnd( std::map<std::string, tinygltf::Mesh>::const_iterator itEnd(
scene.meshes.end()); scene.meshes.end());
for (; it != itEnd; it++) { for (; it != itEnd; it++) {
const tinygltf::Mesh &mesh = it->second; const tinygltf::Mesh &mesh = it->second;
// Currently we only support one primitive per mesh. // Currently we only support one primitive per mesh.
if (mesh.primitives.size() > 1) { if (mesh.primitives.size() > 1) {
continue; continue;
} }
for (size_t primId = 0; primId < mesh.primitives.size(); primId++) { for (size_t primId = 0; primId < mesh.primitives.size(); primId++) {
const tinygltf::Primitive &primitive = mesh.primitives[primId]; const tinygltf::Primitive &primitive = mesh.primitives[primId];
gMeshState[mesh.name].diffuseTex[primId] = 0; gMeshState[mesh.name].diffuseTex[primId] = 0;
if (primitive.material.empty()) { if (primitive.material.empty()) {
continue; continue;
} }
bool has_curves = false; bool has_curves = false;
if (primitive.extras.IsObject()) { if (primitive.extras.IsObject()) {
if (primitive.extras.Has("ext_mode")) { if (primitive.extras.Has("ext_mode")) {
const tinygltf::Value::Object &o = const tinygltf::Value::Object &o =
primitive.extras.Get<tinygltf::Value::Object>(); primitive.extras.Get<tinygltf::Value::Object>();
const tinygltf::Value &ext_mode = o.find("ext_mode")->second; const tinygltf::Value &ext_mode = o.find("ext_mode")->second;
if (ext_mode.IsString()) { if (ext_mode.IsString()) {
const std::string &str = ext_mode.Get<std::string>(); const std::string &str = ext_mode.Get<std::string>();
if (str.compare("curves") == 0) { if (str.compare("curves") == 0) {
has_curves = true; has_curves = true;
} }
} }
} }
} }
if (!has_curves) { if (!has_curves) {
continue; continue;
} }
// Construct curves buffer // Construct curves buffer
const tinygltf::Accessor &vtx_accessor = const tinygltf::Accessor &vtx_accessor =
scene.accessors[primitive.attributes.find("POSITION")->second]; scene.accessors[primitive.attributes.find("POSITION")->second];
const tinygltf::Accessor &nverts_accessor = const tinygltf::Accessor &nverts_accessor =
scene.accessors[primitive.attributes.find("NVERTS")->second]; scene.accessors[primitive.attributes.find("NVERTS")->second];
const tinygltf::BufferView &vtx_bufferView = const tinygltf::BufferView &vtx_bufferView =
scene.bufferViews[vtx_accessor.bufferView]; scene.bufferViews[vtx_accessor.bufferView];
const tinygltf::BufferView &nverts_bufferView = const tinygltf::BufferView &nverts_bufferView =
scene.bufferViews[nverts_accessor.bufferView]; scene.bufferViews[nverts_accessor.bufferView];
const tinygltf::Buffer &vtx_buffer = const tinygltf::Buffer &vtx_buffer =
scene.buffers[vtx_bufferView.buffer]; scene.buffers[vtx_bufferView.buffer];
const tinygltf::Buffer &nverts_buffer = const tinygltf::Buffer &nverts_buffer =
scene.buffers[nverts_bufferView.buffer]; scene.buffers[nverts_bufferView.buffer];
// std::cout << "vtx_bufferView = " << vtx_accessor.bufferView << // std::cout << "vtx_bufferView = " << vtx_accessor.bufferView <<
// std::endl; // std::endl;
// std::cout << "nverts_bufferView = " << nverts_accessor.bufferView << // std::cout << "nverts_bufferView = " << nverts_accessor.bufferView <<
// std::endl; // std::endl;
// std::cout << "vtx_buffer.size = " << vtx_buffer.data.size() << // std::cout << "vtx_buffer.size = " << vtx_buffer.data.size() <<
// std::endl; // std::endl;
// std::cout << "nverts_buffer.size = " << nverts_buffer.data.size() << // std::cout << "nverts_buffer.size = " << nverts_buffer.data.size() <<
// std::endl; // std::endl;
const int *nverts = const int *nverts =
reinterpret_cast<const int *>(nverts_buffer.data.data()); reinterpret_cast<const int *>(nverts_buffer.data.data());
const float *vtx = const float *vtx =
reinterpret_cast<const float *>(vtx_buffer.data.data()); reinterpret_cast<const float *>(vtx_buffer.data.data());
// Convert to GL_LINES data. // Convert to GL_LINES data.
std::vector<float> line_pts; std::vector<float> line_pts;
size_t vtx_offset = 0; size_t vtx_offset = 0;
for (int k = 0; k < static_cast<int>(nverts_accessor.count); k++) { for (int k = 0; k < static_cast<int>(nverts_accessor.count); k++) {
for (int n = 0; n < nverts[k] - 1; n++) { for (int n = 0; n < nverts[k] - 1; n++) {
line_pts.push_back(vtx[3 * (vtx_offset + n) + 0]); line_pts.push_back(vtx[3 * (vtx_offset + n) + 0]);
line_pts.push_back(vtx[3 * (vtx_offset + n) + 1]); line_pts.push_back(vtx[3 * (vtx_offset + n) + 1]);
line_pts.push_back(vtx[3 * (vtx_offset + n) + 2]); line_pts.push_back(vtx[3 * (vtx_offset + n) + 2]);
line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 0]); line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 0]);
line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 1]); line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 1]);
line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 2]); line_pts.push_back(vtx[3 * (vtx_offset + n + 1) + 2]);
// std::cout << "p0 " << vtx[3 * (vtx_offset + n) + 0] << ", " // std::cout << "p0 " << vtx[3 * (vtx_offset + n) + 0] << ", "
// << vtx[3 * (vtx_offset + n) + 1] << ", " // << vtx[3 * (vtx_offset + n) + 1] << ", "
// << vtx[3 * (vtx_offset + n) + 2] << std::endl; // << vtx[3 * (vtx_offset + n) + 2] << std::endl;
// std::cout << "p1 " << vtx[3 * (vtx_offset + n+1) + 0] << ", " // std::cout << "p1 " << vtx[3 * (vtx_offset + n+1) + 0] << ", "
// << vtx[3 * (vtx_offset + n+1) + 1] << ", " // << vtx[3 * (vtx_offset + n+1) + 1] << ", "
// << vtx[3 * (vtx_offset + n+1) + 2] << std::endl; // << vtx[3 * (vtx_offset + n+1) + 2] << std::endl;
} }
vtx_offset += nverts[k]; vtx_offset += nverts[k];
} }
GLCurvesState state; GLCurvesState state;
glGenBuffers(1, &state.vb); glGenBuffers(1, &state.vb);
glBindBuffer(GL_ARRAY_BUFFER, state.vb); glBindBuffer(GL_ARRAY_BUFFER, state.vb);
glBufferData(GL_ARRAY_BUFFER, line_pts.size() * sizeof(float), glBufferData(GL_ARRAY_BUFFER, line_pts.size() * sizeof(float),
line_pts.data(), GL_STATIC_DRAW); line_pts.data(), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
state.count = line_pts.size() / 3; state.count = line_pts.size() / 3;
gCurvesMesh[mesh.name] = state; gCurvesMesh[mesh.name] = state;
// Material // Material
tinygltf::Material &mat = scene.materials[primitive.material]; tinygltf::Material &mat = scene.materials[primitive.material];
// printf("material.name = %s\n", mat.name.c_str()); // printf("material.name = %s\n", mat.name.c_str());
if (mat.values.find("diffuse") != mat.values.end()) { if (mat.values.find("diffuse") != mat.values.end()) {
std::string diffuseTexName = mat.values["diffuse"].string_value; std::string diffuseTexName = mat.values["diffuse"].string_value;
if (scene.textures.find(diffuseTexName) != scene.textures.end()) { if (scene.textures.find(diffuseTexName) != scene.textures.end()) {
tinygltf::Texture &tex = scene.textures[diffuseTexName]; tinygltf::Texture &tex = scene.textures[diffuseTexName];
if (scene.images.find(tex.source) != scene.images.end()) { if (scene.images.find(tex.source) != scene.images.end()) {
tinygltf::Image &image = scene.images[tex.source]; tinygltf::Image &image = scene.images[tex.source];
GLuint texId; GLuint texId;
glGenTextures(1, &texId); glGenTextures(1, &texId);
glBindTexture(tex.target, texId); glBindTexture(tex.target, texId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Ignore Texture.fomat. // Ignore Texture.fomat.
GLenum format = GL_RGBA; GLenum format = GL_RGBA;
if (image.component == 3) { if (image.component == 3) {
format = GL_RGB; format = GL_RGB;
} }
glTexImage2D(tex.target, 0, tex.internalFormat, image.width, glTexImage2D(tex.target, 0, tex.internalFormat, image.width,
image.height, 0, format, tex.type, image.height, 0, format, tex.type,
&image.image.at(0)); &image.image.at(0));
CheckErrors("texImage2D"); CheckErrors("texImage2D");
glBindTexture(tex.target, 0); glBindTexture(tex.target, 0);
printf("TexId = %d\n", texId); printf("TexId = %d\n", texId);
gMeshState[mesh.name].diffuseTex[primId] = texId; gMeshState[mesh.name].diffuseTex[primId] = texId;
} }
} }
} }
} }
} }
} }
glUseProgram(progId); glUseProgram(progId);
GLint vtloc = glGetAttribLocation(progId, "in_vertex"); GLint vtloc = glGetAttribLocation(progId, "in_vertex");
GLint nrmloc = glGetAttribLocation(progId, "in_normal"); GLint nrmloc = glGetAttribLocation(progId, "in_normal");
GLint uvloc = glGetAttribLocation(progId, "in_texcoord"); GLint uvloc = glGetAttribLocation(progId, "in_texcoord");
GLint diffuseTexLoc = glGetUniformLocation(progId, "diffuseTex"); GLint diffuseTexLoc = glGetUniformLocation(progId, "diffuseTex");
GLint isCurvesLoc = glGetUniformLocation(progId, "uIsCurves"); GLint isCurvesLoc = glGetUniformLocation(progId, "uIsCurves");
gGLProgramState.attribs["POSITION"] = vtloc; gGLProgramState.attribs["POSITION"] = vtloc;
gGLProgramState.attribs["NORMAL"] = nrmloc; gGLProgramState.attribs["NORMAL"] = nrmloc;
gGLProgramState.attribs["TEXCOORD_0"] = uvloc; gGLProgramState.attribs["TEXCOORD_0"] = uvloc;
gGLProgramState.uniforms["diffuseTex"] = diffuseTexLoc; gGLProgramState.uniforms["diffuseTex"] = diffuseTexLoc;
gGLProgramState.uniforms["uIsCurves"] = isCurvesLoc; gGLProgramState.uniforms["uIsCurves"] = isCurvesLoc;
}; };
#endif #endif
@ -558,12 +682,13 @@ static void DrawMesh(tinygltf::Model &model, const tinygltf::Mesh &mesh) {
(it->first.compare("TEXCOORD_0") == 0)) { (it->first.compare("TEXCOORD_0") == 0)) {
if (gGLProgramState.attribs[it->first] >= 0) { if (gGLProgramState.attribs[it->first] >= 0) {
// Compute byteStride from Accessor + BufferView combination. // Compute byteStride from Accessor + BufferView combination.
int byteStride = accessor.ByteStride(model.bufferViews[accessor.bufferView]); int byteStride =
accessor.ByteStride(model.bufferViews[accessor.bufferView]);
assert(byteStride != -1); assert(byteStride != -1);
glVertexAttribPointer(gGLProgramState.attribs[it->first], size, glVertexAttribPointer(gGLProgramState.attribs[it->first], size,
accessor.componentType, accessor.normalized ? GL_TRUE : GL_FALSE, accessor.componentType,
byteStride, accessor.normalized ? GL_TRUE : GL_FALSE,
BUFFER_OFFSET(accessor.byteOffset)); byteStride, BUFFER_OFFSET(accessor.byteOffset));
CheckErrors("vertex attrib pointer"); CheckErrors("vertex attrib pointer");
glEnableVertexAttribArray(gGLProgramState.attribs[it->first]); glEnableVertexAttribArray(gGLProgramState.attribs[it->first]);
CheckErrors("enable vertex attrib array"); CheckErrors("enable vertex attrib array");
@ -617,32 +742,32 @@ static void DrawMesh(tinygltf::Model &model, const tinygltf::Mesh &mesh) {
#if 0 // TODO(syoyo): Implement #if 0 // TODO(syoyo): Implement
static void DrawCurves(tinygltf::Scene &scene, const tinygltf::Mesh &mesh) { static void DrawCurves(tinygltf::Scene &scene, const tinygltf::Mesh &mesh) {
(void)scene; (void)scene;
if (gCurvesMesh.find(mesh.name) == gCurvesMesh.end()) { if (gCurvesMesh.find(mesh.name) == gCurvesMesh.end()) {
return; return;
} }
if (gGLProgramState.uniforms["isCurvesLoc"] >= 0) { if (gGLProgramState.uniforms["isCurvesLoc"] >= 0) {
glUniform1i(gGLProgramState.uniforms["isCurvesLoc"], 1); glUniform1i(gGLProgramState.uniforms["isCurvesLoc"], 1);
} }
GLCurvesState &state = gCurvesMesh[mesh.name]; GLCurvesState &state = gCurvesMesh[mesh.name];
if (gGLProgramState.attribs["POSITION"] >= 0) { if (gGLProgramState.attribs["POSITION"] >= 0) {
glBindBuffer(GL_ARRAY_BUFFER, state.vb); glBindBuffer(GL_ARRAY_BUFFER, state.vb);
glVertexAttribPointer(gGLProgramState.attribs["POSITION"], 3, GL_FLOAT, glVertexAttribPointer(gGLProgramState.attribs["POSITION"], 3, GL_FLOAT,
GL_FALSE, /* stride */ 0, BUFFER_OFFSET(0)); GL_FALSE, /* stride */ 0, BUFFER_OFFSET(0));
CheckErrors("curve: vertex attrib pointer"); CheckErrors("curve: vertex attrib pointer");
glEnableVertexAttribArray(gGLProgramState.attribs["POSITION"]); glEnableVertexAttribArray(gGLProgramState.attribs["POSITION"]);
CheckErrors("curve: enable vertex attrib array"); CheckErrors("curve: enable vertex attrib array");
} }
glDrawArrays(GL_LINES, 0, state.count); glDrawArrays(GL_LINES, 0, state.count);
if (gGLProgramState.attribs["POSITION"] >= 0) { if (gGLProgramState.attribs["POSITION"] >= 0) {
glDisableVertexAttribArray(gGLProgramState.attribs["POSITION"]); glDisableVertexAttribArray(gGLProgramState.attribs["POSITION"]);
} }
} }
#endif #endif
@ -693,16 +818,16 @@ static void DrawNode(tinygltf::Model &model, const tinygltf::Node &node) {
static void DrawModel(tinygltf::Model &model) { static void DrawModel(tinygltf::Model &model) {
#if 0 #if 0
std::map<std::string, tinygltf::Mesh>::const_iterator it(scene.meshes.begin()); std::map<std::string, tinygltf::Mesh>::const_iterator it(scene.meshes.begin());
std::map<std::string, tinygltf::Mesh>::const_iterator itEnd(scene.meshes.end()); std::map<std::string, tinygltf::Mesh>::const_iterator itEnd(scene.meshes.end());
for (; it != itEnd; it++) { for (; it != itEnd; it++) {
DrawMesh(scene, it->second); DrawMesh(scene, it->second);
DrawCurves(scene, it->second); DrawCurves(scene, it->second);
} }
#else #else
//If the glTF asset has at least one scene, and doesn't define a default one // If the glTF asset has at least one scene, and doesn't define a default one
//just show the first one we can find // just show the first one we can find
assert(model.scenes.size() > 0); assert(model.scenes.size() > 0);
int scene_to_display = model.defaultScene > -1 ? model.defaultScene : 0; int scene_to_display = model.defaultScene > -1 ? model.defaultScene : 0;
const tinygltf::Scene &scene = model.scenes[scene_to_display]; const tinygltf::Scene &scene = model.scenes[scene_to_display];
@ -752,7 +877,8 @@ int main(int argc, char **argv) {
#ifdef _WIN32 #ifdef _WIN32
#ifdef _DEBUG #ifdef _DEBUG
std::string input_filename(argv[1] ? argv[1] : "../../../models/Cube/Cube.gltf"); std::string input_filename(argv[1] ? argv[1]
: "../../../models/Cube/Cube.gltf");
#endif #endif
#else #else
std::string input_filename(argv[1] ? argv[1] : "../../models/Cube/Cube.gltf"); std::string input_filename(argv[1] ? argv[1] : "../../models/Cube/Cube.gltf");
@ -763,7 +889,8 @@ int main(int argc, char **argv) {
bool ret = false; bool ret = false;
if (ext.compare("glb") == 0) { if (ext.compare("glb") == 0) {
// assume binary glTF. // assume binary glTF.
ret = loader.LoadBinaryFromFile(&model, &err, &warn, input_filename.c_str()); ret =
loader.LoadBinaryFromFile(&model, &err, &warn, input_filename.c_str());
} else { } else {
// assume ascii glTF. // assume ascii glTF.
ret = loader.LoadASCIIFromFile(&model, &err, &warn, input_filename.c_str()); ret = loader.LoadASCIIFromFile(&model, &err, &warn, input_filename.c_str());
@ -825,15 +952,14 @@ int main(int argc, char **argv) {
#ifdef _WIN32 #ifdef _WIN32
#ifdef _DEBUG #ifdef _DEBUG
const char *shader_frag_filename = "../shader.frag"; const char *shader_frag_filename = "../shader.frag";
const char *shader_vert_filename = "../shader.vert"; const char *shader_vert_filename = "../shader.vert";
#endif #endif
#else #else
const char *shader_frag_filename = "shader.frag"; const char *shader_frag_filename = "shader.frag";
const char *shader_vert_filename = "shader.vert"; const char *shader_vert_filename = "shader.vert";
#endif #endif
if (false == LoadShader(GL_VERTEX_SHADER, vertId, shader_vert_filename)) { if (false == LoadShader(GL_VERTEX_SHADER, vertId, shader_vert_filename)) {
return -1; return -1;
} }