mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-11 21:09:07 +08:00
glview can now load static geometry modified by sparse accessor
This commit is contained in:
parent
9223d3133a
commit
14d259f361
@ -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;
|
||||||
|
|
||||||
|
if (sparse_accessor < 0)
|
||||||
glBufferData(bufferView.target, bufferView.byteLength,
|
glBufferData(bufferView.target, bufferView.byteLength,
|
||||||
&buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
|
&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;
|
||||||
@ -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");
|
||||||
@ -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());
|
||||||
@ -833,7 +960,6 @@ int main(int argc, char **argv) {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user