使用GL_ARRAY_BUFFER更新垂直数据
Using GL_ARRAY_BUFFER to update vertice data
这是一个初级OpenGL C++问题
我尝试使用GL_ARRAY_BUFFER更新三角形偏移。这里有一个简单的例子来说明我的问题。#define crashversion
用于启用我认为应该工作但会导致崩溃的版本。如果CCD_ 2被移除,则源工作的剩余部分。我还是一个初学者,所以我使用了一些在这里看不到的功能。AyOpenGL::GlShader;
AyOpenGL::GlProgram;
是管理内存以及着色器和程序加载的瘦辅助类。它们已经被证明可以与我的所有其他功能配合使用。sb6::application
是OpenGL超级圣经第6版中的一个辅助类。我非常确信这些都是合理的无错误,并且我对opengl缓冲区的理解是问题的核心。我可以编辑和支持片段,如果这将有助于回答。
class stackexample : public sb6::application
{
private:
GLuint vertex_array_Object;
GLuint buffer;
std::unique_ptr<AyOpenGL::GlProgram> program;
public:
void render(double currentTime);
void startup();
void shutdown();
};
#define crashversion
void stackexample::startup()
{
vector<shared_ptr<GlShader>> shaders;
shaders.push_back(make_shared<GlShader>("Shaders//VS_Triangle_IN_offset.c", GL_VERTEX_SHADER));
shaders.push_back(make_shared<GlShader>("Shaders//FS_CyanColor.c", GL_FRAGMENT_SHADER));
program = std::make_unique<GlProgram>("program", shaders);
glGenVertexArrays(1, &vertex_array_Object);
glBindVertexArray(vertex_array_Object);
#ifdef crashversion
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_STATIC_DRAW);
#endif
}
void stackexample::render(double currentTime)
{
GLfloat black[] = { 0.0f, 0.0f, 0.0f, 1.0f };
GLfloat offset[] = { (float)std::sin(currentTime), 0.0f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, black);
glUseProgram(*program);
#ifdef crashversion
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(offset), offset);
glEnableVertexAttribArray(0);
#else
glVertexAttrib4fv(0, offset);
#endif
glDrawArrays(GL_TRIANGLES, 0, 3);
}
void stackexample::shutdown()
{
glDeleteVertexArrays(1, &vertex_array_Object);
}
VS_Triangle_IN_offset.c:
#version 430 core
layout (location = 0) in vec4 offset;
void main(void)
{
const vec4 vertices[] = vec4[](vec4( 0.25, -0.25, 0.5, 1.0),
vec4(-0.25, -0.25, 0.5, 1.0),
vec4( 0.25, 0.25, 0.5, 1.0));
gl_Position = vertices[gl_VertexID] + offset;
}
FS_CyanColor.c:
#version 430 core
out vec4 color;
void main(void)
{
color = vec4(0.0, 0.8, 1.0, 1.0);
}
我的理解是,在两个版本中,我都通过缓冲区将偏移推入着色器。尽管第二个版本不起作用,我也不知道为什么。我尝试了不同的代码星座,并试图对此进行研究,但我无法在这里自学。
如何编写crashversion
,使其与正常版本做完全相同的事情?
编辑:我用"崩溃"这个词很随便。它崩溃时有点未定义,但主要是这样的:OpenGLDemo.exe中0x04A025AD(nvoglv32.dll)处未处理的异常:0xC0000005:读取位置0x00000000的访问冲突。
所以它看起来像是一个空指针问题
您从未为属性0设置顶点属性指针,因此您从未使用创建的VBO。但是,您为属性0启用了数组,这将导致GL访问一些完全无效的内存位置,这很可能会崩溃。
也许顶点规范上的OpenGL wiki条目可能有助于您理解这些概念。
正如@derhass所指出的,阅读额外的文档澄清了一些问题。
以下是我为使代码运行而对代码所做的更改。
void stackexample::startup()
{
vector<shared_ptr<GlShader>> shaders;
shaders.push_back(make_shared<GlShader>("Shaders//VS_Triangle_IN_offset.c", GL_VERTEX_SHADER));
shaders.push_back(make_shared<GlShader>("Shaders//FS_CyanColor.c", GL_FRAGMENT_SHADER));
program = std::make_unique<GlProgram>("program", shaders);
glGenVertexArrays(1, &vertex_array_Object);
glBindVertexArray(vertex_array_Object);
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 1000, NULL, GL_STATIC_DRAW);
}
void stackexample::render(double currentTime)
{
GLfloat black[] = { 0.0f, 0.0f, 0.0f, 1.0f };
GLfloat vertex_offset[] = { (float)std::sin(currentTime), 0.0f, 0.0f, 1.0f };
glClearBufferfv(GL_COLOR, 0, black);
glUseProgram(*program);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertex_offset), vertex_offset);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertex_offset), sizeof(vertex_offset), vertex_offset);
glBufferSubData(GL_ARRAY_BUFFER, 2 * sizeof(vertex_offset), sizeof(vertex_offset), vertex_offset);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
我可以看到额外的改进潜力,但我在示例中选择了最小的更改。
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- 嵌套在类中时无法设置成员数据
- 使用流处理接收到的数据
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在cuda线程之间共享大量常量数据
- C++将文本文件中的数据读取到结构数组中
- 如何在C++中序列化结构数据
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 在c代码之间共享数据的最佳方式
- 链表,反向函数,数据结构
- 数据成员SFINAE的C++17测试:gcc vs clang
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- 如何对点云数据进行排序
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 指向纹理数据的指针-垂直翻转数据
- 使用GL_ARRAY_BUFFER更新垂直数据
- QTableView垂直调整未刷新的数据大小