在顶点数组中为每个多边形进行纹理映射 - OpenGL

5

我尝试让我的渲染函数工作。我正在使用顶点数组。这是我的顶点结构:

struct Vertex 
{
    float x, y, z;              // The x, y and z floating point values     
    float u, v;                 // The u - v texture coordinates
    float padding[3];   // needs to be multiple of 32
};

这是我的渲染代码:
// Render the mesh
void WLD::render(GLuint* textures, long curRegion, CFrustum cfrustum)
{

    int num = 0;

    // Set up my indices
    GLuint indicies[3];

    // Cycle through the PVS
    while(num < regions[curRegion].visibility.size())
    {
        int i = regions[curRegion].visibility[num];

        if(!regions[i].dead && regions[i].meshptr != NULL)
        {
            if(cfrustum.BoxInFrustum(regions[i].meshptr->min[0], regions[i].meshptr->min[2], regions[i].meshptr->min[1], regions[i].meshptr->max[0], regions[i].meshptr->max[2], regions[i].meshptr->max[1]))
            {
                // Cycle through every polygon in the mesh and render it
                for(int j = 0; j < regions[i].meshptr->polygonCount; j++)
                {   
                    // Assign the index for the polygon to the index in the huge vertex array
                    indicies[0] = regions[i].meshptr->poly[j].vertIndex[0];
                    indicies[1] = regions[i].meshptr->poly[j].vertIndex[1];
                    indicies[2] = regions[i].meshptr->poly[j].vertIndex[2];

                    glEnableClientState(GL_VERTEX_ARRAY);
                    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &verticies[0].x);

                    // Texture index
                    int tex = regions[i].meshptr->poly[j].tex;
                    // Need to bind this to the polygon I render.

                    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
                    glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &verticies[0].u);
                    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, indicies);

                    glDisableClientState(GL_VERTEX_ARRAY);
                    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
                }
            }
        }
    num++;
    }
}

其中一个参数GLuint * textures包含所有加载的纹理。因此,行int tex = regions [i] .meshptr->poly [j] .tex返回的值是此特定多边形的纹理在纹理中的索引。当我渲染它时,如何将其绑定到每个多边形?如果您有任何问题,请告诉我。

我知道我需要使用glClientActiveTexture(),但是一方面,它说未定义,我找不到正确的头文件;另一方面,我不知道如何使用它。我找不到任何好的例子。那么,如果多边形引用纹理索引4,我该如何使用glClientActiveTexture将其绑定到多边形并进行渲染。


也许一个解决方案是创建一个纹理集。唯一的问题是要获取正确的纹理坐标,但可以通过类和XML在客户端完成。然后你就不必担心切换纹理了。 - user406009
你正在错误地使用顶点数组。顶点数组的理念是,你将大量三角形批处理到单个glDrawElements调用中,而不是为每个三角形切换顶点数组指针,并且只有一个三角形被glDrawElements调用。此外,没有要求将顶点结构填充到32的倍数(什么意思?)。 - datenwolf
@datenwolf但在他的情况下,这似乎是必要的,因为他希望每个多边形都有不同的纹理(虽然还有其他方法可以实现这一点)。 - Christian Rau
@Christian Rau:他可以使用纹理数组来实现这个 http://www.opengl.org/wiki/Array_Texture ,但我同意纹理图集可能是一个明智的解决方案。 - datenwolf
@Moniker:如果您坚持使用原始方法,请先按纹理对三角形进行排序,以便在渲染过程中尽可能少地交换纹理。这一点始终如一地是个好主意(tm)。 - Macke
2个回答

4
您所尝试的操作通常是不可能的。通常情况下,您不会尝试使用多个纹理来渲染单个三角形流(即glDraw*调用)。无论如何,同一次绘制调用中的每个三角形都必须从相同的纹理集中获取数据。
一般的解决方案是将图像合并成一个纹理。这通常称为“纹理地图”。在这种情况下,顶点上的纹理坐标描述了从纹理地图(它是一个单独的纹理)中拉取图像数据的位置。
如果您正在使用GL 4.0兼容硬件(D3D11)和GLSL,则可以通过一些技巧根据任意计算动态选择16个纹理之间进行切换。对于早期的硬件,您可以使用着色器来选择纹理。但两种情况都比正确处理数据要慢。

那么我的计划是什么?当我渲染每个区域时,使用匹配纹理索引的多边形组进行渲染。你会如何建议实现它? - Moniker Grantis
@Moniker: 推荐做什么?你还没有说你实际渲染的是什么。你只是说你有一些三角形,并且想要将一些纹理与它们关联。这是一个粒子系统吗?这是某种类型的瓷砖地图吗?这是你从模型导出的网格吗?你要渲染什么? - Nicol Bolas
这是一个来自旧游戏的区域。它有各种与网格相连的区域。这些网格包含x个多边形和y个顶点。我有一个PVS,即潜在可见部分,因此如果我站在第3个区域,它会生成一个我可以从当前位置看到的区域列表。然后,我通过视锥体对这些潜在可见区域进行排序以确定哪些是可见的。这些区域包含指向巨大顶点列表中顶点的多边形。每个多边形也有一个索引指向纹理列表中的纹理。例如,多边形6具有区域5的索引... - Moniker Grantis
该内容涉及到顶点1234、1263和1253的引用,还有一个纹理引用。因此,我想要渲染特定区域内的所有多边形。问题是每个多边形都有一个关联的纹理。有什么想法吗?我可以画一个UML图,并愿意为在这方面提供任何帮助支付费用。认真地...愿意为此付钱。谢谢。 - Moniker Grantis
@Nicol 但是使用他目前的代码,这绝对是可能的,尽管不是最快/最聪明的方法。 - Christian Rau
我处于相似的情况下(尽管我在生成区域列表方面有点迷失)。我正在渲染一个高度图(即地形),其中“区域”基于您的位置可见,基本上是一个平铺地形,每个“瓦片”在您离它一定距离时被渲染。现在我正在自责,因为这种渲染方法只允许我在每次绘制中应用一种纹理,正如其他人在此帖子中提到的那样。看起来我必须重构瓦片渲染部分以选择具有不同纹理的顶点组。 - eggmatters

1

您可以使用当前的方法来完成此操作。您不需要使用glClientActiveTexture函数。该函数用于多重纹理,我想每个多边形只应用了一个纹理。因此,只需使用glBindTexture(GL_TEXTURE_2D, textures[tex])绑定所需的纹理,并在绘制多边形之前不要忘记启用glEnable(GL_TEXTURE_2D)(如果不使用着色器)。

但是,尽管它可以工作,这显然不是最好的方法。顶点数组可用于一次渲染多个基元(三角形),而您误用它们来渲染单个三角形。第一个和最简单的想法是至少按纹理索引对多边形进行排序,然后在一次调用glDrawElements中呈现所有具有相同纹理的三角形。请查看Nicol的答案以获取更高级的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接