diff --git a/BumpMapDemo.cpp b/BumpMapDemo.cpp index 22991b2..f8303ed 100644 --- a/BumpMapDemo.cpp +++ b/BumpMapDemo.cpp @@ -12,129 +12,29 @@ BumpMapDemo::BumpMapDemo() camera.rotate(30, glm::vec3(1.0, 0.0, 0.0)); } -// renders a 1x1 quad in NDC with manually calculated tangent vectors -// ------------------------------------------------------------------ -unsigned int quadVAO = 0; -unsigned int quadVBO; -void renderQuad() { - if (quadVAO == 0) { - // positions - glm::vec3 pos1(-1.0f, 1.0f, 0.0f); - glm::vec3 pos2(-1.0f, -1.0f, 0.0f); - glm::vec3 pos3(1.0f, -1.0f, 0.0f); - glm::vec3 pos4(1.0f, 1.0f, 0.0f); - // texture coordinates - glm::vec2 uv1(0.0f, 1.0f); - glm::vec2 uv2(0.0f, 0.0f); - glm::vec2 uv3(1.0f, 0.0f); - glm::vec2 uv4(1.0f, 1.0f); - // normal vector - glm::vec3 nm(0.0f, 0.0f, 1.0f); - - // calculate tangent/bitangent vectors of both triangles - glm::vec3 tangent1, bitangent1; - glm::vec3 tangent2, bitangent2; - // triangle 1 - // ---------- - glm::vec3 edge1 = pos2 - pos1; - glm::vec3 edge2 = pos3 - pos1; - glm::vec2 deltaUV1 = uv2 - uv1; - glm::vec2 deltaUV2 = uv3 - uv1; - - float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); - - tangent1.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); - tangent1.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); - tangent1.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); - tangent1 = glm::normalize(tangent1); - - bitangent1.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); - bitangent1.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); - bitangent1.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); - bitangent1 = glm::normalize(bitangent1); - - // triangle 2 - // ---------- - edge1 = pos3 - pos1; - edge2 = pos4 - pos1; - deltaUV1 = uv3 - uv1; - deltaUV2 = uv4 - uv1; - - f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); - - tangent2.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); - tangent2.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); - tangent2.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); - tangent2 = glm::normalize(tangent2); - - bitangent2.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); - bitangent2.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); - bitangent2.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); - bitangent2 = glm::normalize(bitangent2); - - float quadVertices[] = { - // positions // normal // texcoords // tangent // bitangent - pos1.x, pos1.y, pos1.z, nm.x, nm.y, nm.z, uv1.x, - uv1.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, - pos2.x, pos2.y, pos2.z, nm.x, nm.y, nm.z, uv2.x, - uv2.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, - pos3.x, pos3.y, pos3.z, nm.x, nm.y, nm.z, uv3.x, - uv3.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, - - pos1.x, pos1.y, pos1.z, nm.x, nm.y, nm.z, uv1.x, - uv1.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z, - pos3.x, pos3.y, pos3.z, nm.x, nm.y, nm.z, uv3.x, - uv3.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z, - pos4.x, pos4.y, pos4.z, nm.x, nm.y, nm.z, uv4.x, - uv4.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z}; - // configure plane VAO - glGenVertexArrays(1, &quadVAO); - glGenBuffers(1, &quadVBO); - glBindVertexArray(quadVAO); - glBindBuffer(GL_ARRAY_BUFFER, quadVBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void *)0); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), - (void *)(3 * sizeof(float))); - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 14 * sizeof(float), - (void *)(6 * sizeof(float))); - glEnableVertexAttribArray(3); - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), - (void *)(8 * sizeof(float))); - glEnableVertexAttribArray(4); - glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), - (void *)(11 * sizeof(float))); - } - glBindVertexArray(quadVAO); - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); -} - void BumpMapDemo::render(float delta) { glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glm::mat4 projection = camera.get_projection(); - glm::mat4 view = camera.get_view(); - render_shader.use(); - render_shader.setMat4("projection", projection); - render_shader.setMat4("view", view); - glm::mat4 quad_model = glm::mat4(1.0f); - quad_model = glm::rotate( - quad_model, glm::radians((float)glfwGetTime() * 20.0f), - glm::normalize(glm::vec3( - 0.0, 0.0, 1.0))); // rotate the quad to show parallax mapping from multiple directions - render_shader.setMat4("model", quad_model); + // Camera + render_shader.setMat4("projection", camera.get_projection()); + render_shader.setMat4("view", camera.get_view()); render_shader.setVec3("viewPos", camera.get_translation()); + + // Lighting render_shader.setVec3("lightPos", glm::vec3(0.0, 1.0, 5.0)); + + // Settings for bump mapping render_shader.setFloat("height_scale", height_scale); + + // Textures albedo.bind_to(0); normal.bind_to(1); bump.bind_to(2); - renderQuad(); + + // Quad which is rendered onto + quad_mesh.rotate(delta * 25.0f, glm::normalize(glm::vec3(0.0, 0.0, 1.0))); + quad_mesh.render(render_shader); } diff --git a/BumpMapDemo.h b/BumpMapDemo.h index 6d5f778..4a03290 100644 --- a/BumpMapDemo.h +++ b/BumpMapDemo.h @@ -2,6 +2,7 @@ #include "Camera.h" #include "Framebuffer3D.h" +#include "QuadMesh.h" #include "Shader.h" #include "Texture.h" #include "VertexBuffer.h" @@ -26,4 +27,6 @@ class BumpMapDemo { Texture albedo; Texture bump; Texture normal; + + QuadMesh quad_mesh; }; \ No newline at end of file diff --git a/QuadMesh.h b/QuadMesh.h index e69de29..c498b94 100644 --- a/QuadMesh.h +++ b/QuadMesh.h @@ -0,0 +1,119 @@ +#pragma once + +// Must be the first include +#include + +// Other includes +#include "Shader.h" +#include "Spatial.h" +#include + +// A simple 2x2 quad mesh consisting of two triangles. Oriented upwards by default. +class QuadMesh : public Spatial { + public: + QuadMesh() { + // Positions + glm::vec3 pos1(-1.0f, 1.0f, 0.0f); + glm::vec3 pos2(-1.0f, -1.0f, 0.0f); + glm::vec3 pos3(1.0f, -1.0f, 0.0f); + glm::vec3 pos4(1.0f, 1.0f, 0.0f); + + // Texture coordinates + glm::vec2 uv1(0.0f, 1.0f); + glm::vec2 uv2(0.0f, 0.0f); + glm::vec2 uv3(1.0f, 0.0f); + glm::vec2 uv4(1.0f, 1.0f); + + // Normal vector + glm::vec3 nm(0.0f, 0.0f, 1.0f); + + // Calculate tangent/bitangent vectors of both triangles + glm::vec3 tangent1, bitangent1; + glm::vec3 tangent2, bitangent2; + + // Triangle 1 + glm::vec3 edge1 = pos2 - pos1; + glm::vec3 edge2 = pos3 - pos1; + glm::vec2 deltaUV1 = uv2 - uv1; + glm::vec2 deltaUV2 = uv3 - uv1; + + float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); + + tangent1.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); + tangent1.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); + tangent1.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); + tangent1 = glm::normalize(tangent1); + + bitangent1.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); + bitangent1.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); + bitangent1.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); + bitangent1 = glm::normalize(bitangent1); + + // Triangle 2 + edge1 = pos3 - pos1; + edge2 = pos4 - pos1; + deltaUV1 = uv3 - uv1; + deltaUV2 = uv4 - uv1; + + f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y); + + tangent2.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x); + tangent2.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y); + tangent2.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z); + tangent2 = glm::normalize(tangent2); + + bitangent2.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x); + bitangent2.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y); + bitangent2.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z); + bitangent2 = glm::normalize(bitangent2); + + float quadVertices[] = { + // positions // normal // texcoords // tangent // bitangent + pos1.x, pos1.y, pos1.z, nm.x, nm.y, nm.z, uv1.x, + uv1.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, + pos2.x, pos2.y, pos2.z, nm.x, nm.y, nm.z, uv2.x, + uv2.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, + pos3.x, pos3.y, pos3.z, nm.x, nm.y, nm.z, uv3.x, + uv3.y, tangent1.x, tangent1.y, tangent1.z, bitangent1.x, bitangent1.y, bitangent1.z, + + pos1.x, pos1.y, pos1.z, nm.x, nm.y, nm.z, uv1.x, + uv1.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z, + pos3.x, pos3.y, pos3.z, nm.x, nm.y, nm.z, uv3.x, + uv3.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z, + pos4.x, pos4.y, pos4.z, nm.x, nm.y, nm.z, uv4.x, + uv4.y, tangent2.x, tangent2.y, tangent2.z, bitangent2.x, bitangent2.y, bitangent2.z}; + + // Configure plane VAO + glGenVertexArrays(1, &quadVAO); + glGenBuffers(1, &quadVBO); + glBindVertexArray(quadVAO); + glBindBuffer(GL_ARRAY_BUFFER, quadVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), (void *)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), + (void *)(3 * sizeof(float))); + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 14 * sizeof(float), + (void *)(6 * sizeof(float))); + glEnableVertexAttribArray(3); + glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), + (void *)(8 * sizeof(float))); + glEnableVertexAttribArray(4); + glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 14 * sizeof(float), + (void *)(11 * sizeof(float))); + } + + void render(Shader &shader) { + shader.setMat4("model", get_matrix()); + + glBindVertexArray(quadVAO); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + } + + private: + unsigned int quadVAO = 0; + unsigned int quadVBO; +}; \ No newline at end of file