我曾经在 OpenGL 版本 3.2 中做过一个项目,我使用“sampler2DArray”来存储多个具有相同尺寸的图像并使用纹理点渲染它们。
现在我正在尝试将该项目移植到我的 gnu/linux 计算机上。此计算机仅支持最高 2.1 的 OpenGL 版本和最高 1.20 的 GLSL 版本(没有 sampler2DArray)。据我所知,没有办法更新 OpenGL 以支持更新的功能。
我目前正在尝试做的是使用 sampler3D 来存储我的图像并使用深度值来选择我想要的图像。
为了将纹理深度从顶点着色器发送到片段着色器,我声明了一个“可变”浮点变量来保存深度值(0.0 到 1.0)。
我在以下位置渲染 4 张图像:(-0.5, +0.5)、(+0.5, +0.5)、(-0.5, -0.5) 和 (+0.5, -0.5)。
图像切换方法似乎正在工作(更改“索引”变量会更改图像)。但是由于某些奇怪的原因,所有图像都在 (0.0, 0.0) 处渲染,而不是在它们指定的位置处。当我没有分配给包含纹理深度值的变量并在片段着色器中将深度值设置为 0.0 时,这个问题就消失了。
这是顶点着色器:
#version 120
attribute vec2 position
attribute float index
varying float v_index
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
v_index = index; // Removing this assignment makes the images appear at their assigned locations.
}
这是片段着色器:
#version 120
uniform sampler3D texture;
varying float v_index;
void main()
{
gl_FragColor = texture3D(texture, vec3(gl_PointCoord, v_index));
}
我使用的结构表示顶点:
struct vertex {
GLfloat x;
GLfloat y;
GLfloat texture_index;
};
对glVertexAttribPointer
函数的调用(问题也可能在这里):
glBindAttribLocation(shader_program, 0, "position");
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (void *)0);
glBindAttribLocation(shader_program, 1, "index");
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, sizeof(struct vertex), (void *)(2 * sizeof(GLfloat));
我也发现了一个非常相似的问题。标记为“已接受”的答案声称问题的原因是着色器有超过 16 个不同的向量(对我来说不是这种情况)。