使用 GTK 将 EGL 图像渲染到帧缓冲区
Rendering an EGL Image to a frame buffer with GTK
我正在尝试将从 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 renderingn");
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);
看到我正在使用glReadPixel来获取帧缓冲区的一部分,以便我可以看到发生了什么。
这是我在输出中得到的:
0 0 0 255 0 0 0 255 0 0 0 255 ...
我猜它来自我经过0
的glTexImage2D
cal.这意味着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
.它没有用我的图像填充外部纹理!
为什么?
ps:我怀疑eglDisplay
.为什么需要显示器来创建EGLImageKHR
?我见过来自 NVIDIA 的代码,它使用NvEGLImageFromFd
并从 X11 窗口传递 eglDisplay。但是我在GTK中,我不明白为什么egl显示器很重要,首先因为我要渲染到帧缓冲区,其次是因为当我想要渲染图像时,我会渲染到GTK的帧缓冲区。
查看 nvidia 中的示例实现
tegra_multimedia_apiargussamplesutilsPreviewConsumer.cpp
tegra_multimedia_apisamplescommonclassesNvEglRenderer.cpp
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 将图像魔术 blob 保存到节点缓冲区
- 优化图像缓冲区
- 有没有办法将两个输入图像堆叠到卤化物发生器中的单个 4 维缓冲区中?
- 使用 GTK 将 EGL 图像渲染到帧缓冲区
- 用于视频处理的图像缓冲区
- 如何将图像缓冲区传递到OpenCV垫子对象
- QT 无法从缓冲区加载图像
- 尝试为图像缓冲区分配内存时 ptr 值错误
- 将图像缓冲区保存到Android上的文件
- 在 Python 中使用 OpenCV 将打包的 BGRA 图像缓冲区转换为 RGB 时遇到问题
- 在amd64体系结构上的C++中,将图像缓冲区blit到另一个缓冲区的xy偏移中的最快方法
- 在不使用缓冲区的情况下对2个图像进行操作(加法、减法等)
- 如何使用LEADTOOLS 19将图像效果应用于内存缓冲区中的JPEG
- GetDIBits 将图像缓冲区设置为所有 0(全黑)
- Vulkan:在多个命令缓冲区中排列图像内存屏障
- 使用图像对象时,它比使用缓冲区对象慢
- 如何将屏幕图像放入内存缓冲区
- turbojpeg-cpp中的realloc图像缓冲区
- 压缩原始图像缓冲区