c++ - C++ 中的 OpenGL 立方体

标签 c++ opengl buffer vertex vertices

我在尝试使用 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,
    ...

但其余代码将 the 视为 GLuint:

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

您需要确定使用一致的类型,要么到处都是 GLubyte,要么到处都是 GLuint

关于c++ - C++ 中的 OpenGL 立方体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27177610/

相关文章:

c++ - 如何使用具有 3D 纹理的图像存储?

java - 缓冲输入流无法正确加载文件

c - 字符串操作复制字符串的部分c编程

c++ - 不确定如何反转我的堆栈?

c++ - 计算 n 个数字之和的递归函数的意外输出

c - 写入 GL_R8 纹理

c++ - cl_context 和 cl::Context 的区别

c++ - C++调试断言失败: “String is not null terminated”

c++ - 多个列表中的项目

c++ - 在 OpenGL 中动态加载着色器毫无意义吗?