在opengl上需要有关此问题的帮助。它会编译,但是除了创建白框而不是它应该的立方体之外,不会做任何其他事情。我终于使我的编译器正常工作,但是现在这正在发生,并且不确定我在做什么错。应该旋转并成为多色立方体。

#include <Windows.h>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

using namespace std;
#define GLSL(Version, Source) "#version " #Version "\n" #Source

#define WINDOW_TITLE "5-1 Practice Activity 6"

GLint shaderProgram, WindowWidth = 800, WindowHeight = 600;
GLuint VBO, VAO;

GLfloat cameraSpeed = 0.0005f;
GLchar currentKey;
int keymod;

GLfloat scale_by_y = 2.0f;
GLfloat scale_by_z = 2.0f;
GLfloat scale_by_x = 2.0f;

GLfloat lastMouseX = 400, lastMouseY = 300;
GLfloat mouseXoffset, mouseYoffset, yaw = 0.0f, pitch = 0.0f;
GLfloat sensitivity = 0.1f;
bool mouseDetected = true;
bool rotate = false;
bool checkMotion = false;
bool checkZoom = false;

glm::vec3 CameraPosition = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 CameraUpY = glm::vec3(0.0f, 1.0f, 0.0f);
glm::vec3 CameraForwardZ = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 front;

void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
void UMouseMove(int x, int y);
void OnMouseClick(int button, int state, int x, int y);
void onMotion(int x, int y);

const GLchar* vertexShaderSource = "#version 400 core\n"
"layout (location = 0) in vec3 position;"
"layout (location = 1) in vec3 color;"
"out vec3 mobileColor;"
"uniform mat4 model;"
"uniform mat4 view;"
"uniform mat4 projection;"
"{\n"
"gl_Position = projection * view * model * vec4(position, 1.0f);"
"mobileColor = color;"
"}\n";

const GLchar* fragmentShaderSource = "#version 400 core\n"
"in vec3 mobileColor;"
"out vec4 gpuColor;"
"void main()\n"
"{\n"
"gpuColor = vec4(mobileColor, 1.0);"
"}\n";

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

    glUseProgram(shaderProgram);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glutDisplayFunc(URenderGraphics);
    glutPassiveMotionFunc(UMouseMove);
    glutMotionFunc(onMotion);
    glutMouseFunc(OnMouseClick);
    glutMainLoop();

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

    return 0;
}

void UResizeWindow(int w, int h) {
    WindowWidth = w;
    WindowHeight = h;
    glViewport(0, 0, WindowWidth, WindowHeight);
}

void URenderGraphics(void) {
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindVertexArray(VAO);

    CameraForwardZ = front;

    glm::mat4 model;
    model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f));
    model = glm::rotate(model, 45.0f, glm::vec3(0.0f, 1.0f, 0.0f));
    model = glm::scale(model, glm::vec3(scale_by_x, scale_by_y, scale_by_z));

    glm::mat4 view;
    view = glm::lookAt(CameraForwardZ, CameraPosition, CameraUpY);

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

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

    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    glutSwapBuffers();
}

void UCreateShader() {
    GLint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glCompileShader(vertexShader);

    GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    glCompileShader(fragmentShader);

    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}

void UCreateBuffers() {
    GLfloat vertices[] = {
            -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.5, 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//pot here?
    };

    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);

    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    // Active the Element Buffer Object / Indices
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)nullptr);
    glEnableVertexAttribArray(0); // Enables vertex attribute

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(1); // Enables vertex attribute

    glBindVertexArray(0); //Deactivates the VAO which is good
}

void UMouseMove(int x, int y) {
    front.x = 10.0f * cos(yaw);
    front.y = 10.0f * sin(pitch);
    front.z = sin(yaw) * cos(pitch) * 10.0f;
}

void onMotion(int curr_x, int curr_y) {
    if (checkMotion) {
        mouseXoffset = curr_x - lastMouseX;
        mouseYoffset = lastMouseY - curr_y;

        lastMouseX = curr_x;
        lastMouseY = curr_y;

        mouseXoffset *= sensitivity;
        mouseYoffset *= sensitivity;

        if (yaw != yaw + mouseXoffset && pitch == pitch + mouseYoffset) {
            yaw += mouseXoffset;
        }
        else if (pitch != pitch + mouseYoffset && yaw == yaw + mouseXoffset) {
            pitch += mouseYoffset;
        }

        front.x = 10.0f * cos(yaw);
        front.y = 10.0f * sin(pitch);
        front.z = sin(yaw) * cos(pitch) * 10.0f;
    }

    if (checkZoom) {
        if (lastMouseY > curr_y) {
            scale_by_y += 0.1f;
            scale_by_x += 0.1f;
            scale_by_z += 0.1f;

            glutPostRedisplay();
        }
        else {
            scale_by_y -= 0.1f;
            scale_by_x -= 0.1f;
            scale_by_z -= 0.1f;

            if (scale_by_y < 0.2f) {
                scale_by_y = 0.2f;
                scale_by_x = 0.2f;
                scale_by_z = 0.2f;
            }

            glutPostRedisplay();
        }

        lastMouseY = curr_y;
        lastMouseX = curr_x;
    }
}

void OnMouseClick(int button, int state, int x, int y) {
    keymod = glutGetModifiers();

    checkMotion = false;

    if (button == GLUT_LEFT_BUTTON && keymod == GLUT_ACTIVE_ALT && state == GLUT_DOWN) {
        checkMotion = true;

        checkZoom = false;
    }
    else if (button == GLUT_RIGHT_BUTTON && keymod == GLUT_ACTIVE_ALT && state == GLUT_DOWN) {
        checkMotion = false;
        checkZoom = true;
    }
}

我已经一步一步地走了,但对于我的一生,我无法弄清楚任何帮助将不胜感激!

最佳答案

顶点着色器无法编译,因为缺少一行:

const GLchar* vertexShaderSource = "#version 400 core\n"
"layout (location = 0) in vec3 position;"
"layout (location = 1) in vec3 color;"
"out vec3 mobileColor;"
"uniform mat4 model;"
"uniform mat4 view;"
"uniform mat4 projection;"
"void main()\n" // <--- MISSING
"{\n"
"gl_Position = projection * view * model * vec4(position, 1.0f);"
"mobileColor = color;"
"}\n";

我建议检查着色器编译是否成功以及程序对象是否成功链接。

如果可以成功通过着色器 glGetShaderiv 和参数GL_COMPILE_STATUS检查着色器的编译。例如。:

#include <iostream>
#include <vector>

bool 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;
    }
    return status != GL_FALSE;
}

如果程序链接成功,可以通过 glGetProgramiv 和参数GL_LINK_STATUS进行检查。例如。:

bool 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;
    }
    return status != GL_FALSE;
}

调用CompileStatus中的LinkStatusUCreateShader:

void UCreateShader() {
    GLint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glCompileShader(vertexShader);
    CompileStatus(vertexShader);

    GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    glCompileShader(fragmentShader);
    CompileStatus(fragmentShader);

    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    LinkStatus(shaderProgram);

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}

10-06 14:38