diff --git a/src/gamelogic.cpp b/src/gamelogic.cpp index dca9d63..afdab3f 100644 --- a/src/gamelogic.cpp +++ b/src/gamelogic.cpp @@ -120,19 +120,11 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) { Mesh pad = generateBox(padDimensions.x, padDimensions.y, padDimensions.z, false); Mesh sphere = generateSphere(1.0, 40, 40); - uint ballVAO = generateBuffer(sphere); - uint boxVAO = generateBuffer(box, true); - uint padVAO = generateBuffer(pad); - // textures t_charmap = loadPNGFile("../res/textures/charmap.png"); t_cobble_diff = loadPNGFile("../res/textures/cobble_diff.png"); t_cobble_normal = loadPNGFile("../res/textures/cobble_normal.png"); - uint t_charmapID = generateTexture(t_charmap); - uint t_cobble_diffID = generateTexture(t_cobble_diff); - uint t_cobble_normalID = generateTexture(t_cobble_normal); - rootNode = createSceneNode(); boxNode = createSceneNode(NORMAL_TEXTURED_GEOMETRY); padNode = createSceneNode(); @@ -148,21 +140,15 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) { hudNode->children.push_back(textNode); //rootNode->children.push_back(textNode); - boxNode->vertexArrayObjectID = boxVAO; - boxNode->VAOIndexCount = box.indices.size(); - boxNode->diffuseTextureID = t_cobble_diffID; - boxNode->normalTextureID = t_cobble_normalID; + boxNode->setMesh(&box); + boxNode->setTexture(&t_cobble_diff, &t_cobble_normal); - padNode->vertexArrayObjectID = padVAO; - padNode->VAOIndexCount = pad.indices.size(); - - ballNode->vertexArrayObjectID = ballVAO; - ballNode->VAOIndexCount = sphere.indices.size(); + padNode->setMesh(&pad); + ballNode->setMesh(&sphere); // task 1a, add point lights for (int i = 0; i<3; i++) { - lightNode[i] = createSceneNode(); - lightNode[i]->nodeType = SceneNodeType::POINT_LIGHT; + lightNode[i] = createSceneNode(POINT_LIGHT); lightNode[i]->lightID = i; } rootNode->children.push_back(lightNode[0]); @@ -182,7 +168,7 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) { textNode->rotation = vec3(0.0, 0.0, 0.0); textNode->vertexArrayObjectID = generateBuffer(hello_world); textNode->VAOIndexCount = hello_world.indices.size(); - textNode->diffuseTextureID = t_charmapID; + textNode->setTexture(&t_charmap); textNode->isIlluminated = false; textNode->isInverted = true; @@ -235,11 +221,6 @@ void updateNodeTransformations(SceneNode* node, mat4 transformationThusFar, mat4 if (node->targeted_by != nullptr) { assert(node->targeted_by->nodeType == SPOT_LIGHT); node->targeted_by->rotation = vec3(MV*glm::vec4(node->position, 1.0)); - - //std::cout << node->targeted_by->rotation[0] - // << " " << node->targeted_by->rotation[1] - // << " " << node->targeted_by->rotation[2] - // << std::endl; } } diff --git a/src/sceneGraph.hpp b/src/sceneGraph.hpp index 4354391..998c17b 100644 --- a/src/sceneGraph.hpp +++ b/src/sceneGraph.hpp @@ -8,60 +8,87 @@ #include #include #include +#include #include #include +#include #include #include +using glm::vec3; +using glm::mat4; +using std::map; +using std::vector; +typedef unsigned int uint; + enum SceneNodeType { GEOMETRY, POINT_LIGHT, SPOT_LIGHT, HUD, TEXTURED_GEOMETRY, NORMAL_TEXTURED_GEOMETRY }; struct SceneNode { - SceneNode() { - position = glm::vec3(0, 0, 0); - rotation = glm::vec3(0, 0, 0); - scale = glm::vec3(1, 1, 1); + SceneNode(SceneNodeType type = GEOMETRY) { + position = vec3(0, 0, 0); + rotation = vec3(0, 0, 0); + scale = vec3(1, 1, 1); - referencePoint = glm::vec3(0, 0, 0); + referencePoint = vec3(0, 0, 0); vertexArrayObjectID = -1; VAOIndexCount = 0; - nodeType = GEOMETRY; + nodeType = type; targeted_by = nullptr; isIlluminated = true; isInverted = false; } - SceneNode(SceneNodeType type) : SceneNode() { - nodeType = type; - } + + void setMesh(Mesh* mesh) { + static map cache; - std::vector children; + if (cache.find(mesh) == cache.end()) + cache[mesh] = generateBuffer(*mesh, nodeType==NORMAL_TEXTURED_GEOMETRY); + + vertexArrayObjectID = cache[mesh]; + VAOIndexCount = mesh->indices.size(); + } + void setTexture(PNGImage* diffuse, PNGImage* normal = nullptr) { + static map cache; + + if (cache.find(diffuse) == cache.end()) cache[diffuse] = generateTexture(*diffuse); + diffuseTextureID = cache[diffuse]; + + if (!normal) return; + if (cache.find(normal) == cache.end()) cache[normal] = generateTexture(*normal); + normalTextureID = cache[normal]; + } + + vector children; // The node's position and rotation relative to its parent - glm::vec3 position; - glm::vec3 rotation; - glm::vec3 scale; + vec3 position; + vec3 rotation; + vec3 scale; // set this if the shape uses a custom shader other than the default one Gloom::Shader* shader = nullptr; // A transformation matrix representing the transformation of the node's location relative to its parent. This matrix is updated every frame. - glm::mat4 MVP; // MVP - glm::mat4 MV; // MV - glm::mat4 MVnormal; // transpose(inverse(MV)) + mat4 MVP; // MVP + mat4 MV; // MV + mat4 MVnormal; // transpose(inverse(MV)) - // The location of the node's reference point - glm::vec3 referencePoint; + // The location of the node's reference point (center of rotation) + vec3 referencePoint; - // The ID of the VAO containing the "appearance" of this SceneNode. + // VAO IDs refering to a loaded Mesh and its length int vertexArrayObjectID; - unsigned int VAOIndexCount; + uint VAOIndexCount; - unsigned int diffuseTextureID; - unsigned int normalTextureID; + // textures + uint diffuseTextureID; + uint normalTextureID; + // shader flags bool isIlluminated; bool isInverted; @@ -69,7 +96,7 @@ struct SceneNode { SceneNodeType nodeType; // for lights: - unsigned int lightID; + uint lightID; SceneNode* targeted_by; // spot };