light shows but the cube does not appear

怎甘沉沦 提交于 2021-02-17 03:16:19

问题


I am trying to use lighting on a cube but I don't understand where am going wrong. I can be able to view the light source but the rest of the screen appears black so I don't understand why the cube is disappearing.

Here is the code:

/*Header Inclusions*/
#include <iostream>
#include <GL/Glew.h>
#include <GL/freeglut.h>

// GLM Math inclusions
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>

using namespace std; // Uses the standard namespace

#define WINDOW_TITLE "Modern OpenGL" // Macro for window title

//Vertex and fragment shader
#ifndef GLSL
#define GLSL(Version, source) "#version " #Version "\n" #source
#endif


// Variable declarations for shaders, and window size initialization, buffer and vertex array object
GLint cubeShaderProgram, lampShaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, CubeVAO, LightVAO;

// subject position and scale
glm::vec3 cubePosition(0.0f, 0.0f, 0.0f);
glm::vec3 cubeScale(2.0f);

//cube and light color
glm::vec3 objectColor(0.6f, 0.5f, 0.75f);
glm::vec3 lightColor(1.0f, 1.0f, 1.0f);

//light position and scale
glm::vec3 lightPosition(0.5f, 0.5f, -3.0f);
glm::vec3 lightScale(0.3f);

//camera position
glm::vec3 cameraPosition(0.0f, 0.0f, -6.0f);

//camera rotation
float cameraRotation = glm::radians(-25.0f);


/* User-defined Function prototypes to:*/
void UResizeWindow(int,int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);

/*Cube Vertex shader source code*/
const GLchar * cubeVertexShaderSource = GLSL(330,
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;

out vec3 Normal; //declare a vec 3 variable
out vec3 FragmentPos;

//Global variables for the transform matrices
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;

     void main(){
            gl_Position = projection * view * model * vec4(position, 1.0f);//transform vertices

        FragmentPos = vec3(model * vec4(position, 1.0f));

            Normal = mat3(transpose(inverse(model))) * normal;
            }
    );

/*Cube Fragment shader program source code*/
const GLchar * cubeFragmentShaderSource = GLSL(330,

in vec3 Normal;
in vec3 FragmentPos;

out vec4 cubeColor;

//uniform variables
uniform vec3 objectColor;
uniform  vec3 lightColor;
uniform vec3 lightPos;
uniform vec3 viewPosition;


    void main(){

//phong lighting model calculations to generate ambient, diffuse, and specular components

//calculate ambient lighting
float ambientStrength = 0.1f;
vec3 ambient = ambientStrength * lightColor;

//calculater diffuse lighting
vec3 norm = normalize(Normal);
vec3 lightDirection = normalize(lightPos - FragmentPos);
float impact = max(dot(norm, lightDirection), 0.0);
vec3 diffuse = impact * lightColor;


//calculate specular lighting
float specularIntensity = 1.8f;
float highlightSize = 16.0f;
vec3 viewDir = normalize(viewPosition - FragmentPos);
vec3 reflectDir = reflect(-lightDirection, norm);

//calculate specular component
float specularComponent = pow(max(dot(viewDir, reflectDir), 0.0), highlightSize);
vec3 specular = specularIntensity * specularComponent * lightColor;

//calculate phong result
vec3 phong = (ambient + diffue + specular) * objectColor;

cubeColor = vec4(phong, 1.0f);

}
);


/* lamp shader source code*/
const GLchar * lampVertexShaderSource = GLSL(330,

    layout (location = 0) in vec3 position;

//Global variables for the transform matrices
    uniform mat4 model;
    uniform mat4 view;
    uniform mat4 projection;

void main()
{
            gl_Position = projection * view * model * vec4(position, 1.0f);//transform vertices
}
);


/*Fragment Shader Source Code*/
const GLchar * lampFragmentShaderSource = GLSL(330,

    out vec4 color;

    void main()
    {
      color = vec4(1.0f);

    }
);


//main program
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(WindowWidth, WindowHeight);
glutCreateWindow(WINDOW_TITLE);

glutReshapeFunc(UResizeWindow);


