From 91dc770bc5854b1c3fe202274720b30e28410439 Mon Sep 17 00:00:00 2001 From: Joey de Vries Date: Thu, 20 Apr 2017 22:04:34 +0200 Subject: [PATCH] Code re-work: Blending. --- .../3.1.blending_discard/3.1.blending.fs | 6 +- .../3.1.blending_discard/3.1.blending.vs | 8 +- .../3.1.blending_discard/blending_discard.cpp | 78 ++++++++++++++-- .../3.2.blending_sort/3.2.blending.fs | 8 +- .../3.2.blending_sort/3.2.blending.vs | 17 ++-- .../3.2.blending_sort/blending_sorted.cpp | 89 +++++++++++++++++-- 6 files changed, 174 insertions(+), 32 deletions(-) diff --git a/src/4.advanced_opengl/3.1.blending_discard/3.1.blending.fs b/src/4.advanced_opengl/3.1.blending_discard/3.1.blending.fs index 42e30aa..c25148d 100644 --- a/src/4.advanced_opengl/3.1.blending_discard/3.1.blending.fs +++ b/src/4.advanced_opengl/3.1.blending_discard/3.1.blending.fs @@ -1,7 +1,7 @@ #version 330 core -in vec2 TexCoords; +out vec4 FragColor; -out vec4 color; +in vec2 TexCoords; uniform sampler2D texture1; @@ -10,5 +10,5 @@ void main() vec4 texColor = texture(texture1, TexCoords); if(texColor.a < 0.1) discard; - color = texColor; + FragColor = texColor; } \ No newline at end of file diff --git a/src/4.advanced_opengl/3.1.blending_discard/3.1.blending.vs b/src/4.advanced_opengl/3.1.blending_discard/3.1.blending.vs index 3abdaa6..193634c 100644 --- a/src/4.advanced_opengl/3.1.blending_discard/3.1.blending.vs +++ b/src/4.advanced_opengl/3.1.blending_discard/3.1.blending.vs @@ -1,6 +1,6 @@ #version 330 core -layout (location = 0) in vec3 position; -layout (location = 1) in vec2 texCoords; +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec2 aTexCoords; out vec2 TexCoords; @@ -10,6 +10,6 @@ uniform mat4 projection; void main() { - gl_Position = projection * view * model * vec4(position, 1.0f); - TexCoords = texCoords; + TexCoords = aTexCoords; + gl_Position = projection * view * model * vec4(aPos, 1.0f); } \ No newline at end of file diff --git a/src/4.advanced_opengl/3.1.blending_discard/blending_discard.cpp b/src/4.advanced_opengl/3.1.blending_discard/blending_discard.cpp index df3d0a2..7acca1d 100644 --- a/src/4.advanced_opengl/3.1.blending_discard/blending_discard.cpp +++ b/src/4.advanced_opengl/3.1.blending_discard/blending_discard.cpp @@ -73,7 +73,7 @@ int main() // build and compile shaders // ------------------------- - Shader shader("1.1.depth_testing.vs", "1.1.depth_testing.fs"); + Shader shader("3.1.blending.vs", "3.1.blending.fs"); // set up vertex data (and buffer(s)) and configure vertex attributes // ------------------------------------------------------------------ @@ -122,7 +122,7 @@ int main() -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; float planeVertices[] = { - // positions // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat) + // positions // texture Coords 5.0f, -0.5f, 5.0f, 2.0f, 0.0f, -5.0f, -0.5f, 5.0f, 0.0f, 0.0f, -5.0f, -0.5f, -5.0f, 0.0f, 2.0f, @@ -131,6 +131,16 @@ int main() -5.0f, -0.5f, -5.0f, 0.0f, 2.0f, 5.0f, -0.5f, -5.0f, 2.0f, 2.0f }; + float transparentVertices[] = { + // positions // texture Coords (swapped y coordinates because texture is flipped upside down) + 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, + 0.0f, -0.5f, 0.0f, 0.0f, 1.0f, + 1.0f, -0.5f, 0.0f, 1.0f, 1.0f, + + 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, + 1.0f, -0.5f, 0.0f, 1.0f, 1.0f, + 1.0f, 0.5f, 0.0f, 1.0f, 0.0f + }; // cube VAO unsigned int cubeVAO, cubeVBO; glGenVertexArrays(1, &cubeVAO); @@ -142,7 +152,6 @@ int main() glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); - glBindVertexArray(0); // plane VAO unsigned int planeVAO, planeVBO; glGenVertexArrays(1, &planeVAO); @@ -154,17 +163,40 @@ int main() glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); + // transparent VAO + unsigned int transparentVAO, transparentVBO; + glGenVertexArrays(1, &transparentVAO); + glGenBuffers(1, &transparentVBO); + glBindVertexArray(transparentVAO); + glBindBuffer(GL_ARRAY_BUFFER, transparentVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(transparentVertices), transparentVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glBindVertexArray(0); // load textures // ------------- unsigned int cubeTexture = loadTexture(FileSystem::getPath("resources/textures/marble.jpg").c_str()); unsigned int floorTexture = loadTexture(FileSystem::getPath("resources/textures/metal.png").c_str()); + unsigned int transparentTexture = loadTexture(FileSystem::getPath("resources/textures/grass.png").c_str()); + + // transparent vegetation locations + // -------------------------------- + vector vegetation + { + glm::vec3(-1.5f, 0.0f, -0.48f), + glm::vec3( 1.5f, 0.0f, 0.51f), + glm::vec3( 0.0f, 0.0f, 0.7f), + glm::vec3(-0.3f, 0.0f, -2.3f), + glm::vec3 (0.5f, 0.0f, -0.6f) + }; // shader configuration // -------------------- shader.use(); - shader.setInt("ourTexture", 0); + shader.setInt("texture1", 0); // render loop // ----------- @@ -185,6 +217,40 @@ int main() glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // draw objects + shader.use(); + glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); + glm::mat4 view = camera.GetViewMatrix(); + glm::mat4 model; + shader.setMat4("projection", projection); + shader.setMat4("view", view); + // cubes + glBindVertexArray(cubeVAO); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, cubeTexture); + model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f)); + shader.setMat4("model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + model = glm::mat4(); + model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f)); + shader.setMat4("model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + // floor + glBindVertexArray(planeVAO); + glBindTexture(GL_TEXTURE_2D, floorTexture); + model = glm::mat4(); + shader.setMat4("model", model); + glDrawArrays(GL_TRIANGLES, 0, 6); + // vegetation + glBindVertexArray(transparentVAO); + glBindTexture(GL_TEXTURE_2D, transparentTexture); + for (GLuint i = 0; i < vegetation.size(); i++) + { + model = glm::mat4(); + model = glm::translate(model, vegetation[i]); + shader.setMat4("model", model); + glDrawArrays(GL_TRIANGLES, 0, 6); + } // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) @@ -282,8 +348,8 @@ unsigned int loadTexture(char const * path) glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, format == GL_RGBA ? GL_CLAMP_TO_EDGE : GL_REPEAT); // for this tutorial: use GL_CLAMP_TO_EDGE to prevent semi-transparent borders. Due to interpolation it takes texels from next repeat + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, format == GL_RGBA ? GL_CLAMP_TO_EDGE : GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); diff --git a/src/4.advanced_opengl/3.2.blending_sort/3.2.blending.fs b/src/4.advanced_opengl/3.2.blending_sort/3.2.blending.fs index 95f1e69..4390814 100644 --- a/src/4.advanced_opengl/3.2.blending_sort/3.2.blending.fs +++ b/src/4.advanced_opengl/3.2.blending_sort/3.2.blending.fs @@ -1,11 +1,11 @@ #version 330 core -in vec2 TexCoords; +out vec4 FragColor; -out vec4 color; +in vec2 TexCoords; uniform sampler2D texture1; void main() { - color = texture(texture1, TexCoords); -} \ No newline at end of file + FragColor = texture(texture1, TexCoords); +} \ No newline at end of file diff --git a/src/4.advanced_opengl/3.2.blending_sort/3.2.blending.vs b/src/4.advanced_opengl/3.2.blending_sort/3.2.blending.vs index 3abdaa6..c25148d 100644 --- a/src/4.advanced_opengl/3.2.blending_sort/3.2.blending.vs +++ b/src/4.advanced_opengl/3.2.blending_sort/3.2.blending.vs @@ -1,15 +1,14 @@ #version 330 core -layout (location = 0) in vec3 position; -layout (location = 1) in vec2 texCoords; +out vec4 FragColor; -out vec2 TexCoords; +in vec2 TexCoords; -uniform mat4 model; -uniform mat4 view; -uniform mat4 projection; +uniform sampler2D texture1; void main() -{ - gl_Position = projection * view * model * vec4(position, 1.0f); - TexCoords = texCoords; +{ + vec4 texColor = texture(texture1, TexCoords); + if(texColor.a < 0.1) + discard; + FragColor = texColor; } \ No newline at end of file diff --git a/src/4.advanced_opengl/3.2.blending_sort/blending_sorted.cpp b/src/4.advanced_opengl/3.2.blending_sort/blending_sorted.cpp index 3905d2b..338d5b8 100644 --- a/src/4.advanced_opengl/3.2.blending_sort/blending_sorted.cpp +++ b/src/4.advanced_opengl/3.2.blending_sort/blending_sorted.cpp @@ -70,10 +70,12 @@ int main() // configure global opengl state // ----------------------------- glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // build and compile shaders // ------------------------- - Shader shader("1.1.depth_testing.vs", "1.1.depth_testing.fs"); + Shader shader("3.1.blending.vs", "3.1.blending.fs"); // set up vertex data (and buffer(s)) and configure vertex attributes // ------------------------------------------------------------------ @@ -122,7 +124,7 @@ int main() -0.5f, 0.5f, -0.5f, 0.0f, 1.0f }; float planeVertices[] = { - // positions // texture Coords (note we set these higher than 1 (together with GL_REPEAT as texture wrapping mode). this will cause the floor texture to repeat) + // positions // texture Coords 5.0f, -0.5f, 5.0f, 2.0f, 0.0f, -5.0f, -0.5f, 5.0f, 0.0f, 0.0f, -5.0f, -0.5f, -5.0f, 0.0f, 2.0f, @@ -131,6 +133,16 @@ int main() -5.0f, -0.5f, -5.0f, 0.0f, 2.0f, 5.0f, -0.5f, -5.0f, 2.0f, 2.0f }; + float transparentVertices[] = { + // positions // texture Coords (swapped y coordinates because texture is flipped upside down) + 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, + 0.0f, -0.5f, 0.0f, 0.0f, 1.0f, + 1.0f, -0.5f, 0.0f, 1.0f, 1.0f, + + 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, + 1.0f, -0.5f, 0.0f, 1.0f, 1.0f, + 1.0f, 0.5f, 0.0f, 1.0f, 0.0f + }; // cube VAO unsigned int cubeVAO, cubeVBO; glGenVertexArrays(1, &cubeVAO); @@ -142,7 +154,6 @@ int main() glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); - glBindVertexArray(0); // plane VAO unsigned int planeVAO, planeVBO; glGenVertexArrays(1, &planeVAO); @@ -154,17 +165,40 @@ int main() glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glEnableVertexAttribArray(1); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); + // transparent VAO + unsigned int transparentVAO, transparentVBO; + glGenVertexArrays(1, &transparentVAO); + glGenBuffers(1, &transparentVBO); + glBindVertexArray(transparentVAO); + glBindBuffer(GL_ARRAY_BUFFER, transparentVBO); + glBufferData(GL_ARRAY_BUFFER, sizeof(transparentVertices), transparentVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glBindVertexArray(0); // load textures // ------------- unsigned int cubeTexture = loadTexture(FileSystem::getPath("resources/textures/marble.jpg").c_str()); unsigned int floorTexture = loadTexture(FileSystem::getPath("resources/textures/metal.png").c_str()); + unsigned int transparentTexture = loadTexture(FileSystem::getPath("resources/textures/window.png").c_str()); + + // transparent window locations + // -------------------------------- + vector windows + { + glm::vec3(-1.5f, 0.0f, -0.48f), + glm::vec3( 1.5f, 0.0f, 0.51f), + glm::vec3( 0.0f, 0.0f, 0.7f), + glm::vec3(-0.3f, 0.0f, -2.3f), + glm::vec3( 0.5f, 0.0f, -0.6f) + }; // shader configuration // -------------------- shader.use(); - shader.setInt("ourTexture", 0); + shader.setInt("texture1", 0); // render loop // ----------- @@ -180,11 +214,54 @@ int main() // ----- processInput(window); + // sort the transparent windows before rendering + // --------------------------------------------- + std::map sorted; + for (unsigned int i = 0; i < windows.size(); i++) + { + float distance = glm::length(camera.Position - windows[i]); + sorted[distance] = windows[i]; + } + // render // ------ glClearColor(0.1f, 0.1f, 0.1f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // draw objects + shader.use(); + glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f); + glm::mat4 view = camera.GetViewMatrix(); + glm::mat4 model; + shader.setMat4("projection", projection); + shader.setMat4("view", view); + // cubes + glBindVertexArray(cubeVAO); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, cubeTexture); + model = glm::translate(model, glm::vec3(-1.0f, 0.0f, -1.0f)); + shader.setMat4("model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + model = glm::mat4(); + model = glm::translate(model, glm::vec3(2.0f, 0.0f, 0.0f)); + shader.setMat4("model", model); + glDrawArrays(GL_TRIANGLES, 0, 36); + // floor + glBindVertexArray(planeVAO); + glBindTexture(GL_TEXTURE_2D, floorTexture); + model = glm::mat4(); + shader.setMat4("model", model); + glDrawArrays(GL_TRIANGLES, 0, 6); + // windows (from furthest to nearest) + glBindVertexArray(transparentVAO); + glBindTexture(GL_TEXTURE_2D, transparentTexture); + for (std::map::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); ++it) + { + model = glm::mat4(); + model = glm::translate(model, it->second); + shader.setMat4("model", model); + glDrawArrays(GL_TRIANGLES, 0, 6); + } // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) @@ -282,8 +359,8 @@ unsigned int loadTexture(char const * path) glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, format == GL_RGBA ? GL_CLAMP_TO_EDGE : GL_REPEAT); // for this tutorial: use GL_CLAMP_TO_EDGE to prevent semi-transparent borders. Due to interpolation it takes texels from next repeat + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, format == GL_RGBA ? GL_CLAMP_TO_EDGE : GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);