Added stencil testing

This demo show how to draw an outline around
an object.... very cool ! :)
This commit is contained in:
Nigel Barink 2022-02-22 21:52:44 +01:00
parent 82cf5b9c93
commit 3d4d81f260
7 changed files with 102 additions and 33 deletions

20
.vscode/settings.json vendored
View File

@ -43,6 +43,24 @@
"stdexcept": "cpp", "stdexcept": "cpp",
"streambuf": "cpp", "streambuf": "cpp",
"cinttypes": "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"
} }
} }

13
outlineshader.fs Normal file
View File

@ -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);
}

View File

@ -85,7 +85,7 @@ int main() {
glViewport(0,0, 800, 600); glViewport(0,0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
//glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSetCursorPosCallback(window, mouse_callback); glfwSetCursorPosCallback(window, mouse_callback);
glfwSetScrollCallback(window, scroll_callback); glfwSetScrollCallback(window, scroll_callback);
@ -94,40 +94,68 @@ int main() {
Shader shader ("shader.vs", "shader.fs"); Shader shader ("shader.vs", "shader.fs");
Shader outlineShader("shader.vs","outlineshader.fs");
Model backpack("Models/backpack.obj"); Model backpack("Models/backpack.obj");
glEnable(GL_DEPTH_TEST); 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)) while(!glfwWindowShouldClose(window))
{ {
float currentFrame = glfwGetTime(); float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame; deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame; lastFrame = currentFrame;
// std::cout << "Delta Time: " << deltaTime << std::endl;
processInput(window); processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
shader.use();
glm::mat4 model = glm::mat4(1.0f); glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);
view = camera.GetViewMatrix(); glm::mat4 view = camera.GetViewMatrix();
projection = glm::perspective(glm::radians(camera.Zoom), (float)800 / (float)600, 0.1f, 100.0f); glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)800 / (float)600, 0.1f, 100.0f);
model = glm::mat4(1.0); 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("model", model);
shader.setMat4("view", view);
shader.setMat4("projection", projection);
backpack.Draw(shader); 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); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();

View File

@ -2,7 +2,7 @@
Mesh::Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, std::vector<Texture> textures) Mesh::Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, std::vector<Texture> textures)
: vertices(vertices) , indices(indices), textures(textures){ : vertices(vertices) , indices(indices), textures(textures), showOutline(false){
setupMesh(); setupMesh();
} }
@ -35,7 +35,12 @@ void Mesh::setupMesh(){
glBindVertexArray(0); glBindVertexArray(0);
} }
void Mesh::Draw( Shader &shader ){ void Mesh::Draw( Shader &shader ){
shader.use();
unsigned int diffuseNr = 1; unsigned int diffuseNr = 1;
unsigned int specularNr = 1; unsigned int specularNr = 1;
@ -52,12 +57,12 @@ void Mesh::Draw( Shader &shader){
glUniform1i( glGetUniformLocation( shader.ID, (name + number).c_str()), i); glUniform1i( glGetUniformLocation( shader.ID, (name + number).c_str()), i);
glBindTexture(GL_TEXTURE_2D, textures[i].id); glBindTexture(GL_TEXTURE_2D, textures[i].id);
} }
// draw mesh // draw mesh
glBindVertexArray(VAO); glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, static_cast <unsigned int>(indices.size()), GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLES, static_cast <unsigned int>(indices.size()), GL_UNSIGNED_INT, 0);
glBindVertexArray(0); glBindVertexArray(0);
glActiveTexture(GL_TEXTURE0); glActiveTexture(GL_TEXTURE0);

View File

@ -19,6 +19,9 @@ class Mesh{
Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, std::vector<Texture> textures); Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices, std::vector<Texture> textures);
void Draw(Shader &shader); void Draw(Shader &shader);
bool showOutline;
private: private:
// render data // render data
unsigned int VAO, VBO, EBO; unsigned int VAO, VBO, EBO;

View File

@ -91,6 +91,8 @@ void Shader::use(){
glUseProgram(ID); glUseProgram(ID);
} }
void Shader::setBool(const std::string &name, bool value) const{ void Shader::setBool(const std::string &name, bool value) const{
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int) value ); glUniform1i(glGetUniformLocation(ID, name.c_str()), (int) value );
} }