17

好吧,所以这些纹理真的让我很困惑。我一直在看这个教程(我认为它很棒),特别是标题为“您可以定义多达 32 个纹理单元,但每个着色器最多只能定义 8 个纹理。”的图像。据我了解,它是这样工作的:

你激活一个纹理单元。然后,您将纹理对象(类似于图像中的“纹理数据”立方体)绑定到该单元内的某个目标。因此,glGenTextures 制作对象并获取它们的名称,然后 glBindTexture 将该纹理绑定到 TEXTURE_2D 或其他东西(我目前对其他目标不感兴趣)。然后您可以使用 glTexImage2D 指定纹理数据。

现在。我正在使用 3 个着色器程序,每个程序都需要不同的纹理。这是我想要做的:

在初始化阶段,我遍历每个纹理单元,然后

  • glActiveTexture
  • glBindTexture(在活动纹理单元上操作)
  • glTexImage2D(对当前绑定的对象进行操作)

对于着色器,我使用 glUniform 将每个着色器中的制服与 glActiveTexture 的 GL_TEXTUREi 中指定的“i”值匹配。我总共只需要四个纹理,而且它们非常小。

现在,在渲染过程中,我应该可以正常切换程序,一切正常,对吧?每个程序已经有一个统一的指定使用哪个单元,每个单元已经有一个对象绑定到它的 TEXTURE_2D 目标,每个对象都有 glTexImage2D 指定的数据,对吧?所以我的渲染函数中不需要绑定或激活单元?至少我是这么理解的,但是我在错误的地方绘制了错误的纹理。

此外,在我的一个程序中,我想在单个表面的三个纹理之间切换。所以我想我将每个纹理加载到一个对象中,并将每个对象绑定到一个单元,然后在渲染时我可以只 glUniform 告诉程序使用哪个纹理单元。

所以我想知道我是否误解了OpenGL中纹理的基本结构,或者对象与单元的绑定是否在程序切换时过期,或者类似的东西。或者我是否必须多次绑定纹理——但是何时,为什么?

4

1 回答 1

11

不要忘记为每个纹理对象设置 glTexParameteri。

void loadTextures() {
    GLint texture_object_handles[3];
    glGenTextures(3, texture_object_handles);

    for (int i = 0 ; i < 3 ; ++i) {
        glActiveTexture(GL_TEXTURE0 + i);
        glBindTexture(GL_TEXTURE_2D, texture_object_handles[i]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexImage2D(GL_TEXTURE_2D, ...);
    }
    return;
}


void draw() {
    // Draw three different materials without rebinding any textures.
    for (i = 0 ; i < 3 : ++i) {
        ... specify other uniforms and attributes
        glUniform1i(texture_location, i);
        ... 
        glDrawElements(...);
    }
    return;
}    
于 2012-11-20T22:48:03.900 回答