Opengl es绘制多个对象

时间:2016-03-19 19:17:06

标签: android opengl-es mesh

我有这个网格类,它有3个ArrayLists:顶点,边,面,但我找不到以正确方式绘制它们的方法。我希望通过相机前面的面部看不到背面的顶点和边缘。就像我有一个立方体一样,我想要看到面向相机的顶点,边和面,其余部分应该不可见。

我不知道这是否足够清楚,我只是这样做是为了更多地了解OpenGL ES。

如果还有其他方法来处理使用顶点,边和面作为类的网格,请帮助。感谢。

这是我的网格类代码:

public class Mesh {

protected ArrayList<Vertex> vertices;
protected ArrayList<Edge> edges;
protected ArrayList<Triangle> triangles;

public Vector Pos;
public float rx,ry,rz;
public float r,g,b,alfa;
private boolean colorSet;

private static boolean vertexOn,edgeOn,FaceOn;

Mesh()
{
    Pos=new Vector();
    vertices=new ArrayList<Vertex>();
    edges=new ArrayList<Edge>();
    triangles=new ArrayList<Triangle>();

    r=g=b=0; alfa=1;
    colorSet=false;

    vertexOn=true;
    edgeOn=true;
    FaceOn=true;
}

Mesh(Vector pos)
{
    Pos=pos;
    vertices=new ArrayList<Vertex>();
    edges=new ArrayList<Edge>();
    triangles=new ArrayList<Triangle>();

    r=g=b=0; alfa=1;
    colorSet=false;

    vertexOn=true;
    edgeOn=true;
    FaceOn=true;
}


public void add(Vertex v)
{
    vertices.add(v);
}

public void add(Edge e)
{
    edges.add(e);
}

public void add(Triangle t)
{
    triangles.add(t);
}

public static void setOn(boolean v,boolean e,boolean f)
{
    vertexOn=v; edgeOn=e; FaceOn=f;
}

public void setColor(float r,float g,float b,float alfa)
{
    colorSet=true;
    this.r=r; this.g=g; this.b=b; this.alfa=alfa;
}

public ArrayList<Vertex> getVertices()
{
    return vertices;
}

public ArrayList<Edge> getEdges()
{
    return edges;
}

public ArrayList<Triangle> getTriangls()
{
    return triangles;
}

public void draw(GL10 gl)
{
    gl.glPushMatrix();
    gl.glTranslatef(Pos.x,Pos.y,Pos.z);
    gl.glRotatef(rx,1,0,0);
    gl.glRotatef(ry,0,1,0);
    gl.glRotatef(rz,0,0,1);

    if(colorSet)
    {
        if(vertexOn)
            for(Vertex v: vertices)
            {
                v.setcolor(r,g,b,alfa);
                v.draw(gl);
            }

        if(FaceOn)
            for(Triangle t: triangles)
            {
                t.setcolor(r,g,b,alfa);
                t.draw(gl);
            }


        if(edgeOn)
            for(Edge e: edges)
            {
                e.setcolor(r,b,g,alfa);
                e.draw(gl);
            }
    }//if a single color is set for the whole mesh with edges and vertices
    else
    {
        if(vertexOn)
            for(Vertex v: vertices)
            {
                v.draw(gl);
            }

        if(FaceOn)
            for(Triangle t: triangles)
            {
                t.draw(gl);
            }

        if(edgeOn)
            for(Edge e: edges)
            {
                e.draw(gl);
            }
    }//if no color for the whole mesh has been set

    gl.glPopMatrix();
}//Draw

}//class

1 个答案:

答案 0 :(得分:1)

我不确定我是否理解这个问题但通常在3D中绘制形状时应使用深度缓冲区。您需要启用它并在其上设置一些适当的功能(只需在网上搜索一下,使用起来非常简单)。深度缓冲区将确保后面的像素不会被绘制在前面的像素上。

你应该研究的另一件事是面部剔除。这只是您可以启用的顺序,并将顺序设置为顺时针或逆时针,并适用于三角形(或其他可能的表面)。它的作用是,如果表面的屏幕投影的排序顺序不同,那么它将忽略表面,然后是你设置为剔除的顺序。这实际上用作优化,但在单个多维数据集的情况下,它也可以是一个解决方案。只需确保在生成形状时有一致的顺序。

在实践中,你很可能想要同时使用两者。正确绘制的深度缓冲区和剔除以获得性能。

至于处理网格和类,有很多方法。通常所做的是通过共同绘图将网格的各部分组合在一起。由于性能提高,您可能希望减少绘制调用(glDraw调用的数量)。因此,在您的情况下,您将使用单个绘制调用绘制所有三角形,同时给出所有顶点数据和多个三角形。为了使它更有趣,你可以在GPU上实际创建一个顶点缓冲区,保存所有顶点数据并继续重用那个以减少CPU和GPU之间的数据流量。然后,您可以为网格使用单个缓冲区,其中包含要绘制的所有数据,而您的不同部分只能保存缓冲区中不同部分的位置(偏移)。例如,如果您的立方体由36个顶点组成,并且您的网格由2个立方体组成,那么第一个立方体将具有从索引0开始并绘制12个三角形的信息,而第二个立方体将从36*sizeof(Vertex)开始并再次绘制12三角形。