OpenGL, some normals reversed despite counterclockwise order

为君一笑 提交于 2019-12-11 14:12:15

问题


In the code below, I don't understand why some faces have their normals reversed. The triangles looks ordered in the anti-clockwise direction, but some faces remain black.

When I modify the fragment shader with color = -vnormal; the two black faces are rendered correctly, but not the others, obviously.

Thanks for any help given

// minimalist but fonctional code using glew, glfw, glm
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "shaders.h"

GLuint myVAO;

void createCube() {
//    v6----- v5
//   /|      /|
//  v1------v0|
//  | |     | |
//  | |v7---|-|v4
//  |/      |/
//  v2------v3

const GLfloat cube_vertices[] = {
    1, 1, 1,  -1, 1, 1,  -1,-1, 1,      // v0-v1-v2 (front)
    -1,-1, 1,   1,-1, 1,   1, 1, 1,      // v2-v3-v0
    1, 1, 1,   1,-1, 1,   1,-1,-1,      // v0-v3-v4 (right)
    1,-1,-1,   1, 1,-1,   1, 1, 1,      // v4-v5-v0
    1, 1, 1,   1, 1,-1,  -1, 1,-1,      // v0-v5-v6 (top)
    -1, 1,-1,  -1, 1, 1,   1, 1, 1,      // v6-v1-v0
    -1, 1, 1,  -1, 1,-1,  -1,-1,-1,      // v1-v6-v7 (left)
    -1,-1,-1,  -1,-1, 1,  -1, 1, 1,      // v7-v2-v1
    -1,-1,-1,   1,-1,-1,   1,-1, 1,      // v7-v4-v3 (bottom)
    1,-1, 1,  -1,-1, 1,  -1,-1,-1,      // v3-v2-v7
    1,-1,-1,  -1,-1,-1,  -1, 1,-1,      // v4-v7-v6 (back)
    -1, 1,-1,   1, 1,-1,   1,-1,-1 };    // v6-v5-v4

                                         // normal array
const GLfloat cube_normalsI[] = {
    0, 0, 1,   0, 0, 1,   0, 0, 1,      // v0-v1-v2 (front)
    0, 0, 1,   0, 0, 1,   0, 0, 1,      // v2-v3-v0
    1, 0, 0,   1, 0, 0,   1, 0, 0,      // v0-v3-v4 (right)
    1, 0, 0,   1, 0, 0,   1, 0, 0,      // v4-v5-v0
    0, 1, 0,   0, 1, 0,   0, 1, 0,      // v0-v5-v6 (top)
    0, 1, 0,   0, 1, 0,   0, 1, 0,      // v6-v1-v0
    -1, 0, 0,  -1, 0, 0,  -1, 0, 0,      // v1-v6-v7 (left)
    -1, 0, 0,  -1, 0, 0,  -1, 0, 0,      // v7-v2-v1
    0,-1, 0,   0,-1, 0,   0,-1, 0,      // v7-v4-v3 (bottom)
    0,-1, 0,   0,-1, 0,   0,-1, 0,      // v3-v2-v7
    0, 0,-1,   0, 0,-1,   0, 0,-1,      // v4-v7-v6 (back)
    0, 0,-1,   0, 0,-1,   0, 0,-1 };    // v6-v5-v4

// Upload per-vertex positions
GLuint positionVBO = 0;
glGenBuffers(1, &positionVBO);
glBindBuffer(GL_ARRAY_BUFFER, positionVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_vertices) * sizeof(GLfloat), cube_vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

// Upload per-vertex normals
GLuint normalVBO = 0;
glGenBuffers(1, &normalVBO);
glBindBuffer(GL_ARRAY_BUFFER, normalVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(cube_normalsI) * sizeof(GLfloat), cube_normalsI, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);


// Hook up vertex/normals buffers to a "vertex array object" (VAO)
glGenVertexArrays(1, &myVAO);
glBindVertexArray(myVAO);

// Attach position buffer as attribute 0
glBindBuffer(GL_ARRAY_BUFFER, positionVBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);

// Attach normal buffer as attribute 1
glBindBuffer(GL_ARRAY_BUFFER, normalVBO);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindVertexArray(0);
}

int main(int argc, char** argv) {
glfwInit();
GLFWwindow* window = glfwCreateWindow(768, 768, "", NULL, NULL);
glfwMakeContextCurrent(window);
glewInit();

glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE); // same problem with glEnable(GL_FRONT_AND_BACK);
glClearColor(0.8f, 0.7f, 0.5f, 1.0f);

unsigned int program = shaders::CreateShader("simple.vert", "simple.frag");  

createCube();

while (glfwWindowShouldClose(window) == GL_FALSE) {            
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(0.0, 0.0, -4.0));
    glm::mat4 view = glm::lookAt(glm::vec3(-2.0, -2.0, 0.0), glm::vec3(0.0, 0.0, -4.0), glm::vec3(0.0, 1.0, 0.0));
    glm::mat4 projection = glm::perspective(45.0f, 1.0f, 0.1f, 10.0f);
    glm::mat4 mvp = projection * view * model;

    glUseProgram(program);

    GLuint imvp = glGetUniformLocation(program, "mvp");
    glUniformMatrix4fv(imvp, 1, false, glm::value_ptr(mvp));

    glBindVertexArray(myVAO);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);

    glUseProgram(0);

    glfwSwapBuffers(window);
  }
}

The vertex shader:

#version 330 core

layout (location = 0) in vec3 in_position;
layout (location = 1) in vec3 in_normal;

uniform mat4 mvp;

out vec3 vnormal;

void main() {
  vnormal = in_normal;
  gl_Position = mvp * vec4(in_position,1); 
}

The fragment shader:

#version 330 core

in vec3 vnormal;

out vec3 color;

void main() {
  color= vnormal;
}

回答1:


Output colors get clamped to the 0.0-1.0 range.

So your negative normals like -1, 0, 0 end up as RGB(0,0,0) in the color buffer.



来源:https://stackoverflow.com/questions/50827238/opengl-some-normals-reversed-despite-counterclockwise-order

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!