Luc*_*lla 7 c c++ gtk opengl-es
我正在尝试EGLImageKHR将从NVIDIA解码器获得的图像渲染到帧缓冲区,以便可以在屏幕上渲染此帧缓冲区。我编写了执行以下操作的代码:
创建两个纹理,frameBufferTexture和externalTexture。我们写EGLImage到externalTexture和借鉴,以frameBufferTexture从externalTexture。然后,我们读出frameBufferTexture用glReadPixels:
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);
Run Code Online (Sandbox Code Playgroud)
看到我正在使用glReadPixels来获取一部分帧缓冲区,以便我可以看到发生了什么。
这是我在输出中得到的:
0 0 0 255 0 0 0 255 0 0 0 255 ...
Run Code Online (Sandbox Code Playgroud)
我想这是glTexImage2D我经过的地方0。这意味着这glEGLImageTargetTexture2DOES并没有将我们的形象推向高潮externalTexture。
这是片段着色器:
#version 330 core
out vec4 FragColor;
in vec2 TexCoord;
uniform sampler2D tex;
void main()
{
FragColor = texture(tex, TexCoord);
}
Run Code Online (Sandbox Code Playgroud)
如果将此着色器更改为FragColor = vec4(1.0,texture(tex, TexCoord).r,0,1.0)以下输出:
255 0 0 255 255 0 0 255 255 0 0 255 ...
Run Code Online (Sandbox Code Playgroud)
这意味着着色器正在工作,并且正在写入帧缓冲区。如果我放
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);
Run Code Online (Sandbox Code Playgroud)
之后glBindTexture(GL_TEXTURE_2D, externalTexture);,我可以看到的内容d,这意味着我的片段着色器正在正确地从纹理写入数据externalTexture。
这把问题放在了glEGLImageTargetTexture2DOES。这不是用我的图像填充externalTexture!
为什么?
ps:我怀疑eglDisplay。为什么需要一个显示器来创建一个EGLImageKHR?我看过NVIDIA的代码,该代码使用NvEGLImageFromFd并通过X11窗口传递eglDisplay。但是我在GTK中,我不明白为什么egl显示很重要,首先是因为我要渲染到帧缓冲区,其次是因为要渲染图像时要渲染到GTK的帧缓冲区。
检查nvidia中的示例实现
tegra_multimedia_api\argus\samples\utils\PreviewConsumer.cpp
tegra_multimedia_api\samples\common\classes\NvEglRenderer.cpp
Run Code Online (Sandbox Code Playgroud)