OpenGL Cube in C++

OpenGL Cube in C++

本文关键字:C++ in Cube OpenGL      更新时间:2023-10-16

我在尝试使用 OpenGL 和 C++ 渲染立方体时遇到一些问题。我能够在屏幕上得到一个简单的正方形,在添加额外的顶点后,显示了一个略微倾斜的三角形......现在我尝试使用元素缓冲区。我用额外的值填充了element_buffer [](我承认在教程中找到了),并且没有显示任何内容。任何帮助都会很棒。

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

头文件:

#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

类型不匹配。代码中的索引类型为 GLubyte

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

但代码的其余部分将 视为GLuint

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

您需要确定使用一致的类型,要么在任何地方GLubyte,要么在任何地方GLuint