Problem rendering quads

Hi.

We’re porting a game from OpenGL, it originally draws a set of Quads primitive types, it’s an arbitrary input of quads, however, I find myself unable to understand how to draw them on 3d space, right now it draws the primitives but they seem to be drawing in one single plane (drawing flat, not geometrically in 3d).

This is the code I’m using for drawing:

Microsoft.Xna.Framework.Graphics.VertexPositionTexture[] vertices =
                new Microsoft.Xna.Framework.Graphics.VertexPositionTexture[_quadBuffer.Length * 4];

            int vertexFillIndicer = 0;
            for (; currentBatchCount < _quadBuffer.Length; currentBatchCount++)
            {
                TexturedQuad foo = _quadBuffer[currentBatchCount];
                for (int i = 0; i < 4; i++)
                {
                    var position = new Microsoft.Xna.Framework.Vector3((float)foo.Position[i].X, (float)foo.Position[i].Y, 0);
                    var mapping = new Microsoft.Xna.Framework.Vector2((float)foo.TextureMapping[i].X, (float)foo.TextureMapping[i].Y);
                    vertices[vertexFillIndicer] = new Microsoft.Xna.Framework.Graphics.VertexPositionTexture(position, mapping);

                    vertexFillIndicer++;
                }
            }

            var World = Microsoft.Xna.Framework.Matrix.Identity;
            var ortho = Camera.modelViewMatrix;
            var View = new Microsoft.Xna.Framework.Matrix(
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row1.X, (float)ortho.Row1.Y, (float)ortho.Row1.Z, (float)ortho.Row1.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row2.X, (float)ortho.Row2.Y, (float)ortho.Row2.Z, (float)ortho.Row2.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row3.X, (float)ortho.Row3.Y, (float)ortho.Row3.Z, (float)ortho.Row3.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row4.X, (float)ortho.Row4.Y, (float)ortho.Row4.Z, (float)ortho.Row4.W));

            ortho = Camera.projectionMatrix;
            var Projection = new Microsoft.Xna.Framework.Matrix(
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row1.X, (float)ortho.Row1.Y, (float)ortho.Row1.Z, (float)ortho.Row1.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row2.X, (float)ortho.Row2.Y, (float)ortho.Row2.Z, (float)ortho.Row2.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row3.X, (float)ortho.Row3.Y, (float)ortho.Row3.Z, (float)ortho.Row3.W),
                new Microsoft.Xna.Framework.Vector4((float)ortho.Row4.X, (float)ortho.Row4.Y, (float)ortho.Row4.Z, (float)ortho.Row4.W));


            _effect.Parameters["World"].SetValue(World);
            _effect.Parameters["View"].SetValue(View);
            _effect.Parameters["Projection"].SetValue(Projection);

            var texture = (_floorTexture as MonoGameTexture).Texture;
            _effect.Parameters["InputTexture"].SetValue(texture);

            var buffer = new Microsoft.Xna.Framework.Graphics.VertexBuffer(
                                                        GraphicsDevice,
                                                        Microsoft.Xna.Framework.Graphics.VertexPositionTexture.VertexDeclaration,
                                                        vertices.Length,
                                                        Microsoft.Xna.Framework.Graphics.BufferUsage.WriteOnly);
            {
                // Load the buffer
                buffer.SetData(vertices);

                // Send the vertex buffer to the device
                GraphicsDevice.SetVertexBuffer(buffer);
            }
            if (vertices.Length > 0)
            {
                foreach (var pass in _effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    GraphicsDevice.DrawPrimitives(Microsoft.Xna.Framework.Graphics.PrimitiveType.TriangleList, 0, vertices.Length / 2);

                    //GraphicsDevice.DrawUserPrimitives(Microsoft.Xna.Framework.Graphics.PrimitiveType.TriangleList, vertices, 0, vertices.Length/4, Microsoft.Xna.Framework.Graphics.VertexPositionTexture.VertexDeclaration);
                    //GraphicsDevice.DrawUserIndexedPrimitives(Microsoft.Xna.Framework.Graphics.PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, (indices.Length / 3), Microsoft.Xna.Framework.Graphics.VertexPositionTexture.VertexDeclaration);
                    //GraphicsDevice.DrawUserIndexedPrimitives(Microsoft.Xna.Framework.Graphics.PrimitiveType.TriangleList, vertices, 0, vertices.Length, indices, 0, (indices.Length / 3), Microsoft.Xna.Framework.Graphics.VertexPositionTexture.VertexDeclaration);
                }

            }

