2016-06-28 61 views
0

我想创建一个类来处理OpenGL缓冲区,如顶点缓冲区对象或颜色缓冲区。自定义OpenGL缓冲区类不显示任何东西

这里是buffer.h:

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

class glBuffer 
{ 
public: 
    glBuffer(GLenum target); 
    void setdata(const void *data, GLenum mode); 
    void bind(GLuint index, GLint valuePerVertex, GLenum variableType = GL_FLOAT, GLsizei stride = 0, int offset = 0); 
    void unbind(); 
    GLuint getBufferID() const; 
    ~glBuffer(); 

private: 
    bool m_active; 
    GLuint m_buffer; 
    GLuint m_index; 
    GLenum m_target; 
}; 

而且buffer.cpp:

#include "buffer.h" 
#include <GL/glew.h> 
#include <iostream> 


glBuffer::glBuffer(GLenum target) 
{ 
    m_target = target; 
    m_active = false; 
    glGenBuffers(1, &m_buffer); 
} 

void glBuffer::setdata(const void *data, GLenum mode) 
{ 
    glBindBuffer(m_target, m_buffer); 
    glBufferData(m_target, sizeof(data), data, mode); 
    glBindBuffer(m_target, 0); 
} 

void glBuffer::bind(GLuint index, GLint valuePerVertex, GLenum variableType, GLsizei stride, int offset) 
{ 
    m_active = true; 
    m_index = index; 
    glEnableVertexAttribArray(m_index); 
    glBindBuffer(m_target, m_buffer); 
    glVertexAttribPointer(
     m_index, 
     valuePerVertex,  
     variableType,  
     GL_FALSE,   //normalized? 
     stride,    
     (void*)offset  //buffer offset 
    ); 
} 

void glBuffer::unbind() 
{ 
    m_active = false; 
    glBindBuffer(m_target, 0); 
    glDisableVertexAttribArray(m_index); 
} 

GLuint glBuffer::getBufferID() const 
{ 
    return m_buffer; 
} 


glBuffer::~glBuffer() 
{ 
    if (!m_active){ 
     unbind(); 
    } 
    glDeleteBuffers(1, &m_buffer); 
} 

这是我如何使用它在我的应用程序,在那里我#include "buffer.h"

glBuffer vbo(GL_ARRAY_BUFFER); 
vbo.setdata(color_buffer_data, GL_STATIC_DRAW); 
vbo.bind(0, 3); 

取代:

GLuint vbo; 
glGenBuffers(1, &vbo); 
glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STATIC_DRAW); 
glEnableVertexAttribArray(0); 
glBindBuffer(GL_ARRAY_BUFFER, vbo); 
glVertexAttribPointer(
    0,     // attribute 0. No particular reason for 0, but must match the layout in the shader. 
    3,     // size 
    GL_FLOAT,   // type 
    GL_FALSE,   // normalized? 
    0,     // stride 
    (void*)0   // array buffer offset 
); 

当我编译并运行它时,我得到一个没有任何绘制的黑色窗口。

发生了什么事? PS:我正在使用vs,glfw3,glew。

+1

在[mcve]中编辑。对于我们所有人来说,您都处于核心环境并忘记了VAO。 – genpfault

+3

另外,'glBuffer :: setdata()'中的'sizeof(data)'在大多数平台上将是'4'或'8',而不是像你希望的'data'的长度。传递一个单独的'size'参数或使用像'std :: array <>'/'std :: vector <>'这样的容器。 – genpfault

回答

2

这里是设置缓冲区数据

glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_buffer_data), vertex_buffer_data, GL_STATIC_DRAW); 

我假设你vertex_buffer_data是一个数组这就是为什么这个作品你的工作代码。既然你把这个变成了void *,你不能在指针上调用sizeof。你需要的是整个数组的大小,以字节为单位。

下面是你们班的功能不起作用

void glBuffer::setdata(const void *data, GLenum mode) 
{ 
    glBindBuffer(m_target, m_buffer); 
    glBufferData(m_target, sizeof(data), data, mode); 
    glBindBuffer(m_target, 0); 
} 

这是因为的sizeof(数据)是不一样的,如第一种情况。它是由@genpfault指出的4(32位)或8(64位)。简单的解决方案将如下所示更改您的功能。

void glBuffer::setdata(const void *data, int numElements, size_t elementSize, GLenum mode) 
{ 
    glBindBuffer(m_target, m_buffer); 
    glBufferData(m_target, numElements * elementSize, data, mode); 
    glBindBuffer(m_target, 0); 
} 
在此函数“包含numElements”

是您的无效*数据点和“elementSize”是每个元件的尺寸的阵列中的元件的数目。

这里是上述功能

float vertex_buffer_data[9] = {0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f}; 
glBuffer vbo(GL_ARRAY_BUFFER); 
vbo.setdata(vertex_buffer_data, 9, sizeof(float), GL_STATIC_DRAW); 
vbo.bind(0, 3); 

的示例代码和它应该工作。如果您仍然感到困惑,下面是一个小示例程序,用于说明您的代码无法工作的原因。

#include "stdafx.h" 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    int a[5] = {1, 2, 3, 4, 5}; 
    void* ptr = a; 
    printf(" sizeof(a) = %d \n", sizeof(a)); 
    printf(" sizeof(a[0]) = %d \n", sizeof(a[0])); 
    printf(" sizeof(ptr) = %d \n", sizeof(ptr)); 
    getchar(); 

    return 0; 
} 

输出:

sizeof(a) = 20 
sizeof(a[0]) = 4 
sizeof(ptr) = 4 

注意:这被编译上的窗口在视觉工作室32位,因此指针大小为4个字节。如果我将它编译为64位,那将是8。

+0

谢谢!我设法让它使用矢量工作。真酷! – Talesseed

+0

您可以随时打印尺寸并验证其正确性,无论您使用哪种方法。在之前的评论中,@genpfault建议使用'std :: vector'。一旦有人明白为什么一段代码无法按预期工作,那么它很容易。祝你好运。 – Harish

+0

是的,这很容易。对于大小我使用data.size()* sizeof(T)其中T模板我定义:) – Talesseed