我正在尝试渲染从NVIDIA解码器获取的
创建两个纹理:
在
这将问题归结为
为什么? 提示: 我怀疑是
EGLImageKHR
,将其呈现到帧缓冲区中,以便我可以在屏幕上呈现此帧缓冲区。 我编写了以下代码:创建两个纹理:
frameBufferTexture
和externalTexture
。我们将EGLImage写入externalTexture
,并从externalTexture
绘制到frameBufferTexture
。然后,我们使用glReadPixels
从frameBufferTexture
中读取: glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glGenTextures(1, &externalTexture);
glGenTextures(1, &frameBufferTexture);
glBindTexture(GL_TEXTURE_2D, frameBufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, decodedNvFrame->width, decodedNvFrame->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glUniform1i(texLocation, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
glBindTexture(GL_TEXTURE_2D, frameBufferTexture);
EGLImageKHR hEglImage;
hEglImage = NvEGLImageFromFd(eglDisplay, decodedNvFrame->nvBuffer->planes[0].fd);
if (!hEglImage)
printf("Could not get EglImage from fd. Not rendering\n");
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, frameBufferTexture, 0);
glBindTexture(GL_TEXTURE_2D, externalTexture);
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, hEglImage);
glUniform1i(texLocation, 0);
glBindVertexArray(vertexArrayObject);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glReadBuffer(GL_COLOR_ATTACHMENT0);
GLenum frameBufferStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (frameBufferStatus!=GL_FRAMEBUFFER_COMPLETE) {
printf("frameBufferStatus problem!\n");
abort();
}
glReadPixels(0, 0, 512, 512, GL_RGBA, GL_UNSIGNED_BYTE, r);
for (int i = 0; i < 100; ++i)
{
printf("%i ", r[i]);
}
printf("\n");
NvDestroyEGLImage(eglDisplay, hEglImage);
注意我使用 glReadPixels 只获取帧缓冲区的一部分,以便查看正在发生的情况。
这是输出结果:
0 0 0 255 0 0 0 255 0 0 0 255 ...
我猜这个问题源于用 glTexImage2D
函数传递的参数中使用了0
。这意味着glEGLImageTargetTexture2DOES
没有将图像推送到 externalTexture
中。
下面是片段着色器的代码:
#version 330 core
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D tex;
void main()
{
FragColor = texture(tex, TexCoord);
}
如果我将这个着色器更改为 FragColor = vec4(1.0,texture(tex, TexCoord).r,0,1.0)
,那么输出结果如下:
255 0 0 255 255 0 0 255 255 0 0 255 ...
这意味着着色器正在工作并写入帧缓冲区。如果我添加
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_RGBA8, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, d);
在
glBindTexture(GL_TEXTURE_2D,externalTexture)
之后,我能看到d
的内容,这意味着我的片段着色器正确地从纹理externalTexture
中写入数据。这将问题归结为
glEGLImageTargetTexture2DOES
。它没有用我的图像填充externalTexture!为什么? 提示: 我怀疑是
eglDisplay
的问题。为什么我需要一个显示器来创建EGLImageKHR
?我看过 NVIDIA 的代码,他们使用NvEGLImageFromFd
并传递来自 X11 窗口的 eglDisplay。但我在 GTK 中,不明白为什么 egl 显示器很重要,首先因为我正在渲染到帧缓冲区,但其次,当我想要渲染图像时,我会渲染到 GTK 的帧缓冲区。
glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, ...);
是非法的。glEGLImageTargetTexture2DOES
仅能以GL_TEXTURE_EXTERNAL_OES
作为目标。 - Nicol Bolas