Although the relevant part of the code is as follows:

var buffer = new Microsoft.Xna.Framework.Graphics.VertexBuffer(
                                                        GraphicsDevice,
                                                        Microsoft.Xna.Framework.Graphics.VertexPositionTexture.VertexDeclaration,
                                                        vertices.Length,
                                                        Microsoft.Xna.Framework.Graphics.BufferUsage.WriteOnly);
            {
                // Load the buffer
                buffer.SetData(vertices);

                // Send the vertex buffer to the device
                GraphicsDevice.SetVertexBuffer(buffer);
            }
            if (vertices.Length > 0)
            {
                foreach (var pass in _effect.CurrentTechnique.Passes)
                {
                    pass.Apply();
                    GraphicsDevice.DrawPrimitives(Microsoft.Xna.Framework.Graphics.PrimitiveType.TriangleList, 0, vertices.Length / 2);
                }

            }

I’m unsure what to do next, I tried indexed primitives using the following without luck:



            int verticesInaQuad = 4;
            int indicesInaQuad = 6;
            int verticeCount = NumVertices;
            int quadCount = verticeCount / verticesInaQuad;
            int indicesCount = quadCount * indicesInaQuad;

            int indexIndicer = 0;


            short[] indices = new short[indicesCount];

            for (int verticeIndicer = 0; verticeIndicer < NumVertices; verticeIndicer += verticesInaQuad)
            {
                if (GraphicsDevice.RasterizerState == RasterizerState.CullClockwise)
                {
                    indices[indexIndicer + 0] = (short)(verticeIndicer + 0);
                    indices[indexIndicer + 1] = (short)(verticeIndicer + 1);
                    indices[indexIndicer + 2] = (short)(verticeIndicer + 2);

                    indices[indexIndicer + 3] = (short)(verticeIndicer + 2);
                    indices[indexIndicer + 4] = (short)(verticeIndicer + 3);
                    indices[indexIndicer + 5] = (short)(verticeIndicer + 0);
                }
                else
                {
                    indices[indexIndicer + 0] = (short)(verticeIndicer + 0);
                    indices[indexIndicer + 1] = (short)(verticeIndicer + 2);
                    indices[indexIndicer + 2] = (short)(verticeIndicer + 1);

                    indices[indexIndicer + 3] = (short)(verticeIndicer + 2);
                    indices[indexIndicer + 4] = (short)(verticeIndicer + 0);
                    indices[indexIndicer + 5] = (short)(verticeIndicer + 3);

                }

                indexIndicer += indicesInaQuad;
            }

I assume I have to generate triangles out of the quads here:

            for (; currentBatchCount < _quadBuffer.Length; currentBatchCount++)
            {
                TexturedQuad foo = _quadBuffer[currentBatchCount];
                for (int i = 0; i < 4; i++)
                {

                    var position = new Microsoft.Xna.Framework.Vector3((float)foo.Position[i].X, (float)foo.Position[i].Y, 0);
                    var mapping = new Microsoft.Xna.Framework.Vector2((float)foo.TextureMapping[i].X, (float)foo.TextureMapping[i].Y);
                    vertices[vertexFillIndicer] = new Microsoft.Xna.Framework.Graphics.VertexPositionTexture(position, mapping);

                    vertexFillIndicer++;
                }
            }

By the way, it runs out of memory by using VertexBuffer allocations as it seems.

Well I can see a lot wrong here, but lets go through the obvious problems.

  1. Flat polygons.

var position = new Microsoft.Xna.Framework.Vector3((float)foo.Position[i].X, (float)foo.Position[i].Y, 0);

z = 0 so all quads will be at z = 0

  1. Draw code is wrong

GraphicsDevice.DrawPrimitives(Microsoft.Xna.Framework.Graphics.PrimitiveType.TriangleList, 0, vertices.Length / 2);

A TriangleList is just that, a list of triangles. Each triangle needs 3 vertices, so the number of primitives is vertices.Length / 3

Hope this helps

It was the Z position of vertices, indeed.

Thank you.