glewExperimental = GL_TRUE;
    if (glewInit()!= GLEW_OK)
    {
    std::cout << "Failed to initialize GLEW" << std::endl;
    return -1;
    }

    UCreateShader();

    UCreateBuffers();

        glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color

        glutDisplayFunc(URenderGraphics);


        glutMainLoop();

        // Destroys Buffer objects once used
        glDeleteVertexArrays(1, &CubeVAO);
    glDeleteVertexArrays(1, &LightVAO);
        glDeleteBuffers(1, &VBO);

        return 0;

    }

    /* Resizes the window*/
    void UResizeWindow(int w, int h)
    {
    WindowWidth = w;
        WindowHeight = h;
        glViewport(0, 0, WindowWidth, WindowHeight);
     }


     /* Renders graphics */
    void URenderGraphics(void)
    {

        glEnable(GL_DEPTH_TEST); // Enable z-depth

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clears the screen

    GLint modelLoc, viewLoc, projLoc, objectColorLoc, lightColorLoc, lightPositionLoc, viewPositionLoc;

    glm::mat4 model;
    glm::mat4 view;
    glm::mat4 projection;

    //use cube shader and activate cube VAO
    glUseProgram(cubeShaderProgram);
    glBindVertexArray(CubeVAO);

    //transform the cube
        model = glm::translate(model, cameraPosition);
        model = glm::scale(model, cubeScale);

        // Transforms the camera
        view = glm::translate(view, cameraPosition);
        view = glm::rotate(view, cameraRotation, glm::vec3(0.0f, 1.0f, 0.0f));

    //set the camera projection to perspective
    projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);

    // reference matrix uniforms from the cube shader program
    modelLoc = glGetUniformLocation(cubeShaderProgram, "model");
    viewLoc = glGetUniformLocation(cubeShaderProgram, "view");
    projLoc = glGetUniformLocation(cubeShaderProgram, "projection");

    //pass matrix data to the cube shader program's matrix uniforms
    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

    // reference matrix uniforms from the cube shader program for the cube color, light color, light position, and camera position
    objectColorLoc = glGetUniformLocation(cubeShaderProgram, "objectColor");
    lightColorLoc = glGetUniformLocation(cubeShaderProgram, "lightColor");
    lightPositionLoc = glGetUniformLocation(cubeShaderProgram, "lightPos");
    viewPositionLoc = glGetUniformLocation(cubeShaderProgram, "viewPosition");

    //pass color, light, and camera data to the cube shader program's corresponding uniforms
    glUniform3f(objectColorLoc, objectColor.r, objectColor.g, objectColor.b);
    glUniform3f(lightColorLoc, lightColor.r, lightColor.g, lightColor.b);
    glUniform3f(lightPositionLoc, lightPosition.x, lightPosition.y, lightPosition.z);

    glUniform3f(viewPositionLoc, cameraPosition.x, cameraPosition.y, cameraPosition.z);

    glDrawArrays(GL_TRIANGLES, 0, 36);

    // use the lamp shader and activate the LVAO
    glUseProgram(lampShaderProgram);
    glBindVertexArray(LightVAO);

    // transform the smaller cube
    model = glm::translate(model, lightPosition);
    model = glm::scale(model, lightScale);

    // reference matrix uniforms from the lamp shader program
    modelLoc = glGetUniformLocation(lampShaderProgram, "model");
    viewLoc = glGetUniformLocation(lampShaderProgram, "view");
    projLoc = glGetUniformLocation(lampShaderProgram, "projection");

    //pass matrix data to the lamp shader program's matrix uniforms
    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

    glDrawArrays(GL_TRIANGLES,0, 36);

    glBindVertexArray(0); // Deactivate the Vertex Array Object

    glutPostRedisplay();
    glutSwapBuffers();

}

 /*Creates the Shader program*/
         void UCreateShader()
         {

        // cube Vertex shader
        GLint cubeVertexShader = glCreateShader(GL_VERTEX_SHADER); // Creates the Vertex Shader
        glShaderSource(cubeVertexShader, 1, &cubeVertexShaderSource, NULL); // Attaches the Vertex Shader to the source code
        glCompileShader(cubeVertexShader); // Compiles the Vertex Shader

        // cube Fragment Shader
        GLint cubeFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Creates the Fragment Shader
        glShaderSource(cubeFragmentShader, 1, &cubeFragmentShaderSource, NULL);// Attaches the Fragment Shader to the source code
        glCompileShader(cubeFragmentShader); // Compiles the Fragment Shader

        // Cube Shader program
        cubeShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id
        glAttachShader(cubeShaderProgram, cubeVertexShader); // Attach Vertex Shader to the Shader program
        glAttachShader(cubeShaderProgram, cubeFragmentShader);; // Attach Fragment Shader to the Shader program
        glLinkProgram(cubeShaderProgram); //Link Vertex and Fragment shader, to Shader program

        // Delete the cube Vertex and Fragment shaders once linked
        glDeleteShader(cubeVertexShader);
        glDeleteShader(cubeFragmentShader);

    // Lamp Vertex Shader
    GLint lampVertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(lampVertexShader, 1, &lampVertexShaderSource, NULL);
    glCompileShader(lampVertexShader);

    // Lamp Fragment Shader
    GLint lampFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(lampFragmentShader, 1, &lampFragmentShaderSource, NULL);
    glCompileShader(lampFragmentShader);

    // Cube Shader program
        lampShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id
        glAttachShader(lampShaderProgram, lampVertexShader); // Attach Vertex Shader to the Shader program
        glAttachShader(lampShaderProgram, lampFragmentShader);; // Attach Fragment Shader to the Shader program
        glLinkProgram(lampShaderProgram); //Link Vertex and Fragment shader, to Shader program

    // Delete the lamp Vertex and Fragment shaders once linked
        glDeleteShader(lampVertexShader);
        glDeleteShader(lampFragmentShader);

         }


        /*creates the buffer and array object*/
         void UCreateBuffers()
         {

I have tried testing the vertices on their own and i can see the cube. I dont understand why its disapering after adding the lighting.

             //position and color data
             GLfloat 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


             };

             //Generate buffer id,
                glGenVertexArrays(1, &CubeVAO);
                glGenBuffers(1,&VBO);


             // Activate the Vertex Array Object before binding and setting any VB0s and Vertex Attribute Pointers.
                glBindVertexArray(CubeVAO);

              // Activate the VBO
             glBindBuffer(GL_ARRAY_BUFFER, VBO);
             glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); //Copy vertices to VBO

             // Set attribute pointer 0 to hold Position data
             glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
             glEnableVertexAttribArray(0); // Enables vertex attribute

             // Set attribute pointer 1 to hold normal data
              glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
              glEnableVertexAttribArray(1); // Enables vertex attribute

             glBindVertexArray(0); // Deactivates the VAC, which is good practice


         /*Generate buffer ids for lamp (smaller cube)*/
            glGenVertexArrays(1, &LightVAO);

    // activate the VAO
    glBindVertexArray(LightVAO);

    // referencing the same VBO
    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    // set attribute pointer 0 to hold position data for the lamp
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);
    glBindVertexArray(0);

}

