是啥导致基于 OpenGL 2.0 的着色器处理代码在 ::glBegin() 中崩溃?
Posted
技术标签:
【中文标题】是啥导致基于 OpenGL 2.0 的着色器处理代码在 ::glBegin() 中崩溃?【英文标题】:What is causing OpenGL 2.0 based shader handling code to crash in ::glBegin()?是什么导致基于 OpenGL 2.0 的着色器处理代码在 ::glBegin() 中崩溃? 【发布时间】:2012-03-05 07:55:59 【问题描述】:物有所值:
我的图形驱动程序 (ATI Mobility Radeon 4570) 是最新的。 我之前已经设法让基于 ARB 扩展的着色器处理代码在相同的配置上工作(尽管我回到着色器之前已经有一段时间了)。 我在我的设置中遵循 Lighthouse3d 教程(...松散地:Lighthouse3d shader setup 着色器编译日志代码已从一个 SO 问题中撕下,抱歉缺乏信用,我现在似乎找不到它)基本上,我所有的 OpenGL 操作似乎都成功执行了;着色器编译和程序链接。正如您在下面看到的,我在每次 gl*** 调用后都检查了 OpenGL 错误。着色器本身是微不足道的。
当然,我可能忽略了一些简单得可笑的事情。
#define GLOP(operation) operation; if(!GFX::CheckError(#operation)) exit(1)
// GFX::CheckError() prints an error message, if any.
GFX::Init(640, 480, 24, 0);
GLOP(Texture2D::Enable());
// shader setup
GLuint hFrag = GLOP(::glCreateShader(GL_FRAGMENT_SHADER));
GLuint hVert = GLOP(::glCreateShader(GL_VERTEX_SHADER));
GLuint hProg = GLOP(::glCreateProgram());
std::ifstream inFile;
ReadOpen("shader.frag", inFile);
std::string str(ReadFile(inFile));
const char* pSource = str.c_str();
GLOP(::glShaderSource(hFrag, 1, &pSource, 0));
GLOP(::glCompileShader(hFrag));
GLint logLength;
glGetShaderiv(hFrag, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0)
GLchar* log = (GLchar*)malloc(logLength);
glGetShaderInfoLog(hFrag, logLength, &logLength, log);
printf("Shader compile log:\n%s\n", log);
free(log);
XR::ReadOpen(core.GetPath() + "shader.vert", inFile);
XRLOG(XR::GetFileSize(inFile) << " bytes in file." << std::endl);
str = XR::ReadFile(inFile);
pSource = str.c_str();
GLOP(::glShaderSource(hVert, 1, &pSource, 0));
GLOP(::glCompileShader(hVert));
glGetShaderiv(hVert, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0)
GLchar* log = (GLchar*)malloc(logLength);
glGetShaderInfoLog(hVert, logLength, &logLength, log);
printf("Shader compile log:\n%s\n", log);
free(log);
GLOP(::glAttachShader(hProg, hFrag));
GLOP(::glAttachShader(hProg, hVert));
GLOP(::glLinkProgram(hProg));
glGetProgramiv(hProg, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0)
GLchar* log = (GLchar*)malloc(logLength);
glGetProgramInfoLog(hProg, logLength, &logLength, log);
printf("Program link log:\n%s\n", log);
free(log);
GLOP(::glUseProgram(hProg));
// get uniform's location
GLint locTex0 = GLOP(::glGetUniformLocation(hProg, "tex0"));
/// [loading image, creating texture goes here. works perfectly.]
while(core.IsRunning())
GLOP(::glActiveTexture(GL_TEXTURE0));
GLOP(pTex->Bind());
GLOP(::glUniform1i(locTex0, GL_TEXTURE0));
GLOP(::glPushMatrix());
GLOP(::glTranslatef(GFX::GetFlopWidth() / 2, GFX::GetHeight() / 2, .0f)); // still no errors
::glBegin(GL_TRIANGLE_FAN); // crash
::glTexCoord2f(.0f, 1.0f);
::glVertex2f(-100.0f, -100.0f);
::glTexCoord2f(1.0f, 1.0f);
::glVertex2f(100.0f, -100.0f);
::glTexCoord2f(1.0f, .0f);
::glVertex2f(100.0f, 100.0f);
::glTexCoord2f(.0f, .0f);
::glVertex2f(-100.0f, 100.0f);
::glEnd();
::glPopMatrix();
顶点着色器:
void main( void )
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
片段着色器:
uniform sampler2D tex0;
void main()
vec2 texCoords = gl_TexCoord[0].st;
vec3 pixel = texture2D(tex0, texCoords).xyz;
gl_FragColor = vec4(pixel, 1.0);
输出:
Successfully set video mode 640x480@24
Shader compile log:
Fragment shader was successfully compiled to run on hardware.
Shader compile log:
Vertex shader was successfully compiled to run on hardware.
Program link log:
Vertex shader(s) linked, fragment shader(s) linked.
【问题讨论】:
【参考方案1】:它会在第一帧崩溃吗?
我有点怀疑这与您的崩溃有关,但您应该知道您调用 glVertex/glTexcoord 的顺序错误。 glVertex 终止一个顶点,因此在您的情况下,第一个 glVertex 没有设置 texcoord,并且您的最后一个 texcoord 将在下一个循环中应用。
【讨论】:
是的,它在第一帧就崩溃了。感谢您指出 glVertex2f 和 glTexCoord2f 的错误顺序 - 这是仓促写出纹理四边形渲染的产物;我现在已经编辑过了。此示例中的运行时在崩溃之前永远不会到达那里。【参考方案2】:核心配置文件不支持像这样提交顶点的立即模式,所以我想知道您是否在设置 OpenGL 上下文时指定了核心配置文件。这可以解释为什么它会在 glBegin 处死掉。
【讨论】:
似乎不太可能导致它硬崩溃。此外,他在前几行也调用了 glPushMatrix,这也不是核心。 好点。另外,我在自己的设置中尝试了这个,使用核心配置文件执行命令很好。他们只是没有做任何有用的事情。所以我现在认为其他地方存在问题,可能是由其他原因引起的某种堆栈损坏。以上是关于是啥导致基于 OpenGL 2.0 的着色器处理代码在 ::glBegin() 中崩溃?的主要内容,如果未能解决你的问题,请参考以下文章
IOS:OpenGL ES 2.0 与 3.0 中动态分支着色器的性能
如何在 OpenGL ES 2.0 中获得“发光”着色器效果?
用于模糊的 OpenGL ES 2.0 片段着色器速度慢且质量低