mirror of
https://git.mirrors.martin98.com/https://github.com/syoyo/tinygltf.git
synced 2025-08-11 13:18:58 +08:00
Initial GL rendering support of curves primitive(render as GL_LINES).
This commit is contained in:
parent
8038965d33
commit
ebce2521b2
@ -57,6 +57,7 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GLuint vb; // vertex buffer
|
GLuint vb; // vertex buffer
|
||||||
|
size_t count; // byte count
|
||||||
} GLCurvesState;
|
} GLCurvesState;
|
||||||
|
|
||||||
std::map<std::string, GLBufferState> gBufferState;
|
std::map<std::string, GLBufferState> gBufferState;
|
||||||
@ -318,11 +319,13 @@ static void SetupGLState(tinygltf::Scene &scene, GLuint progId) {
|
|||||||
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");
|
||||||
|
|
||||||
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["isCurvesLoc"] = isCurvesLoc;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Setup curves geometry extension
|
// Setup curves geometry extension
|
||||||
@ -378,10 +381,10 @@ static void SetupCurvesState(tinygltf::Scene &scene, GLuint progId) {
|
|||||||
const tinygltf::Buffer &vtx_buffer = scene.buffers[vtx_bufferView.buffer];
|
const tinygltf::Buffer &vtx_buffer = scene.buffers[vtx_bufferView.buffer];
|
||||||
const tinygltf::Buffer &nverts_buffer = scene.buffers[nverts_bufferView.buffer];
|
const tinygltf::Buffer &nverts_buffer = scene.buffers[nverts_bufferView.buffer];
|
||||||
|
|
||||||
std::cout << "vtx_bufferView = " << vtx_accessor.bufferView << std::endl;
|
//std::cout << "vtx_bufferView = " << vtx_accessor.bufferView << std::endl;
|
||||||
std::cout << "nverts_bufferView = " << nverts_accessor.bufferView << std::endl;
|
//std::cout << "nverts_bufferView = " << nverts_accessor.bufferView << std::endl;
|
||||||
std::cout << "vtx_buffer.size = " << vtx_buffer.data.size() << std::endl;
|
//std::cout << "vtx_buffer.size = " << vtx_buffer.data.size() << std::endl;
|
||||||
std::cout << "nverts_buffer.size = " << nverts_buffer.data.size() << std::endl;
|
//std::cout << "nverts_buffer.size = " << nverts_buffer.data.size() << std::endl;
|
||||||
|
|
||||||
const int *nverts = reinterpret_cast<const int*>(nverts_buffer.data.data());
|
const int *nverts = reinterpret_cast<const int*>(nverts_buffer.data.data());
|
||||||
const float *vtx = reinterpret_cast<const float*>(vtx_buffer.data.data());
|
const float *vtx = reinterpret_cast<const float*>(vtx_buffer.data.data());
|
||||||
@ -400,6 +403,7 @@ static void SetupCurvesState(tinygltf::Scene &scene, GLuint progId) {
|
|||||||
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]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vtx_offset += nverts[k];
|
vtx_offset += nverts[k];
|
||||||
@ -412,6 +416,9 @@ static void SetupCurvesState(tinygltf::Scene &scene, GLuint progId) {
|
|||||||
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 / 2; // 2 = GL_LINES
|
||||||
|
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());
|
||||||
@ -455,24 +462,31 @@ static void SetupCurvesState(tinygltf::Scene &scene, GLuint progId) {
|
|||||||
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");
|
||||||
|
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
void DrawMesh(tinygltf::Scene &scene, const tinygltf::Mesh &mesh) {
|
void DrawMesh(tinygltf::Scene &scene, const tinygltf::Mesh &mesh) {
|
||||||
|
|
||||||
if (gGLProgramState.uniforms["diffuseTex"] >= 0) {
|
|
||||||
glUniform1i(gGLProgramState.uniforms["diffuseTex"], 0); // TEXTURE0
|
|
||||||
}
|
|
||||||
|
|
||||||
// Skip curves primitive.
|
// Skip curves primitive.
|
||||||
if (gCurvesMesh.find(mesh.name) != gCurvesMesh.end()) {
|
if (gCurvesMesh.find(mesh.name) != gCurvesMesh.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gGLProgramState.uniforms["diffuseTex"] >= 0) {
|
||||||
|
glUniform1i(gGLProgramState.uniforms["diffuseTex"], 0); // TEXTURE0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gGLProgramState.uniforms["isCurvesLoc"] >= 0) {
|
||||||
|
glUniform1i(gGLProgramState.uniforms["isCurvesLoc"], 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
for (size_t i = 0; i < mesh.primitives.size(); i++) {
|
for (size_t i = 0; i < mesh.primitives.size(); i++) {
|
||||||
const tinygltf::Primitive &primitive = mesh.primitives[i];
|
const tinygltf::Primitive &primitive = mesh.primitives[i];
|
||||||
|
|
||||||
@ -509,14 +523,14 @@ void DrawMesh(tinygltf::Scene &scene, const tinygltf::Mesh &mesh) {
|
|||||||
(it->first.compare("NORMAL") == 0) ||
|
(it->first.compare("NORMAL") == 0) ||
|
||||||
(it->first.compare("TEXCOORD_0") == 0)) {
|
(it->first.compare("TEXCOORD_0") == 0)) {
|
||||||
|
|
||||||
if (gGLProgramState.attribs[it->first] >= 0) {
|
if (gGLProgramState.attribs[it->first] >= 0) {
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
gGLProgramState.attribs[it->first], count, accessor.componentType,
|
gGLProgramState.attribs[it->first], count, accessor.componentType,
|
||||||
GL_FALSE, accessor.byteStride, BUFFER_OFFSET(accessor.byteOffset));
|
GL_FALSE, accessor.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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,98 +579,32 @@ void DrawMesh(tinygltf::Scene &scene, const tinygltf::Mesh &mesh) {
|
|||||||
|
|
||||||
void DrawCurves(tinygltf::Scene &scene, const tinygltf::Mesh &mesh) {
|
void DrawCurves(tinygltf::Scene &scene, const tinygltf::Mesh &mesh) {
|
||||||
|
|
||||||
if (gGLProgramState.uniforms["diffuseTex"] >= 0) {
|
(void)scene;
|
||||||
glUniform1i(gGLProgramState.uniforms["diffuseTex"], 0); // TEXTURE0
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gCurvesMesh.find(mesh.name) == gCurvesMesh.end()) {
|
if (gCurvesMesh.find(mesh.name) == gCurvesMesh.end()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < mesh.primitives.size(); i++) {
|
if (gGLProgramState.uniforms["isCurvesLoc"] >= 0) {
|
||||||
const tinygltf::Primitive &primitive = mesh.primitives[i];
|
glUniform1i(gGLProgramState.uniforms["isCurvesLoc"], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLCurvesState &state = gCurvesMesh[mesh.name];
|
||||||
|
|
||||||
std::map<std::string, std::string>::const_iterator it(
|
if (gGLProgramState.attribs["POSITION"] >= 0) {
|
||||||
primitive.attributes.begin());
|
glBindBuffer(GL_ARRAY_BUFFER, state.vb);
|
||||||
std::map<std::string, std::string>::const_iterator itEnd(
|
glVertexAttribPointer(
|
||||||
primitive.attributes.end());
|
gGLProgramState.attribs["POSITION"], 3, GL_FLOAT,
|
||||||
|
GL_FALSE, /* stride */0, BUFFER_OFFSET(0));
|
||||||
|
CheckErrors("curve: vertex attrib pointer");
|
||||||
|
glEnableVertexAttribArray(gGLProgramState.attribs["POSITION"]);
|
||||||
|
CheckErrors("curve: enable vertex attrib array");
|
||||||
|
}
|
||||||
|
|
||||||
// Assume TEXTURE_2D target for the texture object.
|
glDrawArrays(GL_LINES, 0, state.count);
|
||||||
glBindTexture(GL_TEXTURE_2D, gMeshState[mesh.name].diffuseTex[i]);
|
|
||||||
|
|
||||||
for (; it != itEnd; it++) {
|
if (gGLProgramState.attribs["POSITION"] >= 0) {
|
||||||
const tinygltf::Accessor &accessor = scene.accessors[it->second];
|
glDisableVertexAttribArray(gGLProgramState.attribs["POSITION"]);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, gBufferState[accessor.bufferView].vb);
|
|
||||||
CheckErrors("bind buffer");
|
|
||||||
int count = 1;
|
|
||||||
if (accessor.type == TINYGLTF_TYPE_SCALAR) {
|
|
||||||
count = 1;
|
|
||||||
} else if (accessor.type == TINYGLTF_TYPE_VEC2) {
|
|
||||||
count = 2;
|
|
||||||
} else if (accessor.type == TINYGLTF_TYPE_VEC3) {
|
|
||||||
count = 3;
|
|
||||||
} else if (accessor.type == TINYGLTF_TYPE_VEC4) {
|
|
||||||
count = 4;
|
|
||||||
} else {
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
// it->first would be "POSITION", "NORMAL", "TEXCOORD_0", ...
|
|
||||||
if ((it->first.compare("POSITION") == 0) ||
|
|
||||||
(it->first.compare("NORMAL") == 0) ||
|
|
||||||
(it->first.compare("TEXCOORD_0") == 0)) {
|
|
||||||
|
|
||||||
if (gGLProgramState.attribs[it->first] >= 0) {
|
|
||||||
glVertexAttribPointer(
|
|
||||||
gGLProgramState.attribs[it->first], count, accessor.componentType,
|
|
||||||
GL_FALSE, accessor.byteStride, BUFFER_OFFSET(accessor.byteOffset));
|
|
||||||
CheckErrors("vertex attrib pointer");
|
|
||||||
glEnableVertexAttribArray(gGLProgramState.attribs[it->first]);
|
|
||||||
CheckErrors("enable vertex attrib array");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const tinygltf::Accessor &indexAccessor = scene.accessors[primitive.indices];
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
|
|
||||||
gBufferState[indexAccessor.bufferView].vb);
|
|
||||||
CheckErrors("bind buffer");
|
|
||||||
int mode = -1;
|
|
||||||
if (primitive.mode == TINYGLTF_MODE_TRIANGLES) {
|
|
||||||
mode = GL_TRIANGLES;
|
|
||||||
} else if (primitive.mode == TINYGLTF_MODE_TRIANGLE_STRIP) {
|
|
||||||
mode = GL_TRIANGLE_STRIP;
|
|
||||||
} else if (primitive.mode == TINYGLTF_MODE_TRIANGLE_FAN) {
|
|
||||||
mode = GL_TRIANGLE_FAN;
|
|
||||||
} else if (primitive.mode == TINYGLTF_MODE_POINTS) {
|
|
||||||
mode = GL_POINTS;
|
|
||||||
} else if (primitive.mode == TINYGLTF_MODE_LINE) {
|
|
||||||
mode = GL_LINES;
|
|
||||||
} else if (primitive.mode == TINYGLTF_MODE_LINE_LOOP) {
|
|
||||||
mode = GL_LINE_LOOP;
|
|
||||||
} else {
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
glDrawElements(mode, indexAccessor.count, indexAccessor.componentType,
|
|
||||||
BUFFER_OFFSET(indexAccessor.byteOffset));
|
|
||||||
CheckErrors("draw elements");
|
|
||||||
|
|
||||||
{
|
|
||||||
std::map<std::string, std::string>::const_iterator it(
|
|
||||||
primitive.attributes.begin());
|
|
||||||
std::map<std::string, std::string>::const_iterator itEnd(
|
|
||||||
primitive.attributes.end());
|
|
||||||
|
|
||||||
for (; it != itEnd; it++) {
|
|
||||||
if ((it->first.compare("POSITION") == 0) ||
|
|
||||||
(it->first.compare("NORMAL") == 0) ||
|
|
||||||
(it->first.compare("TEXCOORD_0") == 0)) {
|
|
||||||
if (gGLProgramState.attribs[it->first] >= 0) {
|
|
||||||
glDisableVertexAttribArray(gGLProgramState.attribs[it->first]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -666,6 +614,7 @@ void DrawScene(tinygltf::Scene &scene) {
|
|||||||
|
|
||||||
for (; it != itEnd; it++) {
|
for (; it != itEnd; it++) {
|
||||||
DrawMesh(scene, it->second);
|
DrawMesh(scene, it->second);
|
||||||
|
DrawCurves(scene, it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
uniform sampler2D diffuseTex;
|
uniform sampler2D diffuseTex;
|
||||||
|
uniform int uIsCurve;
|
||||||
|
|
||||||
varying vec3 normal;
|
varying vec3 normal;
|
||||||
varying vec2 texcoord;
|
varying vec2 texcoord;
|
||||||
@ -7,5 +8,9 @@ void main(void)
|
|||||||
{
|
{
|
||||||
//gl_FragColor = vec4(0.5 * normalize(normal) + 0.5, 1.0);
|
//gl_FragColor = vec4(0.5 * normalize(normal) + 0.5, 1.0);
|
||||||
//gl_FragColor = vec4(texcoord, 0.0, 1.0);
|
//gl_FragColor = vec4(texcoord, 0.0, 1.0);
|
||||||
gl_FragColor = texture2D(diffuseTex, texcoord);
|
if (uIsCurve > 0) {
|
||||||
|
gl_FragColor = texture2D(diffuseTex, texcoord);
|
||||||
|
} else {
|
||||||
|
gl_FragColor = vec4(0.5, 0.6, 0.7, 1.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user