这是初学者级别的OpenGL C ++问题
我尝试使用GL_ARRAY_BUFFER更新三角形偏移。这是一个简单的例子,说明了我的问题。 #define crashversion
用于启用我认为应该可以运行但导致崩溃的版本。将#define
删除,其余的源代码将被删除。我还是初学者,所以我使用的是一些在这里看不到的功能。 AyOpenGL::GlShader;
AyOpenGL::GlProgram;
是瘦辅助类,用于管理着色器和程序的内存和加载。它们已被证明可以与我的所有其他功能一起使用。 sb6::application
是OpenGL超级圣经第6版的助手类。我非常确定那些是合理的无bug,我对opengl缓冲区的理解是问题的核心。我可以编辑和支持片段,如果这有助于anser。
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。
所以它看起来像一个nullpointer问题
答案 0 :(得分:1)
您永远不会为属性0设置顶点属性指针,因此您永远不会使用您创建的VBO。但是,您为属性零启用数组,这将导致GL访问一些完全无效的内存位置 - 这可能会崩溃。
也许OpenGL wiki entry on Vertex Specification可能会帮助您理解这些概念。
答案 1 :(得分:0)
正如@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);
}
我可以看到额外的改进潜力,但我在示例中进行了最小的改变。