OpenGL使用着色器将NV12转换为RGB24

OpenGL使用着色器将NV12转换为RGB24,opengl,colors,rgb,fragment-shader,yuv,Opengl,Colors,Rgb,Fragment Shader,Yuv,我试图编写一个应用程序来在OpenGL中显示YUV图像。在C++中,使用此片段成功地将YUV转换为RGB() 但我得到的只是绿色和粉色的像素。我是OpenGL的新手。有人能指出我可能错在哪里吗?谢谢你的帮助 更新:添加加载纹理的代码 FILE fp = fopen("nv21.raw", "rb"); unsigned char *yuvBuffer = new unsigned char[width*height*3/2]; fread(yuvBuffer, 1, width*height*3

我试图编写一个应用程序来在OpenGL中显示YUV图像。在C++中,使用此片段成功地将YUV转换为RGB()

但我得到的只是绿色和粉色的像素。我是OpenGL的新手。有人能指出我可能错在哪里吗?谢谢你的帮助

更新:添加加载纹理的代码

FILE fp = fopen("nv21.raw", "rb");
unsigned char *yuvBuffer = new unsigned char[width*height*3/2];
fread(yuvBuffer, 1, width*height*3/2, fp);

unsigned char *vuBuffer = &yuvBuffer[width*height];

int bufSize = width*height/4;
unsigned char *uBuffer = new unsigned char[bufSize];
memset(uBuffer, 0, bufSize);
unsigned char *vBuffer = new unsigned char[bufSize];
memset(vBuffer, 0, bufSize);

unsigned char *uPtr, *vPtr;
uPtr = uBuffer;
vPtr = vBuffer;

for (int i = 0; i < bufSize; i++)
{
    *vPtr = *vuBuffer++;
    *uPtr = *vuBuffer++;
}

GLuint textureID[3];

glGenTextures(1, &textureID[0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, &yuvBuffer[0]);
glBindTexture(0);

glGenTextures(1, &textureID[1]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textureID[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width/2, height/2, 0, GL_RED, GL_UNSIGNED_BYTE, uBuffer);
glBindTexture(0);

glGenTextures(1, &textureID[2]);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, textureID[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width/2, height/2, 0, GL_RED, GL_UNSIGNED_BYTE, vBuffer);
glBindTexture(0);
文件fp=fopen(“nv21.raw”、“rb”);
无符号字符*yuvBuffer=新的无符号字符[宽度*高度*3/2];
fread(yuvBuffer,1,宽*高*3/2,fp);
无符号字符*Vubffer=&yuvBuffer[width*height];
int bufSize=宽度*高度/4;
unsigned char*uBuffer=新的unsigned char[bufSize];
memset(uBuffer,0,bufSize);
unsigned char*vBuffer=新的unsigned char[bufSize];
memset(vBuffer,0,bufSize);
无符号字符*uPtr,*vPtr;
uPtr=uBuffer;
vPtr=vBuffer;
对于(int i=0;i
默认情况下,着色器程序中的纹理采样器与纹理单元0关联(默认值为0)。
必须通过将纹理单元的索引指定给纹理采样器。纹理单元是纹理和对象之间的绑定点。e、 g:

GLint locTexY=glGetUniformLocation(程序,“textureY”); GLint locTexU=glGetUniformLocation(程序,“textureU”); GLint locTexV=glGetUniformLocation(程序,“textureV”);
glUseProgram(程序);
glUniform1i(locTexY,0);//对应于GL_纹理0
glUniform1i(locTexU,1);//对应于GL_纹理1
glUniform1i(locTexV,2);//对应于GL_纹理2

自OpenGL 4.20以来,可以通过以下方式在着色器中设置:

layout(binding=0)统一采样器2D纹理;
布局(装订=1)统一的纹理;
布局(装订=2)均匀取样器;

着色器似乎不是问题所在。您必须显示创建纹理图像的代码和设置纹理采样器的代码。@rabbi76我刚刚编辑过,请看一下为什么
width/4
?您将纹理单位的索引分配给纹理采样器制服的何处?@Rabbi76
glActiveTexture(GL_TEXTURE0)、glActiveTexture(GL_TEXTURE1)、glActiveTexture(GL_TEXTURE2)
将分别通过opengl@Rabbid76很抱歉它应该是
width/2
height/2
uniform sampler2D textureY;
uniform sampler2D textureU;
uniform sampler2D textureV;
void main() {
    vec3 yuv, rgb;
    vec3 yuv2r = vec3(1.164, 0.0, 1.596);
    vec3 yuv2g = vec3(1.164, -0.391, -0.813);
    vec3 yuv2b = vec3(1.164, 2.018, 0.0);

    yuv.x = texture(textureY, texCoord).r - 0.0625;
    yuv.y = texture(textureU, texCoord).r - 0.5;
    yuv.z = texture(textureV, texCoord).r - 0.5;

    rgb.x = dot(yuv, yuv2r);
    rgb.y = dot(yuv, yuv2g);
    rgb.z = dot(yuv, yuv2b);

    FragColor = vec4(rgb, 1.0);
}
FILE fp = fopen("nv21.raw", "rb");
unsigned char *yuvBuffer = new unsigned char[width*height*3/2];
fread(yuvBuffer, 1, width*height*3/2, fp);

unsigned char *vuBuffer = &yuvBuffer[width*height];

int bufSize = width*height/4;
unsigned char *uBuffer = new unsigned char[bufSize];
memset(uBuffer, 0, bufSize);
unsigned char *vBuffer = new unsigned char[bufSize];
memset(vBuffer, 0, bufSize);

unsigned char *uPtr, *vPtr;
uPtr = uBuffer;
vPtr = vBuffer;

for (int i = 0; i < bufSize; i++)
{
    *vPtr = *vuBuffer++;
    *uPtr = *vuBuffer++;
}

GLuint textureID[3];

glGenTextures(1, &textureID[0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureID[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, &yuvBuffer[0]);
glBindTexture(0);

glGenTextures(1, &textureID[1]);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textureID[1]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width/2, height/2, 0, GL_RED, GL_UNSIGNED_BYTE, uBuffer);
glBindTexture(0);

glGenTextures(1, &textureID[2]);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, textureID[2]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width/2, height/2, 0, GL_RED, GL_UNSIGNED_BYTE, vBuffer);
glBindTexture(0);