c++ - 使用 GTK 将 EGL 图像渲染到帧缓冲区

标签 c++ c opengl-es gtk

我正在尝试将从 NVIDIA 解码器获得的 EGLImageKHR 渲染到帧缓冲区,以便我可以在屏幕上渲染该帧缓冲区。我写了一段代码来执行以下操作:

创建两个纹理,frameBufferTextureexternalTexture。我们将 EGLImage 写入 externalTexture 并从 externalTexture 绘制到 frameBufferTexture。然后我们使用 glReadPixelsframeBufferTexture 读取:

    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 ...

我猜它来自于我传递 0glTexImage2D 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 的内容,这意味着我的片段着色器正在正确地从纹理写入数据 外部纹理

这将问题置于 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

关于c++ - 使用 GTK 将 EGL 图像渲染到帧缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57999432/

相关文章:

c - 如何引用在静态库中声明的变量?

java - 管理大量 "objects"进行绘制。

c++ - 读入一个对象,该对象是另一个对象 C++ 的数据成员

c++ - 带 LGPL 的二维绘图库

c - 从另一个线程关闭套接字时,阻塞 recv 不会退出?

c - 保护应用程序免受错误的 Lua 脚本的影响

iphone - 在 OpenGL ES 2.0 中切换着色器是否会影响性能?

java - 尝试使用 OpenGL 时,由于 NumberFormatException, Activity 崩溃

c++ - 头文件中的函数原型(prototype)

c++ - Visual Studio 2015 认为 Windows 10 是 Windows XP 之前的版本