GLSL фрагмент шейдера на разных видеокартах - PullRequest
3 голосов
/ 26 марта 2012

Я пытаюсь преобразовать 12-битный кадр YUV (YUV420P) в 24-битный кадр RGB с шейдером GLSL.На видеокартах 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);

1 Ответ

0 голосов
/ 06 декабря 2013

Вы используете текстуры неправильно. Нигде не видно, как вы создаете объекты текстуры (glGenTextures). Сначала вам нужно сгенерировать 3 текстурных объекта и передать их внутрь glBindTexture. Вместо этого вы используете индексы 0, 1 и 2, что также неверно, поскольку 0 - это индекс для несуществующей текстуры. Я подозреваю, что OpenGL выдаст вам коды ошибок при любой попытке изменить состояние текстуры 0. Поэтому добавьте некоторые проверки glError () между вызовами. Технически, ваша программа является примером «неопределенного поведения» в GL, поэтому следует ожидать различия в выполнении различными HW / драйверами (пока вы не исправите это).

Для справки, управление текстурой должно выглядеть так:

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 по-прежнему верен, поэтому нет необходимости их исправлять.

...