1

I am having some issues trying to rendering a cube using OpenGL and C++. I was able to get a simple square on the screen, after adding the extra vertices, a slightly tilted triangle was shown instead... Now I have tried to use an element buffer. I filled the element_buffer [] with extra values (I admittedly found on a tutorial) and have nothing being displayed. Any help would be great.

 #include "CubeAsset.h"    
        CubeAsset::CubeAsset() {
          // model coordinates, origin at centre.
          GLfloat vertex_buffer [] {
             -0.5f,-0.5f,-0.5f, // triangle 0 : begin
            -0.5f,-0.5f, 0.5f,
            -0.5f, 0.5f, 0.5f, // triangle 0 : end
        0.5f, 0.5f,-0.5f, // triangle 2 : begin
        -0.5f,-0.5f,-0.5f,
        -0.5f, 0.5f,-0.5f, // triangle 2 : end
        0.5f,-0.5f, 0.5f,
        -0.5f,-0.5f,-0.5f,
        0.5f,-0.5f,-0.5f,
        0.5f, 0.5f,-0.5f,
        0.5f,-0.5f,-0.5f,
        -0.5f,-0.5f,-0.5f,
        -0.5f,-0.5f,-0.5f,
        -0.5f, 0.5f, 0.5f,
        -0.5f, 0.5f,-0.5f,
        0.5f,-0.5f, 0.5f,
        -0.5f,-0.5f, 0.5f,
        -0.5f,-0.5f,-0.5f,
        -0.5f, 0.5f, 0.5f,
        -0.5f,-0.5f, 0.5f,
        0.5f,-0.5f, 0.5f,
        0.5f, 0.5f, 0.5f,
        0.5f,-0.5f,-0.5f,
        0.5f, 0.5f,-0.5f,
        0.5f,-0.5f,-0.5f,
        0.5f, 0.5f, 0.5f,
        0.5f,-0.5f, 0.5f,
        0.5f, 0.5f, 0.5f,
        0.5f, 0.5f,-0.5f,
        -0.5f, 0.5f,-0.5f,
        0.5f, 0.5f, 0.5f,
        -0.5f, 0.5f,-0.5f,
        -0.5f, 0.5f, 0.5f,
        0.5f, 0.5f, 0.5f,
        -0.5f, 0.5f, 0.5f,
        0.5f,-0.5f, 0.5f
      };

      element_buffer_length = 36;
      GLubyte element_buffer []  {
          0, 1, 2, 2, 3, 0,
          0, 3, 4, 4, 5, 0,
          0, 5, 6, 6, 1, 0,
          1, 6, 7, 7, 2, 1,
          7, 4, 3, 3, 2, 7,
          4, 7, 6, 6, 5, 4

      };

      // Transfer buffers to the GPU
      //

      // create buffer
      glGenBuffers(1, &vertex_buffer_token);

      // immediately bind the buffer and transfer the data
      glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_token);
      glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 12, vertex_buffer, GL_STATIC_DRAW);

      glGenBuffers(1, &element_buffer_token);
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer_token);
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * element_buffer_length, element_buffer, GL_STATIC_DRAW);
    }

    CubeAsset::~CubeAsset() {
    }

    #ifdef DEBUG
    #define checkGLError() checkError(__FILE__, __LINE__)
    #else
    // define symbol to be nothing
    #define checkGLError()
    #endif

    void checkError(std::string file, int line) {
      GLenum gl_error = glGetError();
      if(GL_NO_ERROR != gl_error) {
        std::cerr << "GL error in " << file << " at line " << line << " error: " << gl_error << std::endl;
        exit(-1);
      }
    }

    void CubeAsset::Draw(GLuint program_token) {
      if(!glIsProgram(program_token)) {
        std::cerr << "Drawing Cube with invalid program" << std::endl;
        return;
      }
      GLint validation_ok;
      glValidateProgram(program_token);
      glGetProgramiv(program_token, GL_VALIDATE_STATUS, &validation_ok);
      if(!validation_ok) {
        GLint maxLength = 0;
        glGetProgramiv(program_token, GL_INFO_LOG_LENGTH, &maxLength);

        //The maxLength includes the NULL character
        std::vector<char> errorLog(maxLength);
        glGetProgramInfoLog(program_token, maxLength, &maxLength, &errorLog[0]);

        std::cerr << "Invalid program " << program_token << " with error code " << validation_ok << std::endl;
        for(auto c: errorLog) {
          std::cerr << c;
        }
        exit(-1);
      }

      GLuint position_attrib = glGetAttribLocation(program_token, "position");
      checkGLError();

      glUseProgram(program_token);
      checkGLError();

      // use the previously transferred buffer as the vertex array.  This way
      // we transfer the buffer once -- at construction -- not on every frame.
      glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_token);
      glVertexAttribPointer(
                            position_attrib,               /* attribute */
                            3,                             /* size */
                            GL_FLOAT,                      /* type */
                            GL_FALSE,                      /* normalized? */
                            0,                             /* stride */
                            (void*)0                       /* array buffer offset */
                            );
      glEnableVertexAttribArray(position_attrib);

      checkGLError();

      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, element_buffer_token);
      glDrawElements(
                     GL_TRIANGLES,
                     element_buffer_length,
                     GL_UNSIGNED_INT,
                     (GLvoid*) 0
                     );

      checkGLError();

      glDisableVertexAttribArray(position_attrib);
    }

The header file:

#ifndef CUBEASSET_H
#define CUBEASSET_H

#include <vector>

#include <GL/gl.h>
#include <glm/glm.hpp>
#include <glm/ext.hpp>

#include "GameAsset.h"

class CubeAsset : public GameAsset {
 public:
  CubeAsset();
  ~CubeAsset();
  virtual void Draw(GLuint);

 private:
  GLuint element_buffer_length;
  GLuint vertex_buffer_token, element_buffer_token;
};

#endif // CUBEASSET_H

1 Answer 1

1

You have a type mismatch. You indices in your code are of type GLubyte:

GLubyte element_buffer []  {
    0, 1, 2, 2, 3, 0,
    ...

But the rest of the code treats the as GLuint:

glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * element_buffer_length, ...);
...
glDrawElements(GL_TRIANGLES, element_buffer_length, GL_UNSIGNED_INT, ...);

You need to settle on using a consistent type, either GLubyte everywhere, or GLuint everywhere.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! I never thought I'd be happy to see the triangle again, however I am now back to just a triangle.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.