顶点和纹理坐标的索引缓冲区对象

时间:2014-05-03 01:53:49

标签: c# object opengl indexing buffer

好吧,所以我遇到了一个似乎大多数人都有的问题,但是他们的解释要么是,你不能这样做,要么计算机太过模糊,无法理解它正在使用索引作为顶点和另一个纹理。我听说过你应该放置一个顶点结构,它有一个位置,一个纹理坐标和一个法线。但是,如果我对从obj文件导入的对象进行UV映射,则无效。因此,对于相同的顶点将存在一些索引,但是对于纹理坐标具有不同的索引。那么我怎么能告诉opengl如何抓取多个索引,并使用一个用于顶点,一个用于纹理坐标,一个用于颜色(颜色很简单,它们都是一样的,但我仍然需要指定opengl需要使用它吗?

我现在拥有的只是顶点数组索引。

private void InitiateBeforeDraw()
{
    // Vertex Buffer
    Gl.glGenBuffers(1, out VertexId);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, VertexId);
    Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(Vertices.Length), Vertices, Gl.GL_STATIC_DRAW);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);

    // Color Buffer
    Gl.glGenBuffers(1, out ColorId);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, ColorId);
    Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(Colors.Length), Colors, Gl.GL_STATIC_DRAW);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);

    // Texture Buffer
    Gl.glGenBuffers(1, out TexCoordId);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, TexCoordId);
    Gl.glBufferData(Gl.GL_ARRAY_BUFFER, (IntPtr)(UVs.Length), UVs, Gl.GL_STATIC_DRAW);
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0);

    // Index Buffer
    Gl.glGenBuffers(1, out IndexId);
    Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, IndexId);
    Gl.glBufferData(Gl.GL_ELEMENT_ARRAY_BUFFER, (IntPtr)(Faces.Length), Faces, Gl.GL_STATIC_DRAW);
    Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, 0);
}

private void SetupPointers()
{
    // Vertex
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, VertexId);
    Gl.glEnableClientState(Gl.GL_VERTEX_ARRAY);
    Gl.glVertexPointer(3, Gl.GL_DOUBLE, 0, Vertices);
    Gl.glVertexAttribPointer(0, 3, Gl.GL_DOUBLE, Gl.GL_FALSE, 0, 0);

    // Color
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, ColorId);
    Gl.glEnableClientState(Gl.GL_COLOR_ARRAY);
    Gl.glColorPointer(4, Gl.GL_FLOAT, 0, Colors);
    Gl.glVertexAttribPointer(1, 4, Gl.GL_FLOAT, Gl.GL_FALSE, 0, 0);

    // Texture
    Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, TexCoordId);
    Gl.glEnableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
    Gl.glTexCoordPointer(2, Gl.GL_FLOAT, 0, UVs);
    Gl.glVertexAttribPointer(2, 2, Gl.GL_FLOAT, Gl.GL_FALSE, 0, 0);

    // Index
    Gl.glBindBuffer(Gl.GL_ELEMENT_ARRAY_BUFFER, IndexId);
}

public void Draw()
{
    if(bInitiated)
    {
        InitiateBeforeDraw();
        bInitiated= true;
    }

    SetupPointers();

    Gl.glDrawElements(Gl.GL_TRIANGLES, Faces.Length, Gl.GL_UNSIGNED_INT, Faces);

    Gl.glDisableClientState(Gl.GL_VERTEX_ARRAY);
    Gl.glDisableClientState(Gl.GL_COLOR_ARRAY);
    Gl.glDisableClientState(Gl.GL_TEXTURE_COORD_ARRAY);
}

我还附加了一个放入obj文件格式的简单立方体

mtllib Cube.mtl
o Cube
v -10.000000 -10.000000 10.000000
v -10.000000 -10.000000 -10.000000
v 10.000000 -10.000000 -10.000000
v 10.000000 -10.000000 10.000000
v -10.000000 10.000000 10.000000
v -10.000000 10.000000 -10.000000
v 10.000000 10.000000 -10.000000
v 10.000000 10.000000 10.000000
vt 0.000087 0.250044
vt 0.250043 0.250044
vt 0.250043 0.500000
vt 0.500000 0.000087
vt 0.500000 0.250044
vt 0.749956 0.500001
vt 0.499999 0.500000
vt 0.250042 0.749957
vt 0.749956 0.250044
vt 0.999913 0.250044
vt 0.999913 0.500001
vt 0.000087 0.500000
vt 0.250042 0.000087
vt 0.499999 0.749957
usemtl Mat_Cube
s off
f 6/1 2/2 1/3
f 7/4 3/5 2/2
f 8/6 4/7 3/5
f 5/8 1/3 4/7
f 2/2 3/5 4/7
f 7/9 6/10 5/11
f 5/12 6/1 1/3
f 6/13 7/4 2/2
f 7/9 8/6 3/5
f 8/14 5/8 4/7
f 1/3 2/2 4/7
f 8/6 7/9 5/11

现在如果你还没有看到问题已经存在,请查看第一个'f',表示face,第一个数字是6,调用顶点数字6,下一个数字是斜线一,调用纹理坐标编号1.现在在第六个面上,它再次调用顶点编号6,但这次使用纹理坐标编号10.下次弹出时就像第一次,第三次它会弹出它的调用纹理坐标数13.正如你所知,这里的问题不是我必须将所有数据磨练成结构,而是实际告诉opengl如何索引我的顶点,纹理,颜色和法线不同的指标指标。

虽然总是“让你的UV图像中的每个纹理坐标都为同一个顶点调用相同的点”,但是看起来很简单,它有很大的误差范围,看起来很难纹理周围的,并且“剥皮”我的模型仍然会有误差。

那我怎么能做到这一点?

0 个答案:

没有答案