opengl-顶点正常不考虑

opengl- vertex normal not taken in account

I was just getting into diffuse lighting,但是对象总是给黑色输出,

顶点和片段法线定义为:

float vertices[] = {
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 
        0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 
        0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 
        -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 

        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,

        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,

        0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
        0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
        0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
        0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
        0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
        0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
        0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
        0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,

        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
        0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
    };

相关的VAO定义为:

unsigned int VAO, lightVAO, VBO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
        glGenBuffers(1, &VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(vertices), vertices, GL_STATIC_DRAW);

        glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE, 6*sizeof(float),(const void*)0);
        glEnableVertexAttribArray(0);

        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (const void*)3);
        glEnableVertexAttribArray(1);

相关制服设置为:

mShader.use();//activate the shader, already compiled
        mShader.setMat4fv("model", model1);//model matrix
        mShader.setMat4fv("view", view1);//view matrix
        mShader.setMat4fv("projection", projection1);//projection matrix
        mShader.setVec3f("lightPosition", 1.2f, 1.0f, 2.0f);//light source position
        mShader.setVec3f("objectColor", 1.0f, 0.0f, 0.0f);//our object's base color
        mShader.setVec3f("lightColor", 1.0f, 1.0f, 1.0f);//light source color
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
//glSwapBuffers is also performed, which I've double checked

对象的顶点着色器是这样的:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

out vec3 mPos;
out vec3 mNormal;

uniform vec3 lightPosition;
uniform vec3 lightColor;
uniform vec3 objectColor;

out vec3 FragColor;

void main(){

    gl_Position = projection * view * model * vec4(aPos, 1.0f);

    vec3 norm = normalize(aNormal);
    vec3 Fragpos = vec3(model*vec4(aPos, 1.0f));
    vec3 lightDir = normalize(lightPosition-Fragpos);

    float diff = max(dot(norm, lightDir), 0.0f);
    vec3 diffuse = diff*lightColor;

    FragColor = diffuse;
}

片段着色器是这样的:

#version 330

in vec3 FragColor;

out vec4 outFragColor;


void main(){


    outFragColor = vec4(FragColor, 1.0f);

}    

但输出是:

这可能是什么原因造成的。源代码与 one given in learnopenGL

几乎完全相同

完整参考代码为:

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include "Libs/glm/glm.hpp" 
#include "Libs/glm/gtc/matrix_transform.hpp"
#include "Libs/glm/gtc/type_ptr.hpp"  
#include <iostream>
#include "mLibs/camera.hpp"

#ifndef STB_IMAGE_IMPLEMENTATION
    #define STB_IMAGE_IMPLEMENTATION //must define to use the library
#endif

#include "Libs/stb_image.h"

#ifdef WINDOWS
        #include <direct.h>//for windows
        #define getcwd _getcwd
    #else
        #include <unistd.h>//for unix
#endif

#include "mLibs/window.hpp"
#include "mLibs/shaderClass.hpp"

void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xOffset, double yOffset);
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);

Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));

float deltaTime = 0.0f;
float lastFrame = 0.0f;
// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;


bool firstMouse = true;
float lastX = SCR_WIDTH/2.0f;
float lastY = SCR_HEIGHT/2.0f;

std::string objVShader = "objVShader.vs";
std::string objFShader = "objFShader.fs";

std::string lightVShader = "lightVShader.vs";
std::string lightFShader = "lightFShader.fs";

void framebuffer_size_callback(GLFWwindow* window, int width, int height){
    glViewport(0, 0, width, height);
}

