0

我曾经在 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 个不同的向量(对我来说不是这种情况)。

这是链接:GLSL中的奇怪错误,同时将属性分配给顶点着色器的变化

4

1 回答 1

0

这看起来像您的属性位置 bings 无效,并且位置分配给 GL。没有赋值,index属性是不被使用的,只有position一个是,所以很有可能它得到位置0。index实际使用时,它可能得到0(在nvidia上,那些位置似乎是按字母顺序分配的) .

这些glBindAttribLocation()调用仅在链接程序时有效,因此必须在之前 glLinkProgram()调用这些调用,并且当您想要更改它们时必须重新链接程序(您应该真正避免)。您给出的代码表明这是在您的常规绘图调用期间调用的,因此这些对链接程序没有任何影响。

于 2014-06-29T16:02:54.703 回答