正确使用 QT 包装器上传 3D 纹理

Posted

技术标签:

【中文标题】正确使用 QT 包装器上传 3D 纹理【英文标题】:Properly using QT wrappers to upload 3D texture 【发布时间】:2017-01-18 17:08:20 【问题描述】:

我正在尝试使用 QT 包装器从 OpenCV 3D 矩阵上传纹理。

这是我的代码(包括测试):

 unsigned char * buffer = new unsigned char[m_vol_data.total()];
    for (int i = 0; i < m_vol_data.size[0]; i ++)
        for (int j = 0; j < m_vol_data.size[1]; j ++)
            for (int k= 0; k < m_vol_data.size[2]; k ++)
            
                buffer[i + m_vol_data.size[0] * (j + m_vol_data.size[2] * k)] = m_vol_data.at<uint8_t>(i, j, k);
//                      printf("%d, %d \n", m_vol_data.at<uint8_t>(i, j, k),buffer[i + m_vol_data.size[0] * (j + m_vol_data.size[2] * k)]);
            

    m_texture = new QOpenGLTexture(QOpenGLTexture::Target3D);
    m_texture->setSize(m_vol_data.size[0], m_vol_data.size[1], m_vol_data.size[2]);
    m_texture->allocateStorage(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8);
    m_texture->setData(QOpenGLTexture::Luminance, QOpenGLTexture::UInt8, buffer);
    m_vol_uploaded = true;

    unsigned char * check = new unsigned char[m_vol_data.total()];
    glGetTexImage(GL_TEXTURE_3D, 0, GL_RED, GL_UNSIGNED_BYTE, check);
    for (int i = 0; i < 100; i++)
        printf("%d\n", check[i]);
    std::cout << m_vol_data.total() << std::endl;

第一个(注释)打印显示了我的预期,所有值都是 255(虚拟测试)。但是,我的立方体在屏幕上显示为全黑。第二个打印显示了意外的值,范围从 0 到 255。

这些是着色器:

  m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, "#version 410 core\n"
                                                            "in vec4 vPosition;\n"
                                                            "uniform mat4 pMatrix;\n"
                                                            "uniform mat4 mvMatrix;\n"
                                                            "smooth out vec3 uv;\n"
                                                            "void main() \n"
                                                            "   gl_Position = pMatrix * mvMatrix * vPosition;\n"
                                                            "   uv = (vPosition.xyz + vec3(1.0, 1.0, 1.0))/2.0;\n"
                                                            "");
  m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, "#version 410 core\n"
                                                              "in vec3 uv;\n"
                                                              "uniform sampler3D tex;\n"
                                                              "out vec4 fragColor;\n"
                                                              "void main()\n"
                                                              "  vec3 color = texture(tex, uv).rrr;\n"
                                                              "  fragColor.rgb = color;\n"
                                                              ";");

我试图找出问题所在,但没有成功。任何线索将不胜感激。谢谢。

【问题讨论】:

【参考方案1】:

您创建并填充了QOpenGLTexture 对象,但是除非您将其绑定到准备好渲染的单元,否则 OpenGL 管道实际上不会开始使用该对象。您应该将其命名为 m_texture-&gt;bind()m_texture-&gt;bind(uint unit),具体取决于您的可渲染对象。

第二次打印输出垃圾值,因为以下行尝试从空纹理读取到大小为m_vol_data.total()unsigned char 数组。

glGetTexImage(GL_TEXTURE_3D, 0, GL_RED, GL_UNSIGNED_BYTE, check);

有关该课程的更多文档是here。

【讨论】:

以上是关于正确使用 QT 包装器上传 3D 纹理的主要内容,如果未能解决你的问题,请参考以下文章

LibGDX 3d 模型纹理未正确渲染

QT和OpenGL如何正确集成并显示纹理

NamedPipeServerStream/NamedPipeClientStream 包装器

使用fabric js canvas作为threejs 3d模型纹理

FBO 的延迟着色器纹理显示为黑色

OpenGL 包装器中的 Alpha/纹理问题