关于绘制四边形的简单问题。我目前正在使用:
GraphicsDevice.DrawPrimitives(PrimitiveType primitiveType,
int startVertex, int primitiveCount);
这样可以很好地绘制我的四边形,但我能使其工作的唯一方法是使用六(6)个顶点作为我的四边形(将它们绘制为两个三角形)。我只是想知道是否有可能为GPU提供四(4)个顶点并仍然保留我的动态顶点缓冲区。
我知道我可以使用DrawUserIndexedPrimitives()但我想要我的缓冲区! ;)
编辑:我是否需要,如果是这样,我在哪里告诉我的GPU我每两个三角形喂它四个顶点?我现在将我的四边形作为nQuads * 6顶点存储在顶点缓冲区中,我的GPU使用每三个顶点作为三角形。所以只需切换到四个顶点即可:
Quads: {v1,v2,v3,v4} {v5,v6,v7,v8} ...
Triangles: {v1,v2,v3} {v4,v5,v6} {v7,v8 ...}
这不是一件好事,因为第二个三角形使用第一个四边形中的一个顶点,第三个使用第二个四边形中的两个顶点,依此类推。
编辑2:对不起,我实际上是在使用动态顶点缓冲区。
发布一些关于如何使用六个顶点进行四边形的代码:
// ## CONSTRUCTION
// Setting up buffer and vertex holder.
particleVertexBuffer = new DynamicVertexBuffer(graphicsDevice,
ParticleQuad.VerticesSizeInBytes * nMaxParticles,
BufferUsage.WriteOnly);
particleVertices = new ParticleVertex[nMaxParticles * 6];
// ## ADD VERTICES
particleVertices[i].Set();
particleVertices[i+1].Set();
particleVertices[i+2].Set();
particleVertices[i+3].Set();
particleVertices[i+4].Set();
particleVertices[i+5].Set();
// ## SET BUFFER
particleVertexBuffer.SetData(particleVertices, 0, nMaxParticles * 6, SetDataOptions.NoOverwrite);
graphicsDevice.Vertices[0].SetSource(particleVertexBuffer, 0, ParticleVertex.SizeInBytes);
// ## DRAW
graphicsDevice.DrawPrimitives(PrimitiveType.TriangleList,
FirstUsedParticle * 6, ((LastUsedParticle - FirstUsedParticle)+1)* 2);
现在,还有更多内容,因为我使用循环队列和其他一些东西,但这足以让人理解。
答案 0 :(得分:2)
是的,这是可能的。您需要使用TriangleStrip作为PrimitiveType。在VertexBuffer中,按以下顺序定义顶点:
1---3
|\ |
| \ |
| \|
0---2
编辑以解决您修改后的问题
我不知道你的代码是怎样的,但一般来说,有关primitve计数的信息在以下地方使用:
public VertexBuffer (
GraphicsDevice graphicsDevice,
int sizeInBytes,
BufferUsage usage
)
// sizeInBytes取决于原始计数。public void DrawPrimitives (
PrimitiveType primitiveType,
int startVertex,
int primitiveCount
)
请注意,在更多地方需要有关顶点格式的 size 的信息,但不应该是一个问题,因为大小不应该改变。
对于澄清而言,现在我知道,你想要实现的目标。处理问题的正确方法是将顶点缓冲区与索引缓冲区结合使用。顶点缓冲区保存顶点,索引缓冲区保存连接顶点以形成三角形的顺序。想象一下你想在屏幕上绘制以下四边形:
(0,1)________(1,1)
| |
| |
|________|
(0,0) (1,0)
你之前做过的是:
Vector3 v0, v1, v2, v3;
v0 = new Vector3(0, 0, 0);
v1 = new Vector3(1, 0, 0);
v2 = new Vector3(0, 1, 0);
v3 = new Vector3(1, 1, 0);
List vertices = new List();
//first triangle
vertices.add(v0);
vertices.add(v2);
vertices.add(v1);
//second triangle
vertices.add(v2);
vertices.add(v1);
vertices.add(v3);
VertexBuffer vb = new VertexBuffer(...);
vb.setData(verticesToDraw);
//draw the scene using PrimitiveType.TriangleList and primitive count 2
你现在做的是:
//vertices stay the same as in the example above!
List vertices = new List();
vertices.add(v0);
vertices.add(v1);
vertices.add(v2);
vertices.add(v3);
int[] indices = new int[6];
//first triangle
indices[0] = 0;
indices[1] = 2;
indices[2] = 1;
//second triangle
indices[3] = 2;
indices[4] = 1;
indices[5] = 3;
VertexBuffer vb = new VertexBuffer(...);
IndexBuffer ib = new IndexBuffer(...);
vb.setData(vertices);
ib.setData(indices);
/*draw using the DrawIndexedPrimitives() method rather than the
DrawPrimitives() method and use PrimitiveType.TriangleList and
primitive count 2.*/
你看,你每个四边形保存2个顶点,而是使用6个索引来指定从顶点构建三角形的顺序。因此,此方法仅在您的顶点很大(包括法线,纹理坐标等许多信息)并且由许多三角形共享时才有用。
Riemers.net有一个关于顶点和索引缓冲区的非常好,简单易懂的教程。