1

したがって、フラグメントシェーダーにカスタム構造と、これらの構造の配列である均一変数があります。次のように定義されます。

#version 130
#define MAX_LIGHTS 8

struct Light {
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    vec4 position;
    vec3 direction;
    float cutoff;
    float exponent;
};

uniform Light lights[MAX_LIGHTS];

今、私はこのような均一な場所を取得しようとしています:

glGetUniformLocation(program, "lights[0].ambient");
glGetUniformLocation(program, "lights[0].diffuse");
// etc...

GTX460 ではすべて正常に動作しglGetUniformLocationますが、Mobility Radeon HD 5650 では、シェーダーが正常にコンパイル/リンクしているにもかかわらず、-1 が返されます。(これは OpenGL 3.1 コンテキストです。)

私は何を間違っていますか?

編集:さて、ここに完全なシェーダーがあります(私はそれを書きませんでした、私は友人のプログラムを修正しようとしています)。さらに、インテル HD 統合グラフィックス アダプターでこれをテストしたところ、問題なく動作しました。

4

1 に答える 1

11

-1glGetUniformLocation (...)が返される原因を突き止めようとして盲目的に手探りすることがよくあるので、GLSL プログラムごとにすべてのユニフォームを列挙するために使用する修正済みコードを共有することにしました。私は実際にマップ構造を使用して列挙型を文字列名に変換しますが、それは必要以上に複雑になります。

人間が読める型を出力するためのユーティリティ構造 (GLSL 430 まで):

