简体   繁体   English

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

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

I am trying to display a layer in a 3D texture created from some 3D data, but all points sampled are always black (I guess my texture creation/ allocation is failing somehow). 我试图在根据某些3D数据创建的3D纹理中显示图层,但是采样的所有点始终都是黑色的(我想我的纹理创建/分配由于某种原因失败了)。 It is being rendered on a plane using window coords. 使用窗口坐标将其渲染在平面上。 I have checked my data, it is a vector with the correct values. 我检查了我的数据,它是带有正确值的向量。 glEnable(GL_TEXTURE_3D) has been called earlier. glEnable(GL_TEXTURE_3D)之前已被调用。 Any clues why this would fail? 有什么线索为什么会失败?

Function that creates the texture: 创建纹理的函数:

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;
}

Simple fragment shader: 简单的片段着色器:

#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_…) has no effect when using shaders. 使用着色器时,glEnable(GL_TEXTURE_…)不起作用。 It's a relic from the fixed function pipeline era. 这是固定功能管道时代的遗物。 On the other hand the texture must be actually bound when drawing. 另一方面,在绘制时必须实际绑定纹理。

In your code you have 在您的代码中

gl.glBindTexture(GL_TEXTURE_3D, 0);

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

Now since this is in initialization code, it's unclear if you actually understand the consequences of these lines. 现在,由于这是初始化代码,因此尚不清楚您是否真正了解了这些行的结果。 So let's break it down: 因此,让我们分解一下:

gl.glBindTexture(GL_TEXTURE_3D, 0);

This means that texture 0 (which with shaders is the nil texture, but in old and busted OpenGL-1.0 it actually could be sampled form) is bount to texture unit 0. From there on, when trying to sample from texture unit 0, it will not sample anything. 这意味着纹理0(使用着色器是nil纹理,但是在旧的和破烂的OpenGL-1.0中它实际上可以被采样)到纹理单元 0。从那里开始,当尝试从纹理单元0采样时,它不会采样任何东西。

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

Set the sampler uniform with name "VOXELS" to sample from texture unit 0. Whatever texture is bound to that texture unit at the moment of calling the draw function, that texture will be sampled from. 将名称为“ VOXELS”的采样器设置为统一,以从纹理单元0进行采样。无论在调用绘图函数时绑定到该纹理单元的纹理是什么,都将从该纹理中采样。

Somewhere in your program you're making a draw call. 在程序中的某个位置,您正在进行绘图调用。 You didn't show us where. 您没有告诉我们在哪里。 But in order for your drawing to actually sample from your texture you have to bind your 3d texture to texture unit 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