From 3d4d81f260b45ba69d6276fa6d62c40674003b3e Mon Sep 17 00:00:00 2001 From: Nigel Date: Tue, 22 Feb 2022 21:52:44 +0100 Subject: [PATCH] Added stencil testing This demo show how to draw an outline around an object.... very cool ! :) --- .vscode/settings.json | 20 +++++++++++++++- outlineshader.fs | 13 +++++++++++ shader.fs | 2 +- src/main.cpp | 54 ++++++++++++++++++++++++++++++++----------- src/mesh.cpp | 41 +++++++++++++++++--------------- src/mesh.h | 3 +++ src/shader.cpp | 2 ++ 7 files changed, 102 insertions(+), 33 deletions(-) create mode 100644 outlineshader.fs diff --git a/.vscode/settings.json b/.vscode/settings.json index c266966..dda110a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -43,6 +43,24 @@ "stdexcept": "cpp", "streambuf": "cpp", "cinttypes": "cpp", - "typeinfo": "cpp" + "typeinfo": "cpp", + "hash_map": "cpp", + "hash_set": "cpp", + "bitset": "cpp", + "chrono": "cpp", + "codecvt": "cpp", + "condition_variable": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "forward_list": "cpp", + "list": "cpp", + "unordered_set": "cpp", + "map": "cpp", + "ratio": "cpp", + "regex": "cpp", + "set": "cpp", + "iomanip": "cpp", + "mutex": "cpp", + "thread": "cpp" } } \ No newline at end of file diff --git a/outlineshader.fs b/outlineshader.fs new file mode 100644 index 0000000..7850738 --- /dev/null +++ b/outlineshader.fs @@ -0,0 +1,13 @@ +#version 460 core +uniform vec3 outlineColor; + +out vec4 FragColor; + + +in vec2 texCoords; +uniform sampler2D texture_diffuse1; + + +void main(){ + FragColor = vec4(outlineColor, 1.0); +} \ No newline at end of file diff --git a/shader.fs b/shader.fs index 1026dc2..7e5fe62 100644 --- a/shader.fs +++ b/shader.fs @@ -7,5 +7,5 @@ uniform sampler2D texture_diffuse1; void main() { - FragColor = texture( texture_diffuse1, TexCoords); + FragColor = texture( texture_diffuse1, TexCoords) ; } \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 15d9ee8..9856d94 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -85,7 +85,7 @@ int main() { glViewport(0,0, 800, 600); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); - //glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); @@ -94,41 +94,69 @@ int main() { Shader shader ("shader.vs", "shader.fs"); + Shader outlineShader("shader.vs","outlineshader.fs"); Model backpack("Models/backpack.obj"); - glEnable(GL_DEPTH_TEST); +glEnable(GL_STENCIL_TEST); +glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + +///glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); while(!glfwWindowShouldClose(window)) { float currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; - + // std::cout << "Delta Time: " << deltaTime << std::endl; processInput(window); - glClearColor(0.2f, 0.3f, 0.3f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); - shader.use(); glm::mat4 model = glm::mat4(1.0f); - glm::mat4 view = glm::mat4(1.0f); - glm::mat4 projection = glm::mat4(1.0f); - view = camera.GetViewMatrix(); - projection = glm::perspective(glm::radians(camera.Zoom), (float)800 / (float)600, 0.1f, 100.0f); + glm::mat4 view = camera.GetViewMatrix(); + glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)800 / (float)600, 0.1f, 100.0f); model = glm::mat4(1.0); - shader.setMat4("projection", projection); - shader.setMat4("view", view); + + glStencilFunc(GL_ALWAYS, 1, 0xff); + glStencilMask(0xFF); + + shader.use(); shader.setMat4("model", model); + shader.setMat4("view", view); + shader.setMat4("projection", projection); + backpack.Draw(shader); - + + glStencilFunc(GL_NOTEQUAL, 1, 0xFF); + glStencilMask(0x00); + glDisable(GL_DEPTH_TEST); + + outlineShader.use(); + outlineShader.setMat4("model", model); + outlineShader.setMat4("view", view); + outlineShader.setMat4("projection", projection); + outlineShader.setVec3("outlineColor", glm::vec3(0.28, 0.10, 0.26)); + + model = glm::scale(model, glm::vec3(1.05f,1.05f, 1.05f)); + // model = glm::translate(model, glm::vec3(1.0f, 0.0f, 0.0f)); + outlineShader.setMat4("model", model); + + + backpack.Draw(outlineShader); + glStencilMask(0xFF); + glStencilFunc(GL_ALWAYS, 1, 0xFF); + glEnable(GL_DEPTH_TEST); + + glfwSwapBuffers(window); glfwPollEvents(); } diff --git a/src/mesh.cpp b/src/mesh.cpp index 0ca58b1..fb25dd1 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -2,7 +2,7 @@ Mesh::Mesh(std::vector vertices, std::vector indices, std::vector textures) -: vertices(vertices) , indices(indices), textures(textures){ +: vertices(vertices) , indices(indices), textures(textures), showOutline(false){ setupMesh(); } @@ -35,31 +35,36 @@ void Mesh::setupMesh(){ glBindVertexArray(0); } -void Mesh::Draw( Shader &shader){ - unsigned int diffuseNr = 1; - unsigned int specularNr = 1; - for(unsigned int i = 0; i < textures.size(); i++){ - glActiveTexture(GL_TEXTURE0 + i); +void Mesh::Draw( Shader &shader ){ - std::string number; - std::string name = textures[i].type; - if( name == "texture_diffuse") - number = std::to_string(diffuseNr++); - else if(name == "texture_specular") - number = std::to_string(specularNr++); - glUniform1i( glGetUniformLocation( shader.ID, (name + number).c_str()), i); - glBindTexture(GL_TEXTURE_2D, textures[i].id); - } + shader.use(); + + unsigned int diffuseNr = 1; + unsigned int specularNr = 1; + + for(unsigned int i = 0; i < textures.size(); i++){ + glActiveTexture(GL_TEXTURE0 + i); + + std::string number; + std::string name = textures[i].type; + if( name == "texture_diffuse") + number = std::to_string(diffuseNr++); + else if(name == "texture_specular") + number = std::to_string(specularNr++); + + glUniform1i( glGetUniformLocation( shader.ID, (name + number).c_str()), i); + glBindTexture(GL_TEXTURE_2D, textures[i].id); + } + + // draw mesh glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, static_cast (indices.size()), GL_UNSIGNED_INT, 0); glBindVertexArray(0); - - glActiveTexture(GL_TEXTURE0); - + } diff --git a/src/mesh.h b/src/mesh.h index f717f01..e07a8a4 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -19,6 +19,9 @@ class Mesh{ Mesh(std::vector vertices, std::vector indices, std::vector textures); void Draw(Shader &shader); + bool showOutline; + + private: // render data unsigned int VAO, VBO, EBO; diff --git a/src/shader.cpp b/src/shader.cpp index d1867a2..be948b6 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -91,6 +91,8 @@ void Shader::use(){ glUseProgram(ID); } + + void Shader::setBool(const std::string &name, bool value) const{ glUniform1i(glGetUniformLocation(ID, name.c_str()), (int) value ); }