texture support.

This commit is contained in:
Syoyo Fujita 2016-02-07 17:38:17 +09:00
parent b495603c67
commit bde7021b94
6 changed files with 432 additions and 193 deletions

View File

@ -18,6 +18,7 @@ Simple OpenGL viewer for glTF geometry.
## TODO
* [ ] Texture
* [x] Texture
* [ ] Various texture format.
* [ ] Shader
* [ ] Animation

View File

@ -20,6 +20,16 @@
#define BUFFER_OFFSET(i) ((char *)NULL + (i))
#define CheckGLErrors(desc) \
{ \
GLenum e = glGetError(); \
if (e != GL_NO_ERROR) { \
printf("OpenGL error in \"%s\": %d (%d) %s:%d\n", desc, e, e, __FILE__, \
__LINE__); \
exit(20); \
} \
}
#define CAM_Z (3.0f)
int width = 768;
int height = 768;
@ -34,17 +44,19 @@ float eye[3], lookat[3], up[3];
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
} GLMeshState;
typedef struct {
std::map<std::string, GLint> attribs;
std::map<std::string, GLint> uniforms;
} GLProgramState;
std::map<std::string, GLBufferState> gBufferState;
std::map<std::string, GLMeshState> gMeshState;
GLProgramState gGLProgramState;
void CheckErrors(std::string desc) {
@ -122,8 +134,7 @@ bool LinkShader(GLuint &prog, GLuint &vertShader, GLuint &fragShader) {
return true;
}
void reshapeFunc(GLFWwindow* window, int w, int h)
{
void reshapeFunc(GLFWwindow *window, int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@ -135,10 +146,12 @@ void reshapeFunc(GLFWwindow* window, int w, int h)
height = h;
}
void keyboardFunc(GLFWwindow *window, int key, int scancode, int action, int mods) {
void keyboardFunc(GLFWwindow *window, int key, int scancode, int action,
int mods) {
if (action == GLFW_PRESS || action == GLFW_REPEAT) {
// Close window
if(key == GLFW_KEY_Q || key == GLFW_KEY_ESCAPE) glfwSetWindowShouldClose(window, GL_TRUE);
if (key == GLFW_KEY_Q || key == GLFW_KEY_ESCAPE)
glfwSetWindowShouldClose(window, GL_TRUE);
}
}
@ -179,8 +192,7 @@ void motionFunc(GLFWwindow* window, double mouse_x, double mouse_y){
float transScale = 2.0f;
if (mouseLeftPressed) {
trackball(prev_quat,
rotScale * (2.0f * prevMouseX - width) / (float)width,
trackball(prev_quat, rotScale * (2.0f * prevMouseX - width) / (float)width,
rotScale * (height - 2.0f * prevMouseY) / (float)height,
rotScale * (2.0f * mouse_x - width) / (float)width,
rotScale * (height - 2.0f * mouse_y) / (float)height);
@ -201,10 +213,13 @@ void motionFunc(GLFWwindow* window, double mouse_x, double mouse_y){
prevMouseY = mouse_y;
}
static void SetupGLState(Scene& scene, GLuint progId)
static void SetupGLState(Scene &scene, GLuint progId) {
// Buffer
{
std::map<std::string, BufferView>::const_iterator it(scene.bufferViews.begin());
std::map<std::string, BufferView>::const_iterator itEnd(scene.bufferViews.end());
std::map<std::string, BufferView>::const_iterator it(
scene.bufferViews.begin());
std::map<std::string, BufferView>::const_iterator itEnd(
scene.bufferViews.end());
for (; it != itEnd; it++) {
const BufferView &bufferView = it->second;
@ -216,29 +231,99 @@ static void SetupGLState(Scene& scene, GLuint progId)
GLBufferState state;
glGenBuffers(1, &state.vb);
glBindBuffer(bufferView.target, state.vb);
glBufferData(bufferView.target, bufferView.byteLength, &buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
glBufferData(bufferView.target, bufferView.byteLength,
&buffer.data.at(0) + bufferView.byteOffset, GL_STATIC_DRAW);
glBindBuffer(bufferView.target, 0);
gBufferState[it->first] = state;
}
}
// Texture
{
std::map<std::string, Mesh>::const_iterator it(scene.meshes.begin());
std::map<std::string, Mesh>::const_iterator itEnd(scene.meshes.end());
for (; it != itEnd; it++) {
const Mesh &mesh = it->second;
gMeshState[mesh.name].diffuseTex.resize(mesh.primitives.size());
for (size_t primId = 0; primId < mesh.primitives.size(); primId++) {
const Primitive &primitive = mesh.primitives[primId];
gMeshState[mesh.name].diffuseTex[primId] = 0;
if (primitive.material.empty()) {
continue;
}
Material &mat = scene.materials[primitive.material];
printf("material.name = %s\n", mat.name.c_str());
if (mat.values.find("diffuse") != mat.values.end()) {
std::string diffuseTexName = mat.values["diffuse"].stringValue;
if (scene.textures.find(diffuseTexName) != scene.textures.end()) {
Texture &tex = scene.textures[diffuseTexName];
if (scene.images.find(tex.source) != scene.images.end()) {
Image &image = scene.images[tex.source];
GLuint texId;
glGenTextures(1, &texId);
glBindTexture(tex.target, texId);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Ignore Texture.fomat.
GLenum format = GL_RGBA;
if (image.component == 3) {
format = GL_RGB;
}
glTexImage2D(tex.target, 0, tex.internalFormat, image.width,
image.height, 0, format, tex.type,
&image.image.at(0));
CheckErrors("texImage2D");
glBindTexture(tex.target, 0);
printf("TexId = %d\n", texId);
gMeshState[mesh.name].diffuseTex[primId] = texId;
}
}
}
}
}
}
glUseProgram(progId);
GLint vtloc = glGetAttribLocation(progId, "in_vertex");
GLint nrmloc = glGetAttribLocation(progId, "in_normal");
GLint uvloc = glGetAttribLocation(progId, "in_texcoord");
GLint diffuseTexLoc = glGetUniformLocation(progId, "diffuseTex");
gGLProgramState.attribs["POSITION"] = vtloc;
gGLProgramState.attribs["NORMAL"] = nrmloc;
gGLProgramState.attribs["TEXCOORD_0"] = uvloc;
gGLProgramState.uniforms["diffuseTex"] = diffuseTexLoc;
};
void DrawMesh(Scene& scene, const Mesh& mesh)
{
void DrawMesh(Scene &scene, const Mesh &mesh) {
if (gGLProgramState.uniforms["diffuseTex"] >= 0) {
glUniform1i(gGLProgramState.uniforms["diffuseTex"], 0); // TEXTURE0
}
for (size_t i = 0; i < mesh.primitives.size(); i++) {
const Primitive &primitive = mesh.primitives[i];
if (primitive.indices.empty()) return;
if (primitive.indices.empty())
return;
std::map<std::string, std::string>::const_iterator it(primitive.attributes.begin());
std::map<std::string, std::string>::const_iterator itEnd(primitive.attributes.end());
std::map<std::string, std::string>::const_iterator it(
primitive.attributes.begin());
std::map<std::string, std::string>::const_iterator itEnd(
primitive.attributes.end());
// Assume TEXTURE_2D target for the texture object.
glBindTexture(GL_TEXTURE_2D, gMeshState[mesh.name].diffuseTex[i]);
for (; it != itEnd; it++) {
const Accessor &accessor = scene.accessors[it->second];
@ -254,10 +339,13 @@ void DrawMesh(Scene& scene, const Mesh& mesh)
} else if (accessor.type == TINYGLTF_TYPE_VEC4) {
count = 4;
}
// it->first would be "POSITION", "NORMAL", ...
// it->first would be "POSITION", "NORMAL", "TEXCOORD_0", ...
if ((it->first.compare("POSITION") == 0) ||
(it->first.compare("NORMAL") == 0)) {
glVertexAttribPointer(gGLProgramState.attribs[it->first], count, accessor.componentType, GL_FALSE, accessor.byteStride, BUFFER_OFFSET(accessor.byteOffset));
(it->first.compare("NORMAL") == 0) ||
(it->first.compare("TEXCOORD_0") == 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");
@ -265,7 +353,8 @@ void DrawMesh(Scene& scene, const Mesh& mesh)
}
const Accessor &indexAccessor = scene.accessors[primitive.indices];
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gBufferState[indexAccessor.bufferView].vb);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,
gBufferState[indexAccessor.bufferView].vb);
CheckErrors("bind buffer");
int mode = -1;
if (primitive.mode == TINYGLTF_MODE_TRIANGLES) {
@ -281,26 +370,28 @@ void DrawMesh(Scene& scene, const Mesh& mesh)
} else if (primitive.mode == TINYGLTF_MODE_LINE_LOOP) {
mode = GL_LINE_LOOP;
};
glDrawElements(mode, indexAccessor.count, indexAccessor.componentType, BUFFER_OFFSET(indexAccessor.byteOffset));
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());
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("NORMAL") == 0) ||
(it->first.compare("TEXCOORD_0") == 0)) {
glDisableVertexAttribArray(gGLProgramState.attribs[it->first]);
}
}
}
}
}
void DrawScene(Scene& scene)
{
void DrawScene(Scene &scene) {
std::map<std::string, Mesh>::const_iterator it(scene.meshes.begin());
std::map<std::string, Mesh>::const_iterator itEnd(scene.meshes.end());
@ -309,7 +400,6 @@ void DrawScene(Scene& scene)
}
}
static void Init() {
trackball(curr_quat, 0, 0, 0, 0);
@ -326,8 +416,7 @@ static void Init() {
up[2] = 0.0f;
}
int main(int argc, char **argv)
{
int main(int argc, char **argv) {
if (argc < 2) {
std::cout << "glview input.gltf <scale>\n" << std::endl;
return 0;
@ -358,7 +447,8 @@ int main(int argc, char **argv)
return -1;
}
window = glfwCreateWindow(width, height, "Simple glTF geometry viewer", NULL, NULL);
window = glfwCreateWindow(width, height, "Simple glTF geometry viewer", NULL,
NULL);
if (window == NULL) {
std::cerr << "Failed to open GLFW window. " << std::endl;
glfwTerminate();
@ -433,7 +523,8 @@ int main(int argc, char **argv)
// camera(define it in projection matrix)
glMatrixMode(GL_PROJECTION);
glPushMatrix();
gluLookAt(eye[0], eye[1], eye[2], lookat[0], lookat[1], lookat[2], up[0], up[1], up[2]);
gluLookAt(eye[0], eye[1], eye[2], lookat[0], lookat[1], lookat[2], up[0],
up[1], up[2]);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

View File

@ -1,6 +1,11 @@
uniform sampler2D diffuseTex;
varying vec3 normal;
varying vec2 texcoord;
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 = texture2D(diffuseTex, texcoord);
}

View File

@ -1,7 +1,9 @@
attribute vec3 in_vertex;
attribute vec3 in_normal;
attribute vec2 in_texcoord;
varying vec3 normal;
varying vec2 texcoord;
void main(void)
{
@ -9,4 +11,6 @@ void main(void)
gl_Position = p;
vec4 nn = gl_ModelViewMatrixInverseTranspose * vec4(normalize(in_normal), 0);
normal = nn.xyz;
texcoord = in_texcoord;
}

207
test.cc
View File

@ -6,8 +6,7 @@
#include <cstdio>
#include <iostream>
std::string PrintMode(int mode)
{
std::string PrintMode(int mode) {
if (mode == TINYGLTF_MODE_POINTS) {
return "POINTS";
} else if (mode == TINYGLTF_MODE_LINE) {
@ -24,9 +23,7 @@ std::string PrintMode(int mode)
return "**UNKNOWN**";
}
std::string PrintType(int ty)
{
std::string PrintType(int ty) {
if (ty == TINYGLTF_TYPE_SCALAR) {
return "SCALAR";
} else if (ty == TINYGLTF_TYPE_VECTOR) {
@ -49,8 +46,7 @@ std::string PrintType(int ty)
return "**UNKNOWN**";
}
std::string PrintComponentType(int ty)
{
std::string PrintComponentType(int ty) {
if (ty == TINYGLTF_COMPONENT_TYPE_BYTE) {
return "BYTE";
} else if (ty == TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE) {
@ -72,8 +68,7 @@ std::string PrintComponentType(int ty)
return "**UNKNOWN**";
}
std::string PrintFloatArray(const std::vector<double>& arr)
{
std::string PrintFloatArray(const std::vector<double> &arr) {
if (arr.size() == 0) {
return "";
}
@ -88,8 +83,7 @@ std::string PrintFloatArray(const std::vector<double>& arr)
return ss.str();
}
std::string PrintStringArray(const std::vector<std::string>& arr)
{
std::string PrintStringArray(const std::vector<std::string> &arr) {
if (arr.size() == 0) {
return "";
}
@ -104,9 +98,7 @@ std::string PrintStringArray(const std::vector<std::string>& arr)
return ss.str();
}
std::string Indent(int indent)
{
std::string Indent(int indent) {
std::string s;
for (int i = 0; i < indent; i++) {
s += " ";
@ -115,64 +107,82 @@ std::string Indent(int indent)
return s;
}
void DumpNode(const Node& node, int indent)
{
void DumpNode(const Node &node, int indent) {
std::cout << Indent(indent) << "name : " << node.name << std::endl;
std::cout << Indent(indent) << "camera : " << node.camera << std::endl;
if (!node.rotation.empty()) {
std::cout << Indent(indent) << "rotation : " << PrintFloatArray(node.rotation) << std::endl;
std::cout << Indent(indent)
<< "rotation : " << PrintFloatArray(node.rotation)
<< std::endl;
}
if (!node.scale.empty()) {
std::cout << Indent(indent) << "scale : " << PrintFloatArray(node.scale) << std::endl;
std::cout << Indent(indent)
<< "scale : " << PrintFloatArray(node.scale) << std::endl;
}
if (!node.translation.empty()) {
std::cout << Indent(indent) << "translation : " << PrintFloatArray(node.translation) << std::endl;
std::cout << Indent(indent)
<< "translation : " << PrintFloatArray(node.translation)
<< std::endl;
}
if (!node.matrix.empty()) {
std::cout << Indent(indent) << "matrix : " << PrintFloatArray(node.matrix) << std::endl;
std::cout << Indent(indent)
<< "matrix : " << PrintFloatArray(node.matrix) << std::endl;
}
std::cout << Indent(indent) << "meshes : " << PrintStringArray(node.meshes) << std::endl;
std::cout << Indent(indent) << "children : " << PrintStringArray(node.children) << std::endl;
std::cout << Indent(indent)
<< "meshes : " << PrintStringArray(node.meshes) << std::endl;
std::cout << Indent(indent)
<< "children : " << PrintStringArray(node.children) << std::endl;
}
void DumpPrimitive(const Primitive& primitive, int indent)
{
std::cout << Indent(indent) << "material : " << primitive.material << std::endl;
std::cout << Indent(indent) << "mode : " << PrintMode(primitive.mode) << "(" << primitive.mode << ")" << std::endl;
std::cout << Indent(indent) << "attributes(items=" << primitive.attributes.size() << ")" << std::endl;
std::map<std::string, std::string>::const_iterator it(primitive.attributes.begin());
std::map<std::string, std::string>::const_iterator itEnd(primitive.attributes.end());
void DumpPrimitive(const Primitive &primitive, int indent) {
std::cout << Indent(indent) << "material : " << primitive.material
<< std::endl;
std::cout << Indent(indent) << "mode : " << PrintMode(primitive.mode)
<< "(" << primitive.mode << ")" << std::endl;
std::cout << Indent(indent)
<< "attributes(items=" << primitive.attributes.size() << ")"
<< std::endl;
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++) {
std::cout << Indent(indent + 1) << it->first << ": " << it->second << std::endl;
std::cout << Indent(indent + 1) << it->first << ": " << it->second
<< std::endl;
}
}
}
void Dump(const Scene& scene)
{
void Dump(const Scene &scene) {
std::cout << "=== Dump glTF ===" << std::endl;
std::cout << "asset.generator : " << scene.asset.generator << std::endl;
std::cout << "asset.premultipliedAlpha : " << scene.asset.premultipliedAlpha << std::endl;
std::cout << "asset.version : " << scene.asset.version << std::endl;
std::cout << "asset.profile.api : " << scene.asset.profile_api << std::endl;
std::cout << "asset.profile.version : " << scene.asset.profile_version << std::endl;
std::cout << "asset.generator : " << scene.asset.generator
<< std::endl;
std::cout << "asset.premultipliedAlpha : " << scene.asset.premultipliedAlpha
<< std::endl;
std::cout << "asset.version : " << scene.asset.version
<< std::endl;
std::cout << "asset.profile.api : " << scene.asset.profile_api
<< std::endl;
std::cout << "asset.profile.version : " << scene.asset.profile_version
<< std::endl;
std::cout << std::endl;
std::cout << "=== Dump scene ===" << std::endl;
std::cout << "defaultScene: " << scene.defaultScene << std::endl;
{
std::map<std::string, std::vector<std::string> >::const_iterator it(scene.scenes.begin());
std::map<std::string, std::vector<std::string> >::const_iterator itEnd(scene.scenes.end());
std::map<std::string, std::vector<std::string> >::const_iterator it(
scene.scenes.begin());
std::map<std::string, std::vector<std::string> >::const_iterator itEnd(
scene.scenes.end());
std::cout << "scenes(items=" << scene.scenes.size() << ")" << std::endl;
for (; it != itEnd; it++) {
std::cout << Indent(1) << "name : " << it->first << std::endl;
std::cout << Indent(2) << "nodes : [ ";
for (size_t i = 0; i < it->second.size(); i++) {
std::cout << it->second[i] << ((i != it->second.size()) ? ", " : "");
std::cout << it->second[i]
<< ((i != (it->second.size() - 1)) ? ", " : "");
}
std::cout << " ] " << std::endl;
}
@ -184,7 +194,9 @@ void Dump(const Scene& scene)
std::cout << "meshes(item=" << scene.meshes.size() << ")" << std::endl;
for (; it != itEnd; it++) {
std::cout << Indent(1) << "name : " << it->second.name << std::endl;
std::cout << Indent(1) << "primitives(items=" << it->second.primitives.size() << "): " << std::endl;
std::cout << Indent(1)
<< "primitives(items=" << it->second.primitives.size()
<< "): " << std::endl;
for (size_t i = 0; i < it->second.primitives.size(); i++) {
DumpPrimitive(it->second.primitives[i], 2);
@ -194,27 +206,38 @@ void Dump(const Scene& scene)
{
std::map<std::string, Accessor>::const_iterator it(scene.accessors.begin());
std::map<std::string, Accessor>::const_iterator itEnd(scene.accessors.end());
std::cout << "accessos(items=" << scene.accessors.size() << ")" << std::endl;
std::map<std::string, Accessor>::const_iterator itEnd(
scene.accessors.end());
std::cout << "accessos(items=" << scene.accessors.size() << ")"
<< std::endl;
for (; it != itEnd; it++) {
std::cout << Indent(1) << "name : " << it->first << std::endl;
std::cout << Indent(2) << "bufferView : " << it->second.bufferView << std::endl;
std::cout << Indent(2) << "byteOffset : " << it->second.byteOffset << std::endl;
std::cout << Indent(2) << "byteStride : " << it->second.byteStride << std::endl;
std::cout << Indent(2) << "componentType: " << PrintComponentType(it->second.componentType) << "(" << it->second.componentType << ")" << std::endl;
std::cout << Indent(2) << "count : " << it->second.count << std::endl;
std::cout << Indent(2) << "type : " << PrintType(it->second.type) << std::endl;
std::cout << Indent(2) << "bufferView : " << it->second.bufferView
<< std::endl;
std::cout << Indent(2) << "byteOffset : " << it->second.byteOffset
<< std::endl;
std::cout << Indent(2) << "byteStride : " << it->second.byteStride
<< std::endl;
std::cout << Indent(2) << "componentType: "
<< PrintComponentType(it->second.componentType) << "("
<< it->second.componentType << ")" << std::endl;
std::cout << Indent(2) << "count : " << it->second.count
<< std::endl;
std::cout << Indent(2) << "type : " << PrintType(it->second.type)
<< std::endl;
if (!it->second.minValues.empty()) {
std::cout << Indent(2) << "min : [";
for (size_t i = 0; i < it->second.minValues.size(); i++) {
std::cout << it->second.minValues[i] << ((i != it->second.minValues.size()-1) ? ", " : "");
std::cout << it->second.minValues[i]
<< ((i != it->second.minValues.size() - 1) ? ", " : "");
}
std::cout << "]" << std::endl;
}
if (!it->second.maxValues.empty()) {
std::cout << Indent(2) << "max : [";
for (size_t i = 0; i < it->second.maxValues.size(); i++) {
std::cout << it->second.maxValues[i] << ((i != it->second.maxValues.size()-1) ? ", " : "");
std::cout << it->second.maxValues[i]
<< ((i != it->second.maxValues.size() - 1) ? ", " : "");
}
std::cout << "]" << std::endl;
}
@ -222,14 +245,20 @@ void Dump(const Scene& scene)
}
{
std::map<std::string, BufferView>::const_iterator it(scene.bufferViews.begin());
std::map<std::string, BufferView>::const_iterator itEnd(scene.bufferViews.end());
std::cout << "bufferViews(items=" << scene.bufferViews.size() << ")" << std::endl;
std::map<std::string, BufferView>::const_iterator it(
scene.bufferViews.begin());
std::map<std::string, BufferView>::const_iterator itEnd(
scene.bufferViews.end());
std::cout << "bufferViews(items=" << scene.bufferViews.size() << ")"
<< std::endl;
for (; it != itEnd; it++) {
std::cout << Indent(1) << "name : " << it->first << std::endl;
std::cout << Indent(2) << "buffer : " << it->second.buffer << std::endl;
std::cout << Indent(2) << "byteLength : " << it->second.byteLength << std::endl;
std::cout << Indent(2) << "byteOffset : " << it->second.byteOffset << std::endl;
std::cout << Indent(2) << "buffer : " << it->second.buffer
<< std::endl;
std::cout << Indent(2) << "byteLength : " << it->second.byteLength
<< std::endl;
std::cout << Indent(2) << "byteOffset : " << it->second.byteOffset
<< std::endl;
}
}
@ -239,23 +268,35 @@ void Dump(const Scene& scene)
std::cout << "buffers(items=" << scene.buffers.size() << ")" << std::endl;
for (; it != itEnd; it++) {
std::cout << Indent(1) << "name : " << it->first << std::endl;
std::cout << Indent(2) << "byteLength : " << it->second.data.size() << std::endl;
std::cout << Indent(2) << "byteLength : " << it->second.data.size()
<< std::endl;
}
}
{
std::map<std::string, Material>::const_iterator it(scene.materials.begin());
std::map<std::string, Material>::const_iterator itEnd(scene.materials.end());
std::cout << "materials(items=" << scene.materials.size() << ")" << std::endl;
std::map<std::string, Material>::const_iterator itEnd(
scene.materials.end());
std::cout << "materials(items=" << scene.materials.size() << ")"
<< std::endl;
for (; it != itEnd; it++) {
std::cout << Indent(1) << "name : " << it->first << std::endl;
std::cout << Indent(1) << "technique : " << it->second.technique << std::endl;
std::cout << Indent(1) << "values(items=" << it->second.values.size() << std::endl;
std::cout << Indent(1) << "technique : " << it->second.technique
<< std::endl;
std::cout << Indent(1) << "values(items=" << it->second.values.size()
<< std::endl;
FloatParameterMap::const_iterator p(it->second.values.begin());
FloatParameterMap::const_iterator pEnd(it->second.values.end());
ParameterMap::const_iterator p(it->second.values.begin());
ParameterMap::const_iterator pEnd(it->second.values.end());
for (; p != pEnd; p++) {
std::cout << Indent(3) << p->first << PrintFloatArray(p->second) << std::endl;
if (!p->second.numberArray.empty()) {
std::cout << Indent(3) << p->first
<< PrintFloatArray(p->second.numberArray) << std::endl;
}
if (!p->second.stringValue.empty()) {
std::cout << Indent(3) << p->first << " : " << p->second.stringValue
<< std::endl;
}
}
}
}
@ -279,15 +320,37 @@ void Dump(const Scene& scene)
std::cout << Indent(1) << "name : " << it->first << std::endl;
std::cout << Indent(2) << "width : " << it->second.width << std::endl;
std::cout << Indent(2) << "height : " << it->second.height << std::endl;
std::cout << Indent(2) << "component : " << it->second.component << std::endl;
std::cout << Indent(2) << "height : " << it->second.height
<< std::endl;
std::cout << Indent(2) << "component : " << it->second.component
<< std::endl;
std::cout << Indent(2) << "name : " << it->second.name << std::endl;
}
}
{
std::map<std::string, Texture>::const_iterator it(scene.textures.begin());
std::map<std::string, Texture>::const_iterator itEnd(scene.textures.end());
std::cout << "textures(items=" << scene.textures.size() << ")" << std::endl;
for (; it != itEnd; it++) {
std::cout << Indent(1) << "name : " << it->first << std::endl;
std::cout << Indent(1) << "format : " << it->second.format
<< std::endl;
std::cout << Indent(1) << "internalFormat : " << it->second.internalFormat
<< std::endl;
std::cout << Indent(1) << "sampler : " << it->second.sampler
<< std::endl;
std::cout << Indent(1) << "source : " << it->second.source
<< std::endl;
std::cout << Indent(1) << "target : " << it->second.target
<< std::endl;
std::cout << Indent(1) << "type : " << it->second.type
<< std::endl;
}
}
}
int main(int argc, char** argv)
{
int main(int argc, char **argv) {
if (argc < 2) {
printf("Needs input.gltf\n");
exit(1);

View File

@ -31,6 +31,7 @@
//
//
// Version:
// - v0.9.2 Support parsing `texture`
// - v0.9.1 Support loading glTF asset from memory
// - v0.9.0 Initial
//
@ -80,12 +81,20 @@ namespace tinygltf {
#define TINYGLTF_IMAGE_FORMAT_BMP (2)
#define TINYGLTF_IMAGE_FORMAT_GIF (3)
#define TINYGLTF_TEXTURE_FORMAT_RGBA (6408)
#define TINYGLTF_TEXTURE_TARGET_TEXTURE2D (3553)
#define TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE (5121)
#define TINYGLTF_TARGET_ARRAY_BUFFER (34962)
#define TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER (34963)
typedef std::map<std::string, std::vector<double> > FloatParameterMap;
typedef struct {
std::string stringValue;
std::vector<double> numberArray;
} Parameter;
typedef std::map<std::string, Parameter> ParameterMap;
// LDR 8bit image
typedef struct {
std::string name;
int width;
@ -94,10 +103,20 @@ typedef struct {
std::vector<unsigned char> image;
} Image;
typedef struct {
int format;
int internalFormat;
std::string sampler; // Required
std::string source; // Required
int target;
int type;
std::string name;
} Texture;
typedef struct {
std::string name;
std::string technique;
FloatParameterMap values;
ParameterMap values;
} Material;
typedef struct {
@ -191,6 +210,7 @@ public:
std::map<std::string, Material> materials;
std::map<std::string, Mesh> meshes;
std::map<std::string, Node> nodes;
std::map<std::string, Texture> textures;
std::map<std::string, Image> images;
std::map<std::string, std::vector<std::string> > scenes; // list of nodes
@ -212,9 +232,8 @@ public:
/// Loads glTF asset from string(memory).
/// `length` = strlen(str);
/// Returns false and set error string to `err` if there's an error.
bool LoadFromString(Scene &scene, std::string &err,
const char* str, const unsigned int length, const std::string& baseDir);
bool LoadFromString(Scene &scene, std::string &err, const char *str,
const unsigned int length, const std::string &baseDir);
};
} // namespace tinygltf
@ -780,6 +799,39 @@ bool ParseImage(Image &image, std::string &err, const picojson::object &o,
return true;
}
bool ParseTexture(Texture &texture, std::string &err, const picojson::object &o,
const std::string &basedir) {
if (!ParseStringProperty(texture.sampler, err, o, "sampler", true)) {
return false;
}
if (!ParseStringProperty(texture.source, err, o, "source", true)) {
return false;
}
ParseStringProperty(texture.name, err, o, "name", false);
double format = TINYGLTF_TEXTURE_FORMAT_RGBA;
ParseNumberProperty(format, err, o, "format", false);
double internalFormat = TINYGLTF_TEXTURE_FORMAT_RGBA;
ParseNumberProperty(internalFormat, err, o, "internalFormat", false);
double target = TINYGLTF_TEXTURE_TARGET_TEXTURE2D;
ParseNumberProperty(target, err, o, "target", false);
double type = TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE;
ParseNumberProperty(type, err, o, "type", false);
texture.format = static_cast<int>(format);
texture.internalFormat = static_cast<int>(internalFormat);
texture.target = static_cast<int>(target);
texture.type = static_cast<int>(type);
return true;
}
bool ParseBuffer(Buffer &buffer, std::string &err, const picojson::object &o,
const std::string &basedir) {
double byteLength;
@ -1041,17 +1093,20 @@ bool ParseMaterial(Material &material, std::string &err,
for (; it != itEnd; it++) {
// Assume number values.
std::vector<double> values;
if (!ParseNumberArrayProperty(values, err, valuesObject, it->first,
Parameter param;
if (ParseStringProperty(param.stringValue, err, valuesObject, it->first,
false)) {
// Found string property.
} else if (!ParseNumberArrayProperty(param.numberArray, err, valuesObject,
it->first, false)) {
// Fallback to numer property.
double value;
if (ParseNumberProperty(value, err, valuesObject, it->first, false)) {
values.push_back(value);
param.numberArray.push_back(value);
}
}
material.values[it->first] = values;
material.values[it->first] = param;
}
}
@ -1060,7 +1115,8 @@ bool ParseMaterial(Material &material, std::string &err,
}
bool TinyGLTFLoader::LoadFromString(Scene &scene, std::string &err,
const char *str, unsigned int length, const std::string& baseDir) {
const char *str, unsigned int length,
const std::string &baseDir) {
picojson::value v;
std::string perr = picojson::parse(v, str, str + length);
@ -1282,6 +1338,25 @@ bool TinyGLTFLoader::LoadFromString(Scene &scene, std::string &err,
}
}
// 9. Parse Texture
if (v.contains("textures") && v.get("textures").is<picojson::object>()) {
const picojson::object &root = v.get("textures").get<picojson::object>();
picojson::object::const_iterator it(root.begin());
picojson::object::const_iterator itEnd(root.end());
for (; it != itEnd; it++) {
Texture texture;
if (!ParseTexture(texture, err, (it->second).get<picojson::object>(),
baseDir)) {
return false;
}
scene.textures[it->first] = texture;
}
}
return true;
}