0

I've got a basic opengl setup working with shaders, IBOs, and VBOs. And can do simple things such as drawing a 2D rectangle or square or anything of that sense. However, when I implement a vbo and an ibo containing data for a cube nothing shows up on the screen. I've created a cube class which stores the vertex and indices for the cube.

Note: I have not implemented a projection matrix in the shader yet, I am waiting till I get the distorted 3d cube on the screen.

Here's my code-

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;
};
Jcsq6
  • 474
  • 1
  • 4
  • 15
  • If you do not have any view and/or projection matrix, then the geometry is clipped by the near plane (-1). Use `cube block1(0, 0, 0, .2);` – Rabbid76 Apr 30 '20 at 19:37
  • wow thanks! see I tried something like that but i thought i needed to go down- like cube block1(0, 0, 0, -.2). so i guess it was just behind the camera! – Jcsq6 Apr 30 '20 at 19:40
  • Note, if you add a perspective projection matrix, then you'll need to set z=-2.5 again. – Rabbid76 Apr 30 '20 at 19:41
  • wait why? I've seen that used before but I dont understand it... – Jcsq6 Apr 30 '20 at 19:42
  • The projection matrix define the near and far plane. The geometry has to be in between the near and far plane. If no projection is set then the projection matrix is the identity matrix. That means parallel (orthographic) projection and near=-1, far =1. The perspective projection matrix defines a frustum, the near and far are up to you, but they have to be positive values (0 < near < far). The perspective projection matrix turns from right handed to a left handed system by flipping the z axis. Thus the z coordinate of the geometry has to be negative: near < -z < far. – Rabbid76 Apr 30 '20 at 19:47
  • ah, i understand. thanks for your help! – Jcsq6 Apr 30 '20 at 19:48

0 Answers0