我试图在从一些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);
}
1 回答
使用着色器时,glEnable(GL_TEXTURE_ ...)无效 . 这是固定功能管道时代的遗物 . 另一方面,在绘制时必须实际绑定纹理 .
在您的代码中
现在因为这是在初始化代码中,不清楚你是否真正了解这些行的后果 . 所以让我们分解一下:
这意味着纹理0(其中着色器是nil纹理,但在旧的和破坏的OpenGL-1.0中它实际上可以是采样形式)是有素的纹理 unit 0.从那里,当尝试从纹理单元0采样时,它不会采样任何东西 .
将采样器设置为名称为“VOXELS”,以从纹理单元0进行采样 . 无论在调用绘制函数时哪个纹理单元绑定到该纹理单元,都将对该纹理进行采样 .
在你的程序的某个地方,你正在进行平局调用 . 你没告诉我们在哪里 . 但是为了使您的绘图实际从纹理中采样,您必须将3d纹理绑定到纹理单元0 .