struct glsl_type_set {
  GLenum      type;
  const char* name;
}
type_set [] = {
  GL_INVALID_ENUM,                              "invalid",
  GL_FLOAT,                                     "float",
  GL_FLOAT_VEC2,                                "vec2",
  GL_FLOAT_VEC3,                                "vec3",
  GL_FLOAT_VEC4,                                "vec4",
  GL_DOUBLE,                                    "double",
  GL_DOUBLE_VEC2,                               "dvec2",
  GL_DOUBLE_VEC3,                               "dvec3",
  GL_DOUBLE_VEC4,                               "dvec4",
  GL_INT,                                       "int",
  GL_INT_VEC2,                                  "ivec2",
  GL_INT_VEC3,                                  "ivec3",
  GL_INT_VEC4,                                  "ivec4",
  GL_UNSIGNED_INT,                              "unsigned int",
  GL_UNSIGNED_INT_VEC2,                         "uvec2",
  GL_UNSIGNED_INT_VEC3,                         "uvec3",
  GL_UNSIGNED_INT_VEC4,                         "uvec4",
  GL_BOOL,                                      "bool",
  GL_BOOL_VEC2,                                 "bvec2",
  GL_BOOL_VEC3,                                 "bvec3",
  GL_BOOL_VEC4,                                 "bvec4",
  GL_FLOAT_MAT2,                                "mat2",
  GL_FLOAT_MAT3,                                "mat3",
  GL_FLOAT_MAT4,                                "mat4",
  GL_FLOAT_MAT2x3,                              "mat2x3",
  GL_FLOAT_MAT2x4,                              "mat2x4",
  GL_FLOAT_MAT3x2,                              "mat3x2",
  GL_FLOAT_MAT3x4,                              "mat3x4",
  GL_FLOAT_MAT4x2,                              "mat4x2",
  GL_FLOAT_MAT4x3,                              "mat4x3",
  GL_DOUBLE_MAT2,                               "dmat2",
  GL_DOUBLE_MAT3,                               "dmat3",
  GL_DOUBLE_MAT4,                               "dmat4",
  GL_DOUBLE_MAT2x3,                             "dmat2x3",
  GL_DOUBLE_MAT2x4,                             "dmat2x4",
  GL_DOUBLE_MAT3x2,                             "dmat3x2",
  GL_DOUBLE_MAT3x4,                             "dmat3x4",
  GL_DOUBLE_MAT4x2,                             "dmat4x2",
  GL_DOUBLE_MAT4x3,                             "dmat4x3",
  GL_SAMPLER_1D,                                "sampler1D",
  GL_SAMPLER_2D,                                "sampler2D",
  GL_SAMPLER_3D,                                "sampler3D",
  GL_SAMPLER_CUBE,                              "samplerCube",
  GL_SAMPLER_1D_SHADOW,                         "sampler1DShadow",
  GL_SAMPLER_2D_SHADOW,                         "sampler2DShadow",
  GL_SAMPLER_1D_ARRAY,                          "sampler1DArray",
  GL_SAMPLER_2D_ARRAY,                          "sampler2DArray",
  GL_SAMPLER_1D_ARRAY_SHADOW,                   "sampler1DArrayShadow",
  GL_SAMPLER_2D_ARRAY_SHADOW,                   "sampler2DArrayShadow",
  GL_SAMPLER_2D_MULTISAMPLE,                    "sampler2DMS",
  GL_SAMPLER_2D_MULTISAMPLE_ARRAY,              "sampler2DMSArray",
  GL_SAMPLER_CUBE_SHADOW,                       "samplerCubeShadow",
  GL_SAMPLER_BUFFER,                            "samplerBuffer",
  GL_SAMPLER_2D_RECT,                           "sampler2DRect",
  GL_SAMPLER_2D_RECT_SHADOW,                    "sampler2DRectShadow",
  GL_INT_SAMPLER_1D,                            "isampler1D",
  GL_INT_SAMPLER_2D,                            "isampler2D",
  GL_INT_SAMPLER_3D,                            "isampler3D",
  GL_INT_SAMPLER_CUBE,                          "isamplerCube",
  GL_INT_SAMPLER_1D_ARRAY,                      "isampler1DArray",
  GL_INT_SAMPLER_2D_ARRAY,                      "isampler2DArray",
  GL_INT_SAMPLER_2D_MULTISAMPLE,                "isampler2DMS",
  GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,          "isampler2DMSArray",
  GL_INT_SAMPLER_BUFFER,                        "isamplerBuffer",
  GL_INT_SAMPLER_2D_RECT,                       "isampler2DRect",
  GL_UNSIGNED_INT_SAMPLER_1D,                   "usampler1D",
  GL_UNSIGNED_INT_SAMPLER_2D,                   "usampler2D",
  GL_UNSIGNED_INT_SAMPLER_3D,                   "usampler3D",
  GL_UNSIGNED_INT_SAMPLER_CUBE,                 "usamplerCube",
  GL_UNSIGNED_INT_SAMPLER_1D_ARRAY,             "usampler2DArray",
  GL_UNSIGNED_INT_SAMPLER_2D_ARRAY,             "usampler2DArray",
  GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE,       "usampler2DMS",
  GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY, "usampler2DMSArray",
  GL_UNSIGNED_INT_SAMPLER_BUFFER,               "usamplerBuffer",
  GL_UNSIGNED_INT_SAMPLER_2D_RECT,              "usampler2DRect",
  GL_IMAGE_1D,                                  "image1D",
  GL_IMAGE_2D,                                  "image2D",
  GL_IMAGE_3D,                                  "image3D",
  GL_IMAGE_2D_RECT,                             "image2DRect",
  GL_IMAGE_CUBE,                                "imageCube",
  GL_IMAGE_BUFFER,                              "imageBuffer",
  GL_IMAGE_1D_ARRAY,                            "image1DArray",
  GL_IMAGE_2D_ARRAY,                            "image2DArray",
  GL_IMAGE_2D_MULTISAMPLE,                      "image2DMS",
  GL_IMAGE_2D_MULTISAMPLE_ARRAY,                "image2DMSArray",
  GL_INT_IMAGE_1D,                              "iimage1D",
  GL_INT_IMAGE_2D,                              "iimage2D",
  GL_INT_IMAGE_3D,                              "iimage3D",
  GL_INT_IMAGE_2D_RECT,                         "iimage2DRect",
  GL_INT_IMAGE_CUBE,                            "iimageCube",
  GL_INT_IMAGE_BUFFER,                          "iimageBuffer",
  GL_INT_IMAGE_1D_ARRAY,                        "iimage1DArray",
  GL_INT_IMAGE_2D_ARRAY,                        "iimage2DArray",
  GL_INT_IMAGE_2D_MULTISAMPLE,                  "iimage2DMS",
  GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY,            "iimage2DMSArray",
  GL_UNSIGNED_INT_IMAGE_1D,                     "uimage1D",
  GL_UNSIGNED_INT_IMAGE_2D,                     "uimage2D",
  GL_UNSIGNED_INT_IMAGE_3D,                     "uimage3D",
  GL_UNSIGNED_INT_IMAGE_2D_RECT,                "uimage2DRect",
  GL_UNSIGNED_INT_IMAGE_CUBE,                   "uimageCube",
  GL_UNSIGNED_INT_IMAGE_BUFFER,                 "uimageBuffer",
  GL_UNSIGNED_INT_IMAGE_1D_ARRAY,               "uimage1DArray",
  GL_UNSIGNED_INT_IMAGE_2D_ARRAY,               "uimage2DArray",
  GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE,         "uimage2DMS",
  GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY,   "uimage2DMSArray",
  GL_UNSIGNED_INT_ATOMIC_COUNTER,               "atomic_uint"
};

プログラム内のすべてのACTIVEユニフォームを列挙するコード:

