2012-03-26 2 views
3

12 비트 YUV 프레임 (YUV420P)을 GLSL 쉐이더가있는 24 비트 RGB 프레임으로 변환하려고합니다. Nvidia 비디오 카드에서 작동하지만 ATI 비디오 카드에서도 작동하지만 올바르지 않습니다. 이미지가 올바르게 그려지지 않습니다. 색상이 다르며 이미지가 전체 크기의 1/4입니다.다른 비디오 카드에있는 GLSL 조각 쉐이더

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); 
+3

"올바르지 않음"을 정의하십시오. – Bart

+2

호스트 코드도 게시하십시오. GL_TEXTURE_RECTANGLE_ARB 대신 GL_TEXTURE_2D를 사용하고 계신지요? – sschuberth

+0

코드를 게시했습니다 ... 셰이더에 또한 : y = texture2DRect (y_texture, vec2 (sx/2.0, sy/2.0)). r; 이 줄은 ATI 카드 용입니다. nVidia 카드에서 : y = texture2DRect (y_texture, vec2 (sx, sy)). r; – Alexander

답변

0

:

다음은 샘플 코드입니다. 아무데도 텍스처 오브젝트 (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에 전화가 여전히 올바른지 주, 그래서이를 해결하기 위해 필요 없음.

관련 문제