简体   繁体   中英

Modern OpenGL Black Screen with shader program and no errors

I have no errors but when I run the program all I have is a black screen and I am supposed to have two triangles:

#include <iostream> //includes C++ i/o stream
#include <GL/glew.h> //includes glew header
#include <GL/freeglut.h> //includes freeglut header

using namespace std; //Uses the standard namespace

#define WINDOW_TITLE "3-1 Assignment" //Macro for window title

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

//Windows Variables for height and width
int WindowWidth=800, WindowHeight=600;

/*User-defined function prototypes to: initialize the program, set the window size, redraw graphics on the window when resized and render graphics on the screen*/
void UInitalize(int, char*[]);
void UInitWindow(int, char*[]);
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShaders(void);
void UCreateVBO();

//Vertex and Shader program source code
const GLchar * VertexShader = GLSL(440,
    //Receive Vertex coordinates from attribute
    in layout(location=0) vec4 vertex_Position;
//for attribute 1 expect vec(4) floats passed into the vertex shader
in layout(location=1) vec4 colorFromVBO;
//Declare a vec4 variable that will reference the vertex colors passed into the vertex shader from the buffer
out vec4 colorFromVShader;
    void main(){
        //Sends vertex positions
        gl_Position= vertex_Position;

        //References vertex colors sent from the buffer
        colorFromVShader= colorFromVBO;
    }
);

const GLchar * FragmentShader = GLSL(440,
        //vertex colors from the shader
        in vec4 colorFromVShader;

        //vec 4 variable that will reference vertex colors passed into the fragment shader from the vertex shader
        out vec4 vertex_color;
    void main(){
        //gl_FragCOlor= vec4(0.0, 1.0, 0.0, 1.0);
        vertex_Color= colorFromVShader;
    }
);

//Main Function
int main(int argc, char* argv[])
{
    UInitalize(argc, argv); //Initialize openGL program
    glutMainLoop(); //Starts openGL loop in background
    exit(EXIT_SUCCESS); //Ends the program
}

//Implements createVBO function
void UCreateVBO(void)
{
    // Specifies Coordinates
    GLfloat verts[]=
    {
        /*index 0*/
        -1.0f, 1.0f, // top-center of the screen
        1.0f, 0.0f, 0.0f, 1.0f, // Red vertex

        /*index 1*/
        -1.0f, 0.0f, // bottom-left of the screen
        0.0f, 0.0f, 1.0f, 1.0f, // Blue vertex

        /*index 2*/
        -0.5f, 0.0f, // bottom-right of the screen
        0.0f, 1.0f, 0.0f, 1.0f, // Green vertex

        /*index 3*/
        0.0f, 0.0f, // bottom-left of the screen
        1.0f, 0.0f, 0.0f, 1.0f, // Red vertex

        /*index 4*/
        0.0f, -1.0f, // bottom-right of the screen
        0.0f, 1.0f, 0.0f, 1.0f, // Green vertex
    };

    //Stores the size of the verts array
    float numVertices= sizeof(verts);

    //Variable for the vertex buffer object id
    GLuint myBufferID;

    //creates 1 buffer
    glGenBuffers(1, &myBufferID);

    //Activates the buffer
    glBindBuffer(GL_ARRAY_BUFFER, myBufferID);

    //Sends vertex data to the GPU
    glBufferData(GL_ARRAY_BUFFER, numVertices, verts, GL_STATIC_DRAW);

    //Creates vertex attribute pointer
    //Number of coordinates per vertex
    GLuint floatsPerVertex= 2;

    //Specifies the initial position of the coordinates in the buffer
    glEnableVertexAttribArray(0);

    //Strides between vertex coordinates is 6 (x, y ,r, g, b, a)
    //the number of floats before each vertex position

    GLint vertexStride= sizeof(float)*6;

    //Instructs GPU on how to handle the vertex buffer object
    //parameters: atrribPointerPosition | coordinates per vertex|data type| deactivate normalizations | 0 strides | 0 offset
    glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, vertexStride, 0);

    //Sets an attribute pointer for the vertex colors
    glEnableVertexAttribArray(1);
    GLint colorStride= sizeof(float)*6;

    //Parameters: attribPointerPosition 1 | floats per color is 4 | data type | deactivate normalization | 6 strides until the next color | 2 floats until the beginning of each color
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, colorStride, (char*)(sizeof(float)*2));

    //Creates a buffer object for the indexes
    GLushort indicies[]= {0,1,2,2,3,4};
    float numIndicies= sizeof(indicies);
    GLuint indexBufferID;
    glGenBuffers(1, &indexBufferID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndicies, indicies, GL_STATIC_DRAW);
}

