Как нарисовать куб в OpenGL, используя IBO и VBO - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть базовая c установка opengl, работающая с шейдерами, IBO и VBO. И может делать простые вещи, такие как рисование 2D-прямоугольника или квадрата или что-нибудь в этом смысле. Однако, когда я реализую vbo и ibo, содержащие данные для куба, на экране ничего не появляется. Я создал класс куба, который хранит вершины и индексы для куба.

Примечание: я еще не внедрил матрицу проекции в шейдер, я жду, пока не получу искаженный 3d-куб на экране.

Вот мой код -

main. cpp

#include <iostream>

#include <SDL2/SDL.h>
#include <GL/glew.h>

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

#include "shader.h"
#include "cube.h"
#undef main

int main() {
    SDL_Init(SDL_INIT_VIDEO);

    SDL_Window* mainWindow = SDL_CreateWindow("game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 512, 512, SDL_WINDOW_OPENGL);

    SDL_GLContext mainContext = SDL_GL_CreateContext(mainWindow);

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

    glewExperimental = GL_TRUE;

    glewInit();

    GLuint VBO, VAO, IBO;

    cube block1(0, 0, -2.5, .2);
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    glGenBuffers(1, &IBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*36, block1.indices, GL_STATIC_DRAW); 

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 24, block1.vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    shader sqreProg("shaders/shader.vert", "shaders/shader.frag");

    bool running = true;
    while (running) {
        glClearColor(0.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);

        sqreProg.useShader();

        glBindVertexArray(VAO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glBindVertexArray(0);

        glUseProgram(0);

        SDL_GL_SwapWindow(mainWindow);

        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            switch (event.type) {
            case SDL_QUIT:
                running = false;
                break;
            }
        }
    }
    SDL_GL_DeleteContext(mainContext);
    SDL_DestroyWindow(mainWindow);
    SDL_Quit();
}

Shader.h

#pragma once
#include <SDL2/SDL.h>
#include <GL/glew.h>

#include <string>
#include <fstream>
#include <streambuf>
#include <iostream>

class shader {
public:
    shader(const char* vShader, const char* fShader) {
        vShaderCode = readFile(vShader);
        fShaderCode = readFile(fShader);

        shaderProgramID = glCreateProgram();

        addShader(vShaderCode.c_str(), GL_VERTEX_SHADER);
        addShader(fShaderCode.c_str(), GL_FRAGMENT_SHADER);

        glLinkProgram(shaderProgramID);
    }
    void useShader() { glUseProgram(shaderProgramID); }
private:
    GLuint shaderProgramID;
    std::string vShaderCode;
    std::string fShaderCode;

    std::string readFile(const char* fileName) {
        std::ifstream file(fileName);
        std::string fileContents;

        fileContents.assign((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());

        return fileContents;
    }
    void addShader(const char* code, GLenum type) {
        GLuint shaderID = glCreateShader(type);

        const GLchar* theCode[1];
        theCode[0] = code;

        GLint codeLength[1];
        codeLength[0] = strlen(code);

        glShaderSource(shaderID, 1, theCode, codeLength);
        glCompileShader(shaderID);

        GLint result = 0;
        GLchar eLog[1024] = { 0 };

        glGetShaderiv(shaderID, GL_COMPILE_STATUS, &result);
        if (!result) {
            glGetShaderInfoLog(shaderID, 1024, NULL, eLog);
            fprintf(stderr, "error compile the %d shader: '%s'\n", type, eLog);
            return;
        }
        glAttachShader(shaderProgramID, shaderID);
    }
};

cube.h

#pragma once
#include <GL\glew.h>

class cube {
public:
    cube() {
        x = 0;
        y = 0;
        z = 0;
        width = 0;
        vertices = 0;
        indices = 0;
    }
    cube(GLfloat X, GLfloat Y, GLfloat Z, float w) {
        x = X;
        y = Y;
        z = Z;
        width = w;

        vertices = new GLfloat[24];

        //1
        vertices[0] = x;
        vertices[1] = y;
        vertices[2] = z;
        //2
        vertices[3] = x + width;
        vertices[4] = y;
        vertices[5] = z;
        //3
        vertices[6] = x;
        vertices[7] = y - width;
        vertices[8] = z;
        //4
        vertices[9] = x + width;
        vertices[10] = y - width;
        vertices[11] = z;
        //5
        vertices[12] = x;
        vertices[13] = y;
        vertices[14] = z - width;
        //6
        vertices[15] = x + width;
        vertices[16] = y;
        vertices[17] = z - width;
        //7
        vertices[18] = x;
        vertices[19] = y - width;
        vertices[20] = z - width;
        //8
        vertices[21] = x + width;
        vertices[22] = y - width;
        vertices[23] = z - width;

        indices = new unsigned int[36];
        //0
        indices[0] = 0;
        indices[1] = 1;
        indices[2] = 2;
        //1
        indices[3] = 1;
        indices[4] = 2;
        indices[5] = 3;
        //2
        indices[6] = 4;
        indices[7] = 5;
        indices[8] = 6;
        //3
        indices[9] = 5;
        indices[10] = 6;
        indices[11] = 7;
        //4
        indices[12] = 4;
        indices[13] = 0;
        indices[14] = 1;
        //5
        indices[15] = 4;
        indices[16] = 5;
        indices[17] = 1;
        //6
        indices[18] = 6;
        indices[19] = 2;
        indices[20] = 3;
        //7
        indices[21] = 6;
        indices[22] = 7;
        indices[23] = 3;
        //8
        indices[24] = 1;
        indices[25] = 5;
        indices[26] = 3;
        //9
        indices[27] = 5;
        indices[28] = 7;
        indices[29] = 3;
        //10
        indices[30] = 4;
        indices[31] = 0;
        indices[32] = 2;
        //11
        indices[33] = 4;
        indices[34] = 6;
        indices[35] = 2;
    }

    GLfloat* vertices;
    unsigned int* indices;
private:
    GLfloat x;
    GLfloat y;
    GLfloat z;
    float width;
};
...