使用texture()

时间:2015-07-09 16:59:38

标签: opengl glsl fragment-shader

我有以下片段着色器:

#version 330 core

layout (location = 0) out vec4 color;

uniform vec4 colour;
uniform vec2 light_pos;

in DATA
{
    vec4 position;
    vec2 texCoord;
    float tid;
    vec4 color;
} fs_in;

uniform sampler2D textures[32];

void main()
{
    float intensity = 1.0 / length(fs_in.position.xy - light_pos);

    vec4 texColor = fs_in.color;
    if (fs_in.tid > 0.0)
    {
        int tid = int(fs_in.tid + 0.5);
        texColor = texture(textures[tid], fs_in.texCoord);
    }

    color = texColor * intensity;
}

如果我运行我的程序,我得到opengl错误1282,这是无效的操作。如果我不使用texture(),那么我写texCoord = vec4(...)它完美无缺。我总是将tid(纹理ID)传递为0(没有纹理),因此该部分甚至不应该运行。我已经将纹理设置为一些占位符,但据我所知,这不应该是重要的。什么可能导致无效操作呢?

2 个答案:

答案 0 :(得分:3)

您的着色器编译很可能失败了。确保在尝试编译着色器后始终使用以下方法检查编译状态:

try<- function (data,var){
    for (i in 1:nrow(data)){
            if (var[i]== "1"){
                    var[i]<- "Good"
            } else {var[i]<- "Bad"}        
    }
    return (var)
}

在您的情况下,着色器是非法的,因为您正在尝试访问具有可变索引的采样器数组:

GLint val = GL_FALSE;
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &val);
if (val != GL_TRUE)
{
    // compilation failed
}

GLSL 3.30不支持此功能。从规范(强调添加):

  

在着色器中聚合到数组中的采样器(使用方括号[])只能使用整数常量表达式进行索引(请参见第4.3.3节“常量表达式”)。

此限制在以后的OpenGL版本中放宽了。例如,来自GLSL 4.50规范:

  

当在着色器中聚合到数组中时,只能使用动态统一的整数表达式对采样器编制索引,否则结果将是未定义的。

此更改已在GLSL 4.00中引入。但是对于你的情况来说仍然不够,因为你正在尝试使用texColor = texture(textures[tid], fs_in.texCoord); 变量作为索引,这不是动态统一的。

如果您的纹理大小相同,您可能需要考虑使用数组纹理。这样您就可以根据动态计算的索引对数组纹理中的一个图层进行采样。

答案 1 :(得分:0)

我知道这个解决方案已经晚了,但如果它对任何人都有帮助..

根据Cherno的视频,这应该有效。然而,他使用属性&#39; fs_in.tid&#39;作为&#39; GL_BYTE&#39;在纹理索引的gl_VertexAttribPointer中,由于某些原因,关于转换1.0f总是被转换为0.0f因此不起作用。 将GL_BYTE更改为GL_FLOAT为我解决了这个问题。

关于&#39; opengl错误1282&#39;,这是我遇到的一个非常常见的错误。我曾经忘记在设置任何制服之前调用glUseProgram(ShaderID)。因此,即使当时没有使用/设置制服也会导致错误,即“1282”。这可能是解决方案之一,这为我解决了。