OPENGL Показывает белое поле вместо подвижного куба - PullRequest
3 голосов
/ 05 апреля 2020

Нужна помощь с этой проблемой на 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;
    }
}

Я прошел через строку за строкой, но я не могу понять, что за любую помощь я буду очень признателен!

1 Ответ

1 голос
/ 06 апреля 2020

Вершинный шейдер не компилируется, поскольку отсутствует строка:

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 и LinkStatus в UCreateShader:

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