void
eTB_GLSL__print_uniforms (GLuint program)
{
  GLint uniform_count;
  glGetProgramiv (program, GL_ACTIVE_UNIFORMS, &uniform_count);

  GLchar name [256];

  for (GLint i = 0; i < uniform_count; i++) {
    memset (name, '\0', 256);
    GLint  size;
    GLenum type;

    glGetActiveUniform (program, i, 255, NULL, &size, &type, name);

    GLint location = glGetUniformLocation (program, name);

    for (int j = 0; j < sizeof (type_set) / sizeof (glsl_type_set); j++) {
      if (type_set [j].type != type)
        continue;

      const char* type_name = type_set [j].name;

      if (size > 1)
        printf ( "Uniform %d (loc=%d):\t%20s %-20s <Size: %d>\n",
                   i, location, type_name, name, size );
      else
        printf ( "Uniform %d (loc=%d):\t%20s %-20s\n",
                   i, location, type_name, name );

      break;
    }

    if (i == (uniform_count - 1))
      printf ("\n");
  }
}

サンプル出力 (AMD):

Uniform 0 (loc=0):                         float buffer_res_x        
Uniform 1 (loc=1):                         float buffer_res_y        
Uniform 2 (loc=2):                         float buffer_scale        
Uniform 3 (loc=3):                          mat4 camera_matrix       
Uniform 4 (loc=4):                          bool fxaa                
Uniform 5 (loc=5):                          vec3 light_colors         <Size: 128>
Uniform 6 (loc=133):                        vec3 light_pos            <Size: 128>
Uniform 7 (loc=261):                        mat4 modelview_mat       
Uniform 8 (loc=262):                         int num_lights          
Uniform 9 (loc=263):                   sampler2D depth_buffer        
Uniform 10 (loc=264):                  sampler2D diffuse_buffer      
Uniform 11 (loc=265):                  sampler2D normal_buffer       
Uniform 12 (loc=266):                samplerCube shadow_buffer        <Size: 10>

サンプル出力 (NV):

Uniform 0 (loc=0):                         float buffer_res_x        
Uniform 1 (loc=1):                         float buffer_res_y        
Uniform 2 (loc=2):                         float buffer_scale        
Uniform 3 (loc=3):                          mat4 camera_matrix       
Uniform 4 (loc=4):                          bool fxaa                
Uniform 5 (loc=5):                          vec3 light_colors[0]      <Size: 128>
Uniform 6 (loc=133):                        vec3 light_pos[0]         <Size: 128>
Uniform 7 (loc=261):                        mat4 modelview_mat       
Uniform 8 (loc=262):                         int num_lights          
Uniform 9 (loc=263):                   sampler2D depth_buffer        
Uniform 10 (loc=264):                  sampler2D diffuse_buffer      
Uniform 11 (loc=265):                  sampler2D normal_buffer       
Uniform 12 (loc=266):                samplerCube shadow_buffer[0]     <Size: 10>

私がこの特定のシェーダーを選択したのは、配列の統一名を報告するときに NV と AMD がどのように異なるかを示す最初のシェーダーであり、特に特別なことは何もないためです。NV は常に[0]表記を使用し、AMD は使用しません (ただし、新しいドライバーは使用する傾向があります)。<Size: X> で示される範囲内であれば、個々の均一な位置を照会できます。つまり、ドライバーはそれらをname[0]またはとして列挙しますが、いずれかの実装でまたはnameの均一な場所を照会することは技術的に有効です。namename[0]

私は次の3つのことを見ることに非常に興味があります。

  1. AMD ハードウェアにリンクした後の出力
  2. NV ハードウェアにリンクした後の出力
  3. あなたのフルシェーダー

この3つがあれば、実際の答えが可能になるはずです。

アップデート

シェーダーの記述方法が原因で、GLSL コンパイラーが使用法を判断するのに苦労していると思います。これを確認するには、以下を置き換えてみてください。

vec3 computeLight(int light_index){
  Light light = lights[light_index];
  if(light.position == vec4(0.0)) { return vec3(0.0);}
  if(light.position.w == 0.0 ) {return directionLight(light);}
  if(light.cutoff == 0) {return pointLight(light);}
  return reflectionLight(light);
}

[...]

vec3 lighting = vec3(0.);
  for(int i = 0; i < lights_no; i++) {
    lighting += computeLight(i);
}

次のようなもっと醜いものを使用します。

vec3 lighting = vec3(0.0);
  for(int i = 0; i < lights_no; i++) {
    Light light = lights [i];
    if (light.position != vec4 (0.0)) {
      if (light.position.w == 0.0)
        lighting += directionLight(light);
      else if (light.cutoff == 0.0)
        lighting += pointLight(light);
      else
        lighting += reflectionLight (light);
    }
  }
}
于 2013-11-12T00:17:01.580 に答える