//Implements UInitalize function
void UInitalize(int argc, char* argv[])
{
    //glew status variable
    GLenum GlewInitResult;

    UInitWindow(argc, argv);

    //Check glew status
    GlewInitResult= glewInit();

    if (GLEW_OK != GlewInitResult)
    {
        fprintf(stderr,"ERROR: %s\n", glewGetErrorString(GlewInitResult));
        exit(EXIT_FAILURE);
    }

    //Display GPU OpenGl version
    fprintf(stdout, "INFO: OpenGL Version: %s\n", glGetString(GL_VERSION));

    //Makes the screen black
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}

//Implements the UInitWindow function
void UInitWindow(int argc, char* argv[])
{
    //Initialize freeglut
    glutInit(&argc, argv);

    //Set window size
    glutInitWindowSize(WindowWidth, WindowHeight);

    //Memory buffer setup for display
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

    //Creates a window with the macro placeholder title
    glutCreateWindow(WINDOW_TITLE);

    //Called when window is resized
    glutReshapeFunc(UResizeWindow);

    //Renders graphics on the screen
    glutDisplayFunc(URenderGraphics);
}

//Implements the UResizeWindow function
void UResizeWindow(int Width, int Height)
{
    glViewport(0, 0, Width, Height);
}

//Implements the URenderGraphics
void URenderGraphics(void)
{
    //Clear the screen
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //Create the triangle
    //Specifies the number of vertexes
    GLuint totalVertices = 6;

    //Draw the triangles
    //glDrawArrays(GL_TRIANGLES, 0, totalVertices);
    glDrawElements(GL_TRIANGLES, totalVertices, GL_UNSIGNED_SHORT, NULL);

    //Flips the back buffer with the front buffer every frame, akin to GL Flush
    glutSwapBuffers();
}

//Initialize the UCreateShaders function
void UCreateShaders(void)
{
    //Create a shader program object
    GLuint ProgramId = glCreateProgram();

    //Create the vertex shader
    GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);

    //Create the fragment shader
    GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);

    //Get the source for the vertex shader
    glShaderSource(vertexShaderId, 1, &VertexShader, NULL);

    //Get the source for the fragment shader
    glShaderSource(fragmentShaderId, 1, &FragmentShader, NULL);

    //Complies the vertex shader
    glCompileShader(vertexShaderId);

    //Compiles the fragment shader
    glCompileShader(fragmentShaderId);

    //Attach shaders
    glAttachShader(ProgramId, vertexShaderId);
    glAttachShader(ProgramId, fragmentShaderId);

    //Link the shader program
    glLinkProgram(ProgramId);

    //Utilizes the shader program
    glUseProgram(ProgramId);
}

