GLSL:我应该如何存储和跟踪统一/属性位置?

时间:2011-04-06 12:21:16

标签: c++ visual-studio-2008 opengl glsl

目前我只是这样做:

someuniform1 = glGetUniformLocation(MyShaderName, "someuniform1");
someattribute1 = glGetAttribLocation(MyShaderName, "someattribute1");

但是这个方法看起来很烦人,所以我想到了使用std :: map:

Shaders[MyShaderName].Uniforms["someuniform1"] = glGetUniformLocation(MyShaderName, "someuniform1");
Shaders[MyShaderName].Attributes["someattribute1"] = glGetAttribLocation(MyShaderName, "someattribute1");
// i could add a function to remove the repetition of the two strings at both sides.

有更聪明/更快的方法吗? (尽可能减少重复)。

-

编辑:我正在考虑更多关于这个想法,我想,如果我只是阅读glsl源文件,解析统一/属性并自动设置到我的地图,这不会很好我需要写除glsl源之外的其他内容!?这是大男孩们这样做的吗?

Edit2:我现在正在成功解析GLSL着色器文件,并使用std::map方法,我使用单个函数调用和一个字符串参数来获取制服/属性的地址当前启用的着色器。如果我需要更多性能,我会将std::map调用缓存到其他变量。但我想知道我是否在这里正确的轨道...所以请,任何评论赞赏。

2 个答案:

答案 0 :(得分:6)

GetActiveUniform枚举着色器程序的制服,然后将它们存储在地图中。

编辑:目的。

  1. 代码中没有重复。作为常量的统一名称仅出现在您要访问它们的位置。
  2. 早期语义不匹配检查。当您从GL收集有关制服的信息时,您确切知道它所期望的值类型。因此,当传递实际值时,您可以检查客户端是否提供了正确的值的类型/大小。当OpenGL驱动程序决定“智能”时,这些检查可以为您节省大量的调试时间。

答案 1 :(得分:1)

glGetProgramivglGetActiveUniformglGetActiveAttrib可用于获取有关着色器程序中使用过的制服的信息。在程序链接后,可以随时检索信息glLinkProgram

  • glGetProgramiv( MyShaderName, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxUniformNameLen )返回最长的长度 活动统一变量名称(包括空终止字符)

  • glGetProgramiv( MyShaderName, GL_ACTIVE_UNIFORMS, &noOfUniforms )返回活动统一变量的数量。

  • glGetActiveUniform返回有关包含制服名称的活动统一变量的信息。

  • glGetProgramiv( MyShaderName, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttribNameLen )返回最长的vetex属性名称的长度(包括空终止字符)

  • glGetProgramiv( MyShaderName, GL_ACTIVE_ATTRIBUTES, &noOfAttributes )返回活动属性的数量。

  • glGetActiveAttrib返回有关包含属性名称的有效vetrtex属性的信息。

使用上述函数中的信息查找程序中的所有统一名称和属性名称。根据每个制服的名称询问每个制服的位置和每个属性的索引。请参阅下面的代码段:

GLint maxUniformNameLen, noOfUniforms;
glGetProgramiv( MyShaderName, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformNameLen );
glGetProgramiv( MyShaderName, GL_ACTIVE_UNIFORMS, &noOfUniforms );

GLint maxAttribNameLen, noOfAttributes;
glGetProgramiv( MyShaderName, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxAttribNameLen );
glGetProgramiv( MyShaderName, GL_ACTIVE_ATTRIBUTES, &noOfAttributes );

GLint read, size;
GLenum type;

std::vector< GLchar >unifN( maxUniformNameLen, 0 );
for ( GLint i = 0; i < noOfUniforms; ++ i )
{
    glGetActiveUniform(Object(), i, maxUniformNameLen, &read, &size, &type, unifN.data());
    Shaders[ MyShaderName ].Uniforms[ unifN.data() ] =
        glGetUniformLocation( MyShaderName, unifN.data() );
}

std::vector< GLchar >attrN( maxAttribNameLen, 0 );
for ( GLint i = 0; i < noOfAttributes; ++ i )
{
    glGetActiveAttrib(Object(), i, maxAttribNameLen, &read, &size, &type, attrN.data());
    Shaders[ MyShaderName ].Attributes[ attrN.data() ] =
        glGetAttribLocation( MyShaderName, attrN.data() );
}