Opengl es 绘制多个对象
Opengl es drawing multiple objects
我有这个网格 class,它有 3 个数组列表:顶点、边、面,但我找不到以正确方式绘制它们的方法。我希望背面的顶点和边缘不会通过相机前面的面孔可见。就像我有一个立方体一样,我希望面向相机的顶点、边和面可见,其余部分不可见。
我不知道这是否足够清楚,我只是将其作为练习来了解有关 OpenGL ES 的更多信息。
如果有另一种方法可以像 class 那样使用顶点、边和面来处理网格,请帮忙。谢谢
这是我的网格 class 代码:
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
我不确定我是否理解这个问题,但通常在 3D 中绘制形状时,您应该使用深度缓冲区。您需要启用它并为其设置一些适当的功能(只需在网上搜索一下,它使用起来非常简单)。深度缓冲区将确保后面的像素不会覆盖前面的像素。
您应该研究的另一件事是面部剔除。这只是您可以启用并将顺序设置为顺时针或逆时针并适用于三角形(或其他可能的表面)的东西。它所做的是,如果表面的屏幕投影顺序与您设置的剔除顺序不同,它将简单地忽略表面。这实际上用作优化,但在单个立方体的情况下,它也可以是一个解决方案。只需确保在生成形状时顺序一致即可。
在实践中,您很可能希望同时使用两者。正确绘制的深度缓冲区和剔除以获得性能。
至于处理网格,类有很多方法。通常所做的是通过公共绘图将网格的各个部分组合在一起。由于性能提高,您可能希望减少绘图调用(glDraw
调用的次数)。因此,在您的情况下,您将通过一次绘制调用绘制所有三角形,同时提供所有顶点数据和多个三角形。为了让它更有趣一点,您实际上可以在 GPU 上创建一个顶点缓冲区来保存所有顶点数据,并继续重复使用该缓冲区以减少 CPU 和 GPU 之间的数据流量。然后,您可以为网格使用单个缓冲区,该缓冲区包含要绘制的所有数据,并且您的不同部分只会保存缓冲区中不同部分的位置(偏移量)。例如,如果您的立方体由 36 个顶点组成,而您的网格由 2 个立方体组成,那么第一个立方体的信息将从索引 0 开始并绘制 12 个三角形,而第二个将从 36*sizeof(Vertex)
开始并再次绘制 12三角形。
我有这个网格 class,它有 3 个数组列表:顶点、边、面,但我找不到以正确方式绘制它们的方法。我希望背面的顶点和边缘不会通过相机前面的面孔可见。就像我有一个立方体一样,我希望面向相机的顶点、边和面可见,其余部分不可见。
我不知道这是否足够清楚,我只是将其作为练习来了解有关 OpenGL ES 的更多信息。
如果有另一种方法可以像 class 那样使用顶点、边和面来处理网格,请帮忙。谢谢
这是我的网格 class 代码:
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
我不确定我是否理解这个问题,但通常在 3D 中绘制形状时,您应该使用深度缓冲区。您需要启用它并为其设置一些适当的功能(只需在网上搜索一下,它使用起来非常简单)。深度缓冲区将确保后面的像素不会覆盖前面的像素。
您应该研究的另一件事是面部剔除。这只是您可以启用并将顺序设置为顺时针或逆时针并适用于三角形(或其他可能的表面)的东西。它所做的是,如果表面的屏幕投影顺序与您设置的剔除顺序不同,它将简单地忽略表面。这实际上用作优化,但在单个立方体的情况下,它也可以是一个解决方案。只需确保在生成形状时顺序一致即可。
在实践中,您很可能希望同时使用两者。正确绘制的深度缓冲区和剔除以获得性能。
至于处理网格,类有很多方法。通常所做的是通过公共绘图将网格的各个部分组合在一起。由于性能提高,您可能希望减少绘图调用(glDraw
调用的次数)。因此,在您的情况下,您将通过一次绘制调用绘制所有三角形,同时提供所有顶点数据和多个三角形。为了让它更有趣一点,您实际上可以在 GPU 上创建一个顶点缓冲区来保存所有顶点数据,并继续重复使用该缓冲区以减少 CPU 和 GPU 之间的数据流量。然后,您可以为网格使用单个缓冲区,该缓冲区包含要绘制的所有数据,并且您的不同部分只会保存缓冲区中不同部分的位置(偏移量)。例如,如果您的立方体由 36 个顶点组成,而您的网格由 2 个立方体组成,那么第一个立方体的信息将从索引 0 开始并绘制 12 个三角形,而第二个将从 36*sizeof(Vertex)
开始并再次绘制 12三角形。