回答1:


The "cube" fragment shader fails to compile. The variable diffus does not exist, it has to be diffuse:

vec3 phong = (ambient + diffus + specular) * objectColor;

vec3 phong = (ambient + diffuse + specular) * objectColor;

I recommend to verify if compiling the shader succeeded by glGetShaderiv(..., GL_COMPILE_STATUS, ...) and linking succeeded by glGetProgramiv(..., GL_LINK_STATUS, ...).

Implement functions which validate a shader and a program and log the error messages:

#include <iostream>
#include <vector>

void CompileStatus( GLuint shader )
{
    GLint status = GL_TRUE;
    glGetShaderiv( shader, GL_COMPILE_STATUS, &status );
    if (status == GL_FALSE)
    {
        GLint logLen;
        glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logLen );
        std::vector< char >log( logLen );
        GLsizei written;
        glGetShaderInfoLog( shader, logLen, &written, log.data() );
        std::cout << "compile error:" << std::endl << log.data() << std::endl;
    }
}

void LinkStatus( GLuint program )
{
    GLint status = GL_TRUE;
    glGetProgramiv( program, GL_LINK_STATUS, &status );
    if (status == GL_FALSE)
    {
        GLint logLen;
        glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logLen );
        std::vector< char >log( logLen );
        GLsizei written;
        glGetProgramInfoLog( program, logLen, &written, log.data() );
        std::cout << "link error:" << std::endl << log.data() << std::endl;
    }
}

Validate the shaders after glCompileShader and the program after glLinkProgram:

void UCreateShader()
{
    // cube Vertex shader
    GLint cubeVertexShader = glCreateShader(GL_VERTEX_SHADER); // Creates the Vertex Shader
    glShaderSource(cubeVertexShader, 1, &cubeVertexShaderSource, NULL); // Attaches the Vertex Shader to the source code
    glCompileShader(cubeVertexShader); // Compiles the Vertex Shader
    CompileStatus( cubeVertexShader );

    // cube Fragment Shader
    GLint cubeFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Creates the Fragment Shader
    glShaderSource(cubeFragmentShader, 1, &cubeFragmentShaderSource, NULL);// Attaches the Fragment Shader to the source code
    glCompileShader(cubeFragmentShader); // Compiles the Fragment Shader
    CompileStatus( cubeFragmentShader );

    // Cube Shader program
    cubeShaderProgram = glCreateProgram(); // Creates the Shader program and returns an id
    glAttachShader(cubeShaderProgram, cubeVertexShader); // Attach Vertex Shader to the Shader program
    glAttachShader(cubeShaderProgram, cubeFragmentShader);; // Attach Fragment Shader to the Shader program
    glLinkProgram(cubeShaderProgram); //Link Vertex and Fragment shader, to Shader program
    LinkStatus( cubeShaderProgram );

    // [...]

} 


来源:https://stackoverflow.com/questions/59235204/light-shows-but-the-cube-does-not-appear

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