diff --git a/res/shaders/texture.frag b/res/shaders/texture.frag new file mode 100644 index 0000000..0d2d5dc --- /dev/null +++ b/res/shaders/texture.frag @@ -0,0 +1,12 @@ +#version 430 core + +in layout(location = 0) vec3 normal; +in layout(location = 1) vec2 textureCoordinates; +in layout(location = 2) vec3 worldPosition; + +out vec4 fragColor; + +void main() +{ + fragColor = vec4(1.0); +} diff --git a/res/textures/Brick03_col.png b/res/textures/Brick03_col.png new file mode 100644 index 0000000..5204471 Binary files /dev/null and b/res/textures/Brick03_col.png differ diff --git a/res/textures/Brick03_nrm.png b/res/textures/Brick03_nrm.png new file mode 100644 index 0000000..5d76491 Binary files /dev/null and b/res/textures/Brick03_nrm.png differ diff --git a/res/textures/Brick03_rgh.png b/res/textures/Brick03_rgh.png new file mode 100644 index 0000000..f83e14f Binary files /dev/null and b/res/textures/Brick03_rgh.png differ diff --git a/res/textures/charmap.png b/res/textures/charmap.png new file mode 100644 index 0000000..cac173d Binary files /dev/null and b/res/textures/charmap.png differ diff --git a/res/textures/normal-map-debug.png b/res/textures/normal-map-debug.png new file mode 100644 index 0000000..27a58a2 Binary files /dev/null and b/res/textures/normal-map-debug.png differ diff --git a/src/gamelogic.cpp b/src/gamelogic.cpp index be5d5c7..9da8bc2 100644 --- a/src/gamelogic.cpp +++ b/src/gamelogic.cpp @@ -43,6 +43,7 @@ SceneNode* rootNode; SceneNode* boxNode; SceneNode* ballNode; SceneNode* padNode; +SceneNode* textureNode; std::vector lightNodes; std::vector lights; @@ -75,6 +76,8 @@ sf::Sound* sound; Gloom::Shader* shader; CommandLineOptions options; +Gloom::Shader* textureShader; + double mouseSensitivity = 1.0; double lastMouseX = windowWidth / 2; double lastMouseY = windowHeight / 2; @@ -93,6 +96,17 @@ void mouseCallback(GLFWwindow* window, double x, double y) { glfwSetCursorPos(window, w / 2, h / 2); } +unsigned int createTextureFromImage(PNGImage *img) { + unsigned int tid; + glGenTextures(1, &tid); + glBindTexture(GL_TEXTURE_2D, tid); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img->width, img->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img->pixels.data()); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR); + return tid; +} + void initGame(GLFWwindow* window, CommandLineOptions gameOptions) { options = gameOptions; @@ -104,7 +118,18 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) { shader = new Gloom::Shader(); shader->makeBasicShader("../res/shaders/simple.vert", "../res/shaders/simple.frag"); - shader->activate(); + + std::cout << "loading textures..." << std::endl; + + textureShader = new Gloom::Shader(); + textureShader->makeBasicShader("../res/shaders/simple.vert", "../res/shaders/texture.frag"); + + auto img = loadPNGFile("../res/textures/charmap.png"); + auto tid = createTextureFromImage(&img); + auto mesh = generateTextGeometryBuffer("hello world", 39.0 / 29.0, 120.0); + generateBuffer(mesh); + + std::cout << "loaded textures" << std::endl; Mesh padMesh = cube(padDimensions, glm::vec2(30, 40), true); Mesh boxMesh = cube(boxDimensions, glm::vec2(90), true, true); // inverted for interior view @@ -119,6 +144,10 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) { padNode = createSceneNode(); ballNode = createSceneNode(); + textureNode = createSceneNode(); + addChild(rootNode, textureNode); + textureNode->position = {0.0, 0.0, 0.0}; + rootNode->children.push_back(boxNode); rootNode->children.push_back(padNode); rootNode->children.push_back(ballNode); @@ -348,10 +377,23 @@ void renderNode(SceneNode* node) { } } +void renderTexture(SceneNode *node) { + glUniformMatrix4fv(3, 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrix)); + glUniformMatrix4fv(4, 1, GL_FALSE, glm::value_ptr(node->modelMatrix)); + glUniformMatrix3fv(5, 1, GL_FALSE, glm::value_ptr(node->normalMatrix)); + +} + void renderFrame(GLFWwindow* window) { int w, h; glfwGetWindowSize(window, &w, &h); glViewport(0, 0, w, h); + shader->activate(); renderNode(rootNode); + shader->deactivate(); + + textureShader->activate(); + renderTexture(textureNode); + textureShader->deactivate(); } diff --git a/src/sceneGraph.hpp b/src/sceneGraph.hpp index 8928118..d70b97e 100644 --- a/src/sceneGraph.hpp +++ b/src/sceneGraph.hpp @@ -14,7 +14,7 @@ #include enum SceneNodeType { - GEOMETRY, POINT_LIGHT, SPOT_LIGHT + GEOMETRY, POINT_LIGHT, SPOT_LIGHT, FLAT_GEOMETRY, NORMAL_MAPPED_GEOMETRY }; struct SceneNode { @@ -65,6 +65,12 @@ struct SceneNode { // used by light nodes glm::vec3 worldPosition; + + // used to identify a texture (FLAT_GEOMETRY nodes) + unsigned int textureID; + + // normal map texture id + unsigned int normalMapID; }; SceneNode* createSceneNode(); diff --git a/src/utilities/glfont.cpp b/src/utilities/glfont.cpp index 79397f0..61a21a1 100644 --- a/src/utilities/glfont.cpp +++ b/src/utilities/glfont.cpp @@ -7,11 +7,13 @@ Mesh generateTextGeometryBuffer(std::string text, float characterHeightOverWidth unsigned int vertexCount = 4 * text.length(); unsigned int indexCount = 6 * text.length(); + unsigned int texCoordCount = characterWidth * characterHeight * text.length(); Mesh mesh; mesh.vertices.resize(vertexCount); mesh.indices.resize(indexCount); + mesh.textureCoordinates.resize(texCoordCount); for(unsigned int i = 0; i < text.length(); i++) { @@ -32,7 +34,13 @@ Mesh generateTextGeometryBuffer(std::string text, float characterHeightOverWidth mesh.indices.at(6 * i + 3) = 4 * i + 0; mesh.indices.at(6 * i + 4) = 4 * i + 2; mesh.indices.at(6 * i + 5) = 4 * i + 3; + + for (int v = 0; v < characterWidth; v++) { + for (int u = 0; u < characterHeight; u++) { + mesh.textureCoordinates.at(i * (v * characterWidth + u)) = {u / characterWidth, v / characterHeight}; + } + } } return mesh; -} \ No newline at end of file +}