[英]Custom OpenGL buffer class doesn't display anything
我想创建一个类来处理诸如顶点缓冲区对象或颜色缓冲区之类的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,glw。
这是您用于设置缓冲区数据的工作代码
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(data)与第一种情况不同。 @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”是您的void *数据指向的数组中的元素数,“ 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
注意:这是在Visual Studio中的32位Windows上编译的,因此指针大小为4个字节。 如果用64位编译,它将是8。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.