将基本OpenGL纹理转换为四边形到GLSL

时间:2015-04-22 13:01:30

标签: opengl textures glsl shader

我目前正在尝试将我原有的OpenGL代码转换为现代OpenGL,但我无法让它做我想做的事。

我使用的代码非常基本。它将视频帧渲染为FBO四边形(保留纵横比)。

这是我的GL代码:

glBindFramebuffer(GL_FRAMEBUFFER, device.drawingFramebufferID);

glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, deviceSize.width, deviceSize.height);

static const GLfloat squareVertices[] =
{
    (GLfloat)scaledFrameRect.origin.x,
    (GLfloat)scaledFrameRect.origin.y,
    (GLfloat)(scaledFrameRect.origin.x + scaledFrameRect.size.width),
    (GLfloat)scaledFrameRect.origin.y,
    (GLfloat)(scaledFrameRect.origin.x + scaledFrameRect.size.width),
    (GLfloat)(scaledFrameRect.origin.y + scaledFrameRect.size.height),
    (GLfloat)scaledFrameRect.origin.x,
    (GLfloat)(scaledFrameRect.origin.y + scaledFrameRect.size.height)
};

static const GLfloat textureVertices[] = {
    0.0f, 0.0f,
    (GLfloat)frame.width, 0.0f,
    (GLfloat)frame.width,  (GLfloat)frame.height,
    0.0f, (GLfloat)frame.height
};

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_DEPTH_TEST);

mtxLoadIdentity(projection);
mtxLoadIdentity(modelView);
mtxLoadIdentity(mvp);

mtxLoadOrthographic(projection, 0.0, deviceSize.width, 0.0f,deviceSize.height, 5.0, 10000);
mtxMultiply(mvp, projection, modelView);

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, frame.texID);
glActiveTexture(GL_TEXTURE0);

// Use shader program.
glUseProgram(self.textureRenderShader);

glUniform1i(uniforms[UNIFORM_VIDEOFRAME], /*GL_TEXTURE*/0);
glUniformMatrix4fv(uniforms[UNIFORM_MVP], 1, GL_FALSE, mvp);

// Update attribute values.
glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

CGLFlushDrawable(device.renderingContext);

glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

这是片段着色器:

#version 150
in vec2 textureCoordinate;
out vec4 fragColor;

uniform sampler2D videoFrame;

void main()
{  
    fragColor = texture(videoFrame, textureCoordinate.st, 0.0);
}

和顶点着色器:

uniform mat4 modelViewProjectionMatrix;

#version 150
in vec4  position;
in vec2  inputTextureCoordinate;
out vec2 textureCoordinate;

void main()
{
    gl_Position = position * modelViewProjectionMatrix;
    textureCoordinate = inputTextureCoordinate;
}

将纹理绘制到帧缓冲区并使用glReadPixels下载帧缓冲区的内容后,我只得到一个绿色缓冲区。

以' mtx'开头的功能来自Apple示例代码项目,因此我假设它们是正确的。

我不知道出了什么问题以及什么可能导致这种奇怪的输出。我希望任何人都能说出我做错了什么。谢谢!

修改

我尝试在使用核心配置文件之前下载完美无缺的纹理。现在下载的纹理仅为绿色(背景颜色)。所以也许绘图代码并没有错,但纹理上传代码是(这没有被修改,因为我认为它不需要,但也许这是错误的):

glEnable(GL_TEXTURE_RECTANGLE_ARB);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, frame.texID);

glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB,
             frame.width, frame.height, 0,
             GL_YCBCR_422_APPLE,
             GL_UNSIGNED_SHORT_8_8_REV_APPLE,
             frame.frameData);

unsigned char* buffer = (unsigned char*) malloc(frame.width*frame.height*3);
glGetTexImage(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGB, GL_UNSIGNED_BYTE, buffer);

即使我上传视频帧,下载的缓冲区也只包含背景色。

1 个答案:

答案 0 :(得分:0)

经过数小时的反复试验,我发现核心配置文件中的像素格式GL_YCBCR_422_APPLE似乎不可用。

有趣的是,如果着色器编译失败,纹理上载将起作用。如果着色器编译并且版本不是< 140,纹理上传有效。