为什么我不能将此纹理统一附加到我的GLSL片段着色器?
在我的Mac应用程序中,我基于来自附加摄像机的YUV 4:2:2数据定义矩形纹理.使用标准的顶点和纹理坐标,我可以将其绘制到屏幕上的矩形区域,而不会出现任何问题.
In my Mac application, I define a rectangular texture based on YUV 4:2:2 data from an attached camera. Using standard vertex and texture coordinates, I can draw this to a rectangular area on the screen without any problems.
但是,我想使用GLSL片段着色器在GPU上处理这些图像帧,并且在将矩形矩形矩形视频纹理统一传递给片段着色器时遇到了麻烦.当我尝试这样做时,纹理会读为黑色.
However, I would like to use a GLSL fragment shader to process these image frames on the GPU, and am having trouble passing in the rectangular video texture as a uniform to the fragment shader. When I attempt to do so, the texture simply reads as black.
着色器程序编译,链接并通过验证.我从着色器程序收到了统一的正确地址.其他制服(例如浮点值)会正确传入,并且片段着色器会响应这些值的更改.片段着色器接收正确的纹理坐标.我还用glGetError()大量添加了代码,却看不到任何错误.
The shader program compiles, links, and passes validation. I am receiving the proper address for the uniform from the shader program. Other uniforms, such as floating point values, pass in correctly and the fragment shader responds to changes in these values. The fragment shader receives the correct texture coordinates. I've also sprinkled my code liberally with glGetError() and seen no errors anywhere.
顶点着色器如下:
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
}
和片段着色器如下:
uniform sampler2D videoFrame;
void main()
{
gl_FragColor = texture2D(videoFrame, gl_TexCoord[0].st);
}
这应该只是在我的矩形几何图形上显示纹理.
This should simply display the texture on my rectangular geometry.
相关的绘图代码如下:
static const GLfloat squareVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
const GLfloat textureVertices[] = {
0.0, videoImageSize.height,
videoImageSize.width, videoImageSize.height,
0.0, 0.0,
videoImageSize.width, 0.0
};
CGLSetCurrentContext(glContext);
if(!readyToDraw)
{
[self initGL];
readyToDraw = YES;
}
glViewport(0, 0, (GLfloat)self.bounds.size.width, (GLfloat)self.bounds.size.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &textureName);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, textureName);
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, videoImageSize.width, videoImageSize.height, 0, GL_YCBCR_422_APPLE, GL_UNSIGNED_SHORT_8_8_REV_APPLE, videoTexture);
glUseProgram(filterProgram);
glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
glTexCoordPointer(2, GL_FLOAT, 0, textureVertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
[super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:interval displayTime:timeStamp];
glDeleteTextures(1, &textureName);
此代码位于CAOpenGLLayer中,超类的-drawInCGLContext:pixelFormat:forLayerTime: displayTime:
仅在其中运行glFlush()
.
This code resides within a CAOpenGLLayer, where the superclass's -drawInCGLContext:pixelFormat:forLayerTime: displayTime:
simply runs glFlush()
.
使用以下代码读取统一地址:
The uniform address is read using code like the following:
uniforms[UNIFORM_VIDEOFRAME] = glGetUniformLocation(filterProgram, "videoFrame");
正如我所说,如果我注释掉glUseProgram()
和glUniform1i()
线,则此纹理矩形将正确绘制.将它们留在其中会导致绘制黑色矩形.
As I said, if I comment out the glUseProgram()
and glUniform1i()
lines, this textured rectangle draws properly. Leaving them in leads to a black rectangle being drawn.
是什么导致我的纹理均匀性无法传递到片段着色器中?
What could be preventing my texture uniform from being passed into my fragment shader?
不确定所使用的GLSL版本,但是从1.40起,类型为sampler2DRect
专门用于访问非二次幂纹理. 可能是您要寻找的东西,但是我不知道在glsl 1.40之前如何处理矩形纹理.
Not sure about the GLSL version you're using, but from 1.40 upwards there's the type sampler2DRect
specifically for accessing non-power-of-two textures. Might be what you're looking for, however I don't know how rectangular textures were handled before glsl 1.40.