gpt4 book ai didi

opengl - 不同显卡上的 GLSL 片段着色器

转载 作者:行者123 更新时间:2023-12-02 05:07:02 31 4
gpt4 key购买 nike

我正在尝试使用 GLSL 着色器将 12 位 YUV 帧 (YUV420P) 转换为 24 位 RGB 帧。在 Nvidia 视频卡上它可以工作,但在 ATI 视频卡上它也可以工作,但工作不正确。图像绘制不正确。颜色不同,图像是完整尺寸的四分之一。

这是着色器的代码:

uniform sampler2DRect y_texture, u_texture, v_texture;
uniform float imageHeight;

void main(void) {
float sx, sy, r, g, b, y, u, v;
sx = gl_TexCoord[0].x;
sy = imageHeight - gl_TexCoord[0].y;
y = texture2DRect(y_texture, vec2(sx / 2.0, sy / 2.0)).r;
u = texture2DRect(u_texture, vec2(sx / 2.0, sy / 2.0)).r;
v = texture2DRect(v_texture, vec2(sx / 2.0, sy / 2.0)).r;
y = 1.1643 * (y - 0.0625);
u = u - 0.5;
v = v - 0.5;
r = y + 1.5958 * v;
g = y - 0.39173 * u - 0.8129 * v;
b = y + 2.017 * u;
gl_FragColor = vec4(r, g, b, 1.0);
}

我如何修改它(或创建新的)?

示例代码如下:

glEnable(GL_TEXTURE_RECTANGLE_ARB);

//FrameHeight
int i_imageHeight = glGetUniformLocation(handleProgram, "imageHeight");
glUniform1f(i_imageHeight, (float)frameHeight);

//U
glActiveTexture(GL_TEXTURE1);
int i_u = glGetUniformLocationARB(handleProgram, "u_texture");
glUniform1iARB(i_u, 1);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 1);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, frameWidth / 2, frameHeight / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, uFrameData);

//V
glActiveTexture(GL_TEXTURE2);
int i_v = glGetUniformLocationARB(handleProgram, "v_texture");
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 2);
glUniform1iARB(i_v, 2);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, frameWidth / 2, frameHeight / 2, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, vFrameData);

//Y
glActiveTexture(GL_TEXTURE0);
int i_y = glGetUniformLocationARB(handleProgram, "y_texture");
glUniform1iARB(i_y, 3);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);

glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_LUMINANCE, frameWidth, frameHeight, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, yFrameData);

//Draw
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(0, 0);
glTexCoord2i(frameWidth, 0); glVertex2i(this->width, 0);
glTexCoord2i(frameWidth, frameHeight); glVertex2i(this->width, this->height);
glTexCoord2i(0, frameHeight); glVertex2i(0, this->height);
glEnd();

glFlush();
SwapBuffers(hDC);

最佳答案

您没有正确使用纹理。我在任何地方都看不到您创建纹理对象 (glGenTextures)。您需要先生成 3 个纹理对象,然后将它们传递到 glBindTexture 中。相反,您正在做的是使用 0、1 和 2 索引,这也是不正确的,因为 0 是不存在的纹理的索引。我怀疑 OpenGL 会在任何尝试更改 0 纹理状态时为您提供错误代码。所以在调用之间添加一些 glError() 检查。从技术上讲,您的程序是 GL 上“未定义行为”的一个示例,因此应该预料到各种硬件/驱动程序的执行差异(直到您修复它)。

供您引用,纹理管理应如下所示:

GLuint textures[3];
glGenTextures(3,textures);
...
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[1]);
//initialize state of t1
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[2]);
//initialize state of t2
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[0]);
//initialize state of t0

请注意,您对 glUniform 和 glActiveTexture 的调用仍然正确,因此无需修复它们。

关于opengl - 不同显卡上的 GLSL 片段着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9869667/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com