Scene *SceneParser::loadScene(KeyValues *data) { Scene *scene = new Scene(); KeyValues *key = data->firstSubKey(); while(key) { const char *name = key->name(); if(strcmp(name, "object") == 0) { Object *object = loadObject(key); if(object) { scene->addObject(object); } else { fprintf(stderr, "Failed to load Object\n"); } } else if(strcmp(name, "light") == 0) { Light *light = loadLight(key); if(light) { scene->addLight(light); } else { fprintf(stderr, "Failed to load Light\n"); } } else { fprintf(stderr, "Unknown element: %s\n", name); } key = key->nextKey(); } return scene; }
Object *SceneParser::loadObject(KeyValues *data) { const char *format = data->getString("format"); if(!format) { fprintf(stderr, "Key 'format' not found on Object\n"); return NULL; } Mesh *mesh; if(strcmp("OFF", format) == 0 || strcmp("PLY", format) == 0) { const char *file = data->getString("file"); if(!file) { fprintf(stderr, "Key 'file' not found on Object\n"); return NULL; } char *filename = resolvePath(file); MeshData *meshData; if(strcmp("OFF", format) == 0) { meshData = MeshLoaderOFF::load(filename); } else if(strcmp("PLY", format) == 0) { meshData = MeshLoaderPLY::load(filename); } if(!meshData) { fprintf(stderr, "Failed to load MeshData of %s\n", filename); delete[] filename; return NULL; } if(data->getInt("normalize", 1)) { meshData->normalize(); } if(data->getInt("normals", 0)) { meshData->computeNormals(); } const char *texcoords = data->getString("texcoords"); if(texcoords) { MeshData::TexCoordsMethod method; if(strcmp(texcoords, "sphere") == 0) { method = MeshData::TexCoordsSphere; } else if(strcmp(texcoords, "cylinder") == 0) { method = MeshData::TexCoordsCylinder; } meshData->genTexCoords(method); } if(data->getInt("tangents", 0)) { meshData->genTangents(); } mesh = new Mesh(meshData); delete meshData; delete[] filename; } else { fprintf(stderr, "Invalid object format: %s\n", format); return NULL; } Material *material = NULL; QGLShaderProgram *shaderProgram = new QGLShaderProgram(); KeyValues *key; bool error = false; key = data->firstSubKey(); while(key) { if(strcmp(key->name(), "shader") == 0) { QGLShader *shader = loadShader(key); if(shader) { shaderProgram->addShader(shader); } else { fprintf(stderr, "Failed to load shader\n"); error = true; break; } } else if (strcmp(key->name(), "material") == 0) { if(material) { fprintf(stderr, "Duplicated material definition\n"); } else { material = loadMaterial(key); } } key = key->nextKey(); } if(!shaderProgram->link()) { fprintf(stderr, "Failed to link shader program\n"); error = true; } if(error) { if(material) { delete material; } delete shaderProgram; delete mesh; return NULL; } Object *object = new Object(mesh, shaderProgram, material); object->scale(data->getFloat("scale", 1.0)); float pitch = data->getFloat("pitch", 0.0); float yaw = data->getFloat("yaw", 0.0); object->rotation(pitch, yaw); const char *position = data->getString("position"); if(position) { object->position(strtoV3D(position)); } key = data->firstSubKey(); while(key) { if (strcmp(key->name(), "texture") == 0) { Texture *texture = loadTexture(key); if(texture) { object->addTexture(texture); } else { fprintf(stderr, "Failed to load texture\n"); error = true; break; } } key = key->nextKey(); } if(error) { return object; } return object; }