int main(){

    GLFWwindow* mainWindow = static_cast<GLFWwindow*>(window::getWindow());
    if(glewInit() != GLEW_OK){
        util::LogUtil::Log("GLEW: ", "GlewInitialization failed");
        window::DestroyAndTerminate(mainWindow);
    }


    glfwSetFramebufferSizeCallback(mainWindow, framebuffer_size_callback);
    glfwSetFramebufferSizeCallback(mainWindow, framebuffer_size_callback);
    glfwSetCursorPosCallback(mainWindow, mouse_callback);
    glfwSetScrollCallback(mainWindow, scroll_callback);

    glEnable(GL_DEPTH_TEST);

    float vertices[] = {
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,
        0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 
        0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 
        0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 
        -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 
        -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f, 

        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,
        -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,

        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,

        0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
        0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
        0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
        0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,
        0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,
        0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,

        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
        0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,
        0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,

        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
        0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,
        -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f
    };



    unsigned int VAO, lightVAO, VBO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
        glGenBuffers(1, &VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER,sizeof(vertices), vertices, GL_STATIC_DRAW);

        glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE, 6*sizeof(float),(const void*)0);
        glEnableVertexAttribArray(0);

        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (const void*)3);
        glEnableVertexAttribArray(1);

    glGenVertexArrays(1, &lightVAO);
    glBindVertexArray(lightVAO);
        //select lightVAO and bind the same VBO to this VAO
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glVertexAttribPointer(0,3, GL_FLOAT,GL_FALSE,6*sizeof(float),(const void*)0);
        glEnableVertexAttribArray(0);

    glm::mat4 model1 = glm::mat4(1.0f);
    glm::mat4 view1 = glm::mat4(1.0f);
    glm::mat4 projection1 = glm::mat4(1.0f);

    glm::mat4 model2 = glm::mat4(1.0f);
    glm::mat4 view2 = glm::mat4(1.0f);
    glm::mat4 projection2 = glm::mat4(1.0f);

    Shader mShader(objVShader.c_str(), objFShader.c_str());
    Shader lightCubeShader(lightVShader.c_str(), lightFShader.c_str());

    mShader.CompileShaders();
    lightCubeShader.CompileShaders();

    model2 = glm::translate(model2, glm::vec3(.3f, .4f, .5f));

    projection1 = glm::perspective(camera.Zoom, static_cast<float>(SCR_WIDTH/SCR_HEIGHT), 0.1f, 100.0f);

    float currentFrame;
    while(!window::WindowShouldClose(mainWindow)){

        glfwPollEvents();

        currentFrame = glfwGetTime();
        deltaTime = currentFrame - lastFrame;
        lastFrame = currentFrame;

        processInput(mainWindow);

        view1 = camera.GetViewMatrix();
        glClearColor(1, 0, 1, 1);
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


        mShader.use();
        mShader.setMat4fv("model", model1);
        mShader.setMat4fv("view", view1);
        mShader.setMat4fv("projection", projection1);
        mShader.setVec3f("lightPosition", 1.2f, 1.0f, 2.0f);
        mShader.setVec3f("objectColor", 1.0f, 0.0f, 0.0f);
        mShader.setVec3f("lightColor", 1.0f, 1.0f, 1.0f);


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

        lightCubeShader.use();
        model2 = glm::mat4(1.0f);
        model2 = glm::translate(model2, glm::vec3(1, 1, 1));
        model2 = glm::scale(model2, glm::vec3(0.5f, 0.5f, 0.5f));
        lightCubeShader.setMat4fv("model", model2);
        lightCubeShader.setMat4fv("view", view1);
        lightCubeShader.setMat4fv("projection", projection1);
        glBindVertexArray(lightVAO);
        glDrawArrays(GL_TRIANGLES,0, 36);

        glfwSwapBuffers(mainWindow);
    }

    glDeleteVertexArrays(1,&VAO);
    glDeleteVertexArrays(1,&lightVAO);
    glDeleteBuffers(1, &VBO);

    return 0;
}



void mouse_callback(GLFWwindow* window, double xpos, double ypos){
    if(firstMouse){
        lastX = xpos;
        lastY = ypos;
        firstMouse = false;
    }

    float xOffset = xpos-lastX;
    float yOffset = lastY - ypos;
    lastX = xpos;
    lastY = ypos;
    camera.ProcessMouseMovement(xOffset, yOffset);
}

void scroll_callback(GLFWwindow* window, double xOffset, double yOffset){
    camera.ProcessMouseScroll(yOffset);
}


void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);

    if(glfwGetKey(window, GLFW_KEY_W)==GLFW_PRESS)
        camera.ProcessKeyboard(FORWARD, deltaTime);
    if(glfwGetKey(window, GLFW_KEY_S)==GLFW_PRESS)
        camera.ProcessKeyboard(BACKWARD, deltaTime);
    if(glfwGetKey(window, GLFW_KEY_A)==GLFW_PRESS)
        camera.ProcessKeyboard(LEFT, deltaTime);
    if(glfwGetKey(window, GLFW_KEY_D)==GLFW_PRESS)
        camera.ProcessKeyboard(RIGHT, deltaTime);
    if(glfwGetKey(window, GLFW_KEY_Q)==GLFW_PRESS)
        camera.ProcessKeyboard(UP, deltaTime);
    if(glfwGetKey(window, GLFW_KEY_E)==GLFW_PRESS)
        camera.ProcessKeyboard(DOWN, deltaTime);

}

如果绑定了命名缓冲区对象,则 glVertexAttribPointer 的最后一个参数将被视为缓冲区对象数据存储中的 字节 偏移量。法向量属性的偏移量是 3*4 字节,因此 (const void*)3 必须是 (const void*)(3*sizeof(float)):

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), (const void*)3);

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(float), 
    (const void*)(3*sizeof(float));