代码之家  ›  专栏  ›  技术社区  ›  Brad Larson Code Synthesis

为什么我不能将此纹理统一附加到GLSL片段着色器?

  •  3
  • Brad Larson Code Synthesis  · 技术社区  · 13 年前

    在我的Mac应用程序中,我定义了一个矩形纹理,它基于附加相机的YUV 4:2:2数据。使用标准的顶点和纹理坐标,我可以将其绘制到屏幕上的一个矩形区域而不会出现任何问题。

    但是,我想使用GLSL片段着色器在GPU上处理这些图像帧,并且很难将矩形视频纹理作为统一传递给片段着色器。当我尝试这样做时,纹理只是读作黑色。

    着色器程序编译、链接并通过验证。我从shader程序收到制服的正确地址。其他统一格式(如浮点值)将正确传入,片段着色器将响应这些值中的更改。片段着色器接收正确的纹理坐标。我还用glGetError()大量地散布了代码,在任何地方都没有看到错误。

    顶点着色器如下所示:

    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);
    }
    

    这只需要在我的矩形几何体上显示纹理。

    相关图纸代号如下:

    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() .

    使用如下代码读取统一地址:

    uniforms[UNIFORM_VIDEOFRAME] = glGetUniformLocation(filterProgram, "videoFrame");
    

    如我所说,如果我把 glUseProgram() glUniform1i() 线条,这个有纹理的矩形画得很好。把它们留在里面,就会画出一个黑色的矩形。

    什么可以阻止我的纹理均匀性传递到我的碎片着色器?

    1 回复  |  直到 13 年前
        1
  •  7
  •   Kos    13 年前

    不确定你使用的是GLSL版本,但从1.40开始,就有了 sampler2DRect 专门用于访问两个纹理的非幂。 可能 你要找的是什么,但是我不知道在glsl 1.40之前矩形纹理是如何处理的。