//Vertex Shader
#version 450 core
out vec3 vs_color;
layout(location=0) in vec3 position;
layout(location=1) in vec3 colors;
uniform float x_offset;
void main(void)
{
gl_Position = vec4(position,1.0);
gl_Position.x += x_offset;
//vs_color = colors;
vs_color = position;
}
//Fragment Shader
#version 450 core
out vec4 color;
in vec3 vs_color;
void main(void)
{
color = vec4(vs_color,1);
}
这仅在我在顶点着色器中使用vs_color = colors时有效,对于任何其他值,例如:position(包含顶点的xyz坐标)或vec3(0.1,0.1,0.1),它将在glDrawArrays()处引发此异常: / p>
Exception thrown at 0x048D1AD0 (nvoglv32.dll) in OpenGL Starting Out.exe:
0xC0000005: Access violation reading location 0x00000000.
为什么会发生这种情况,我该如何解决? (我想尝试将位置值设置为颜色值)
编辑:
另外,如果我没有使用
启用第二个顶点属性
glEnableVertexArrayAttrib(VAO,1) //VAO is my vertex array object
我能够做我想做的(将位置传递到片段着色器)
但是如果启用它,我需要将其传递给片段着色器,然后输出颜色(如果我在片段着色器中不对其进行任何操作,则会产生相同的错误)
属性的设置方法如下:
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesAndcolors), verticesAndcolors, GL_STATIC_DRAW);
glVertexAttribPointer(
glGetAttribLocation(rendering_program,"position"),
3,
GL_FLOAT,
GL_FALSE,
6*sizeof(float),
(void*)0
);
glVertexAttribPointer(
glGetAttribLocation(rendering_program,"colors"),
3,
GL_FLOAT,
GL_FALSE,
6*sizeof(float),
(void*)(3*sizeof(float))
);
glEnableVertexArrayAttrib(VAO, 0);
glEnableVertexArrayAttrib(VAO, 1);
编辑2:
如果我这样做:
gl_Position = vec4(colors,1.0);
vs_color = position;
它不会产生访问冲突并且可以正常工作,
我检查了如何设置我的顶点属性,但除此之外我做不到。
答案 0 :(得分:1)
此问题的根本原因在于:
glVertexAttribPointer(glGetAttribLocation(rendering_program,"position"), ...) glVertexAttribPointer(glGetAttribLocation(rendering_program,"colors"), ...); ... glEnableVertexArrayAttrib(VAO, 0); glEnableVertexArrayAttrib(VAO, 1);
只有活动属性将具有位置,并且您是否可以使用layout(location=...)
限定属性并不重要。如果在着色器中未使用该属性,则该属性将被优化,因此将没有位置。 glGetAttribLocation()
返回一个 signed 整数,并使用返回值-1
表示该名称不存在活动属性。 glVertexAttribPointer()
期望一个 unsigned 属性位置,并且(GLuint)-1
最终将以一个很大的数字出现,该数字超出了允许的范围,因此此函数只会产生GL错误,但未设置任何指针。
但是,您将glEnableVertexArrayAttrib()
与硬编码位置0
和1
一起使用。
每个属性的默认顶点属性指针为0
,绑定该属性的默认cvertex数组缓冲区也将为0
,因此该指针将被解释为指向客户端的指针侧存储器。
这意味着如果position
和color
都处于活动状态(意味着:在代码中以某种方式使用,以便着色器编译器/链接器无法完全排除它可能影响输出的可能性),您的代码将按预期运行。
但是,如果仅使用一个,则不会为另一个设置指针,但仍会启用该数组。这意味着您的驱动程序实际上将访问地址为0
的内存:
在OpenGL Starting Out.exe中抛出0x048D1AD0(nvoglv32.dll)的异常: 0xC0000005:访问冲突读取位置0x00000000。
所以这里有几件事:
glGetAttribLocation()
的结果,并正确处理-1
情况。glVertexAttribPointer
和相应的glEnableVertexAttrib()
的属性索引API error high [0x501]: GL_INVALID_VALUE error generated. Index out of range.
时,我的实现(Nvidia / Linux)将报告glVertexAttribPointer(-1,...)
。答案 1 :(得分:0)
我终于能够解决此问题:
我在绘图循环中调用glUseProgram(programObj)
,将其移出解决了问题
我不确定为什么会导致问题发生,但是我的猜测是openGL在未使用vertex属性时做了一些操作,然后该更改在下一次迭代中导致了访问冲突。
随时告诉我您是否知道原因