Couple issues:

  • UCreateShaders() and UCreateVBO() are never called.

    Without a shader or geometry bound glDrawElements() can't do anything useful.

  • Fragment shader case mismatch causing a link failure: vertex_color != vertex_Color :

     0:6(2): error: `vertex_Color' undeclared 0:6(2): error: value of type vec4 cannot be assigned to variable of type error

    Make sure to check GL_COMPILE_STATUS & GL_LINK_STATUS & grab the appropriate info logs ( glGetShaderInfoLog() / glGetProgramInfoLog() ) when loading shaders to help identify issues like this in the future.

All together:

截屏

#include <GL/glew.h>
#include <GL/freeglut.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>

void CheckStatus( GLuint obj, bool isShader )
{
    GLint status = GL_FALSE, log[ 1 << 11 ] = { 0 };
    ( isShader ? glGetShaderiv : glGetProgramiv )( obj, isShader ? GL_COMPILE_STATUS : GL_LINK_STATUS, &status );
    if( status == GL_TRUE ) return;
    ( isShader ? glGetShaderInfoLog : glGetProgramInfoLog )( obj, sizeof( log ), NULL, (GLchar*)log );
    std::cerr << (GLchar*)log << "\n";
    std::exit( EXIT_FAILURE );
}

void AttachShader( GLuint program, GLenum type, const char* src )
{
    GLuint shader = glCreateShader( type );
    glShaderSource( shader, 1, &src, NULL );
    glCompileShader( shader );
    CheckStatus( shader, true );
    glAttachShader( program, shader );
    glDeleteShader( shader );
}

const char* const vert = R"GLSL(
#version 440
in layout(location=0) vec4 vertex_Position;
in layout(location=1) vec4 colorFromVBO;
out vec4 colorFromVShader;
void main()
{
    gl_Position = vertex_Position;
    colorFromVShader = colorFromVBO;
}
)GLSL";

const char* const frag = R"GLSL(
#version 440
in vec4 colorFromVShader;
out vec4 vertex_color;
void main()
{
    vertex_color = colorFromVShader;
}
)GLSL";

void UCreateShaders()
{
    GLuint prog = glCreateProgram();
    AttachShader( prog, GL_VERTEX_SHADER, vert );
    AttachShader( prog, GL_FRAGMENT_SHADER, frag );
    glLinkProgram( prog );
    CheckStatus( prog, false );
    glUseProgram( prog );    
}

void UCreateVBO()
{
    // Specifies Coordinates
    GLfloat verts[]=
    {
        /*index 0*/
        -1.0f, 1.0f, // top-center of the screen
        1.0f, 0.0f, 0.0f, 1.0f, // Red vertex

        /*index 1*/
        -1.0f, 0.0f, // bottom-left of the screen
        0.0f, 0.0f, 1.0f, 1.0f, // Blue vertex

        /*index 2*/
        -0.5f, 0.0f, // bottom-right of the screen
        0.0f, 1.0f, 0.0f, 1.0f, // Green vertex

        /*index 3*/
        0.0f, 0.0f, // bottom-left of the screen
        1.0f, 0.0f, 0.0f, 1.0f, // Red vertex

        /*index 4*/
        0.0f, -1.0f, // bottom-right of the screen
        0.0f, 1.0f, 0.0f, 1.0f, // Green vertex
    };

    //Variable for the vertex buffer object id
    GLuint myBufferID;
    glGenBuffers(1, &myBufferID);
    glBindBuffer(GL_ARRAY_BUFFER, myBufferID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*6, 0);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float)*6, (char*)(sizeof(float)*2));
    glEnableVertexAttribArray(1);

    //Creates a buffer object for the indexes
    GLushort indicies[]= {0,1,2,2,3,4};
    GLuint indexBufferID;
    glGenBuffers(1, &indexBufferID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies), indicies, GL_STATIC_DRAW);
}

void URenderGraphics(void)
{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);    
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    GLuint totalVertices = 6;
    glDrawElements(GL_TRIANGLES, totalVertices, GL_UNSIGNED_SHORT, NULL);
    glutSwapBuffers();
}

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutInitWindowSize(640, 480);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutCreateWindow("GLUT");
    glutDisplayFunc(URenderGraphics);    

    GLenum GlewInitResult = glewInit();
    if (GLEW_OK != GlewInitResult)
    {
        fprintf(stderr,"ERROR: %s\n", glewGetErrorString(GlewInitResult));
        exit(EXIT_FAILURE);
    }

    fprintf(stdout, "INFO: OpenGL Version: %s\n", glGetString(GL_VERSION));    

    UCreateVBO();
    UCreateShaders();
    
    glutMainLoop();
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM