OpenGL对象无法正确呈现?

问题描述 投票:3回答:1

代码可以处理任何错误,但对象显示为白色。我使用的IDE是Eclipse。

我尝试了一些调试,发现UCreateBuffers()中的错误#1282。

// header inclusions
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>

//GLM math header inclusions
#include <GL/glm.hpp>
#include <GL/gtc/matrix_transform.hpp>
#include <GL/gtc/type_ptr.hpp>

using namespace std;

#define WINDOW_TITLE "Modern OpenGL" // window title macro

// shader program macro
#ifndef GLSL
#define GLSL(Version, Source) "#Version " #Version "\n" #Source
#endif

//variable declarations for shader, window size initialization, buffer and array objects
GLint shaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, VAO;

GLfloat cameraSpeed = 0.0005f;

GLchar currentKey; // will store key pressed

//global vector declarations
glm::vec3 cameraPosition = glm::vec3(0.0f, 0.0f, 5.0f);
glm::vec3 CameraUpY = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 CameraForwardZ = glm::vec3(0.0f, 0.0f, -1.0f);


// function prototypes
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
void UKeyboard(unsigned char key, int x, int y);
void UKeyReleased(unsigned char key, int x, int y);

//vertex shader source code
const GLchar * vertexShaderSource = GLSL(330,
        layout (location = 0) in vec3 position; // vertex data from vertex attrib pointer 0
        layout (location = 1) in vec3 color; // color data from vertex attrib pointer 1

        out vec3 mobileColor; // variable to transfer color data to the fragment shader

        // 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); //transforms vertices to clip coordinates
    mobileColor = color; // references incoming color data

}
);

// fragment shader source code
const GLchar * fragmentShaderSource = GLSL(330,

        in vec3 mobileColor; // variable to hold incoming color data from vertex shader

        out vec4 gpuColor; // variable to pass color data to the gpu

    void main()
    {
        gpuColor = vec4(mobileColor, 1.0); // sends color data to the gpu for rendering
    }
);


//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();

    //use the shader program
    glUseProgram(shaderProgram);


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

    glutDisplayFunc(URenderGraphics);

    glutKeyboardFunc(UKeyboard); // detects key press

    glutKeyboardUpFunc(UKeyReleased); // detects key release

    glutMainLoop();

    //destroys buffer objects once used
    glDeleteVertexArrays(1, &VAO);
    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);

     glBindVertexArray(VAO); // Activate the vertex array object before rendering and transforming them

     // Camera Movement Logic
     if(currentKey =='w')
         cameraPosition += cameraSpeed * CameraForwardZ;

     if(currentKey =='s')
         cameraPosition -= cameraSpeed * CameraForwardZ;

     if(currentKey =='a')
         cameraPosition -= glm::normalize(glm::cross(CameraForwardZ, CameraUpY)) * cameraSpeed;

     if(currentKey =='d')
         cameraPosition += glm::normalize(glm::cross(CameraForwardZ, CameraUpY)) * cameraSpeed;


    // transforms the object
     glm::mat4 model;
     model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); // place the object at the center of the viewport
     model = glm::rotate(model, 45.0f, glm::vec3(0.0, 1.0f, 0.0f)); // rotate the object 45 degrees on the x
     model = glm::scale(model, glm::vec3(2.0f, 2.0f, 2.0f)); // increase the object size by a scale of 2

     //transform the camera
     glm::mat4 view;
     view = glm::lookAt(cameraPosition, cameraPosition + CameraForwardZ, CameraUpY);

     //creates a perspective projection
     glm::mat4 projection;
     projection = glm::perspective(45.0f, (GLfloat)WindowWidth / (GLfloat)WindowHeight, 0.1f, 100.0f);

     //retrieves and passes transform matrices to the shader program
     GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
     GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
     GLint projLoc = glGetUniformLocation(shaderProgram, "projection");

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



    glutPostRedisplay();

    //draws the triangles
    glDrawArrays(GL_TRIANGLES, 0, 36);

    glBindVertexArray(0);

    glutSwapBuffers(); // flips the back buffer with the front buffer every frame

}


//creates the shader program
void UCreateShader()
{

    //vertex shader
        GLint vertexShader = glCreateShader(GL_VERTEX_SHADER); // creates the vertex shader
        glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); // attaches the vertex shader to the source code
        glCompileShader(vertexShader); // compiles the vertex shader

        //fragment shader
        GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
        glCompileShader(fragmentShader);

        //shader program
        shaderProgram = glCreateProgram();
        glAttachShader(shaderProgram, vertexShader);
        glAttachShader(shaderProgram, fragmentShader);
        glLinkProgram(shaderProgram);

        // delete the vertex and fragment shaders once linked
        glDeleteShader(vertexShader);
        glDeleteShader(fragmentShader);
}

void UCreateBuffers()
{

    GLfloat vertices[] = {
                                //positions           //Color
                                -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, 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, 1.0f, 0.0f,
                                 0.5f,  0.5f, -0.5f,  1.0f, 1.0f, 0.0f,
                                 0.5f, -0.5f, -0.5f,  1.0f, 1.0f, 0.0f,
                                 0.5f, -0.5f, -0.5f,  1.0f, 1.0f, 0.0f,
                                 0.5f, -0.5f,  0.5f,  1.0f, 1.0f, 0.0f,
                                 0.5f,  0.5f,  0.5f,  1.0f, 1.0f, 0.0f,

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

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

                            };


    //generate buffer Ids
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    //activate the vertex array object before binding and setting any VBOs and Vertex Attribute Pointers
    glBindVertexArray(VAO);

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

    //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 color data
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1); // enables vertex attribute

    glBindVertexArray(0);// enable the Vao which is good pratice


}


// implements the UKeyboar function
void UKeyboard(unsigned char key, GLint x, GLint y)
{
    switch(key){

    case 'w':
        cout << "You pressed w!" <<endl;
        break;

    case 's':
        cout << "You pressed s!" <<endl;
        break;

    case 'a':
        cout << "You pressed a!" <<endl;
        break;

    case 'd':
        cout << "You pressed d!" <<endl;
        break;

    default:
        cout << "Press a key!" << endl;

    }

}

//implements the UkeyRelease function
void UKeyReleased(unsigned char key, GLint x, GLint y)
{
    cout << "Key released!" <<endl;
}
c++ opengl glut glm-math
1个回答
1
投票

着色器无法编译。 GLSL区分大小写。版本限定符必须是#version而不是#Version

#define GLSL(Version, Source) "#Version " #Version "\n" #Source

#define GLSL(Version, Source) "#version " #Version "\n" #Source

我建议检查编译和链接错误并添加错误记录。

编译错误可以通过glGetShaderiv / glGetShaderInfoLog获得:

EG

#include <vector>
void UCompileShader( GLuint shader )
{
    glCompileShader( shader );

    GLint status;
    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;
    }
}

链接错误可以通过glGetProgramiv / glGetProgramInfoLog获得:

EG

void ULinkShader( GLuint program )
{
    glLinkProgram( program );

    GLint status;
    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;
    }
}
//creates the shader program
void UCreateShader()
{
    //vertex shader
    GLint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); 
    UCompileShader(vertexShader); // compiles the vertex shader

    //fragment shader
    GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    UCompileShader(fragmentShader);

    //shader program
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    ULinkShader(shaderProgram);

    // delete the vertex and fragment shaders once linked
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}
© www.soinside.com 2019 - 2024. All rights reserved.