繁体   English   中英

无法创建/采样3D纹理(Qt / OpenGL)

[英]Cannot create/ sample 3D Texture (Qt/ OpenGL)

我试图在根据某些3D数据创建的3D纹理中显示图层,但是采样的所有点始终都是黑色的(我想我的纹理创建/分配由于某种原因失败了)。 使用窗口坐标将其渲染在平面上。 我检查了我的数据,它是带有正确值的向量。 glEnable(GL_TEXTURE_3D)之前已被调用。 有什么线索为什么会失败?

创建纹理的函数:

bool VolumeRender::setVolumeData(QOpenGLShaderProgram *program, vector<unsigned short> v, int x, int y, int z){
    voxels.resize(v.size(), 0);

    cout << "Processing texture" << endl;

    unsigned short sMax = 0;
    unsigned short sMin = 32768;

    for (unsigned int i =0; i< voxels.size(); i++){
        sMax = max(sMax, v[i]);
        sMin = min(sMin, v[i]);
    } for (unsigned int i =0; i< voxels.size(); i++) voxels[i] = (v[i] - sMin)/(float)(sMax-sMin);

    cout << "Loading 3D texture" << endl;

    gl.glActiveTexture(GL_TEXTURE0);
    gl.glGenTextures(1, &volumeTexture);
    gl.glBindTexture(GL_TEXTURE_3D, volumeTexture);

    gl.glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    gl.glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    gl.glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
    gl.glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
    gl.glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);

    gl.glTexImage3D(GL_TEXTURE_3D, 0, GL_RED, x, y, z, 0, GL_RED, GL_FLOAT, &voxels[0]);

    gl.glBindTexture(GL_TEXTURE_3D, 0);

    program->bind();
    program->setUniformValue("VOXELS", 0);
    program->release();

    voxelsLoaded = true;
    return true;
}

简单的片段着色器:

#version 330 core

uniform sampler3D VOXELS;
uniform vec2 SIZE;

out vec4 color;

void main(){
    vec2 coords = (gl_FragCoord.xy - 0.5) / SIZE;
    vec3 texcoords = vec3(coords, 0.5);
    color = texture(VOXELS, texcoords);
}

使用着色器时,glEnable(GL_TEXTURE_…)不起作用。 这是固定功能管道时代的遗物。 另一方面,在绘制时必须实际绑定纹理。

在您的代码中

gl.glBindTexture(GL_TEXTURE_3D, 0);

program->bind();
program->setUniformValue("VOXELS", 0);
program->release();

现在,由于这是初始化代码,因此尚不清楚您是否真正了解了这些行的结果。 因此,让我们分解一下:

gl.glBindTexture(GL_TEXTURE_3D, 0);

这意味着纹理0(使用着色器是nil纹理,但是在旧的和破烂的OpenGL-1.0中它实际上可以被采样)到纹理单元 0。从那里开始,当尝试从纹理单元0采样时,它不会采样任何东西。

program->bind();
program->setUniformValue("VOXELS", 0);
program->release();

将名称为“ VOXELS”的采样器设置为统一,以从纹理单元0进行采样。无论在调用绘图函数时绑定到该纹理单元的纹理是什么,都将从该纹理中采样。

在程序中的某个位置,您正在进行绘图调用。 您没有告诉我们在哪里。 但是,为了使图形实际从纹理中采样,必须将3d纹理绑定到纹理单元0。

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_3D, volumeTexture);
draw_stuff();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM