\$10

### Image of the Day Submit

IOTD | Top Screenshots

## How to make multiple rectangles?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

11 replies to this topic

### #1Kyle Brechin  Members

Posted 27 January 2011 - 11:40 AM

I keep having to read over the sections initializing and setting up the indices, vertex, and index buffer. I find the concept a little intimidating code wise, though the concept isn't hard.

I'd like to try to do something to better help my understanding by taking the original rectangle that was made and setting up two more along the left and right side.

1st rect vetexes:
-1,1,0
1,-1,0
-1,-1,0
1,1,0

2nd:
-1,1,1
-1,-1,0
-1,-1,1
-1,1,0

3rd:
1,1,0
1,-1,1
1,-1,0
1,1,1

Now, what I can't grasp is after I create these points, do try have to be made in order? Or following the culling rules? Can I put the drawing in the same effect start and end? How so I properly I initialize this in the vertex and index buffer?

I'm trying to grasp the concept of how and why but I'm not getting enough answers from the book.

### #2Kyle Brechin  Members

Posted 27 January 2011 - 12:38 PM

In keeping with the culling, I've created new vertices in InitializeVertices() as such:


#region Left Rectangle

// top left

position = new Vertex3(-1, 1, 1);

textureCoordinates = new Vector2(0,0);

vertices[0] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

// bottom right

position = new Vertex3(-1, 1, 0);

textureCoordinates = new Vector2(1,1);

vertices[1] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

// bottom left

position = new Vertex3(-1, -1, 1);

textureCoordinates = new Vector2(0,1);

vertices[2] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

// top right

position = new Vertex3(-1, 1, 0);

textureCoordinates = new Vector2(1,0);

vertices[3] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

#endregion

#region Middle rectangle

// top left

position = new Vertex3(-1, 1, 0);

textureCoordinates = new Vector2(0,0);

vertices[4] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

// bottom right

position = new Vertex3(1, 1, 0);

textureCoordinates = new Vector2(1,1);

vertices[5] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

// bottom left

position = new Vertex3(-1, -1, 0);

textureCoordinates = new Vector2(0,1);

vertices[6] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

// top right

position = new Vertex3(1, 1, 0);

textureCoordinates = new Vector2(1,0);

vertices[7] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

#endregion

#region right rectangle

// top left

position = new Vertex3(1, 1, 1);

textureCoordinates = new Vector2(0,0);

vertices[8] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

// bottom right

position = new Vertex3(1, -1, 1);

textureCoordinates = new Vector2(1,1);

vertices[9] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

// bottom left

position = new Vertex3(1, -1, 0);

textureCoordinates = new Vector2(0,1);

vertices[10] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

// top right

position = new Vertex3(1, 1, 1);

textureCoordinates = new Vector2(1,0);

vertices[11] = new VertexPositionNormalTexture(position, Vector3.Forward, textureCoordinates);

#endregion



Note i changed:
vertices = new VertexPositionNormalTexture[4];
to
vertices = new VertexPositionNormalTexture[12];

Then I went into InitializeIndices() and changed it to:

indices = new short[18];

// left (bottom)

indices[0] = 0; // top left

indices[1] = 1; // bottom right

indices[2] = 2; // bottom left

// left (top)

indices[3] = 0; // top left

indices[4] = 3; // top right

indices[5] = 1; // bottom right

// middle (bottom)

indices[6] = 3; // top left

indices[7] = 4; // bottom right

indices[8] = 1; // bottom left

// middle (top)

indices[9] = 3; // top left

indices[10] = 5; // top right

indices[11] = 4; // bottom right

// right (bottom)

indices[12] = 5; // top left

indices[13] = 6; // bottom right

indices[14] = 4; // bottom left

// right (top)

indices[15] = 5; // top left

indices[16] = 7; // top right

indices[17] = 6; // bottom right



I did this on my iPhone, sorry if there're any typos. I also haven't been able to run it or anything, but it makes sense in my head that it'll work. Except I don't know how ill set it up. Would I just modify the call to DrawUserPrimitives we already have?

Oh man my eyes and fingers hurt now....

### #3NEXUSKill  Members

Posted 28 January 2011 - 07:42 AM

Time for a little object oriented work, as I recommended in my thread, you should try to separate the code and variables that "make" the rectangle into one class, MeshObject or something, and the code and variables that can be used to draw any given mesh into another class, Renderer, which should prepare the graphics device and draw all the rectangles it knows about.

The World transform, the vertex and index buffers (and the vertices initialization), the texture and the vertex declaration are specifically of the mesh.

The effect, the Technique/Pass loop, and the setting of parameters should be responsability of the renderer.

You should also make the camera into a separate object, in the next chapter we'll be doing that and adding some input control to it.

Game making is godlike

### #4Kyle Brechin  Members

Posted 28 January 2011 - 08:36 AM

With such a small project i didn't bother creating new methods for my two new triangles, but creating new methods for various calls is important especially in the OOP realm. Breaking down methods such as gamepad, keyboard, and graphics initialization, really make the process easier and more reusable.

I got off work and tried running the code, while it ran and compiled (after a few typos i had to fix mainly all my Vertex3 to Vector3 [damn iPhone autocorrect]) I still didn't get the result I wanted. In fact I got something strange. The right rectangle appeared to draw, but t wasn't a rectangle. So I reread the chapter trying to figure where I went wrong.

Then I modified the number of vertices I placed in InitializeVertices() to create only vertices that wouldn't be double (though im sure index buffer helps with this as well). Still didn't get the result I wanted of my little U shaped rectangles facing me.

Any suggestions or pointers in the right direction?

When i get off work again I'll have to give it another go! Ooooo this is fun!

### #5NEXUSKill  Members

Posted 28 January 2011 - 08:43 AM

The point of creating an object to handle the representation of a mesh is to avoid having to figure out where the vertices should be, if you create an object that defines the rectangle as given by the book, with 4 vertices only, then you can create two instances of that object, apply different transformations to their world matrices and voila! you have two rectangles in different positions and orientations.
Game making is godlike

### #6Kyle Brechin  Members

Posted 28 January 2011 - 10:21 AM

So I have to make the triangles separately just like the book does a few pages after with the DrawRectangle() and apply the transformations to their world matrices? I can't just create all the points and draw them?

(by the way, what's the tag for code?! Haha)

### #7NEXUSKill  Members

Posted 28 January 2011 - 10:29 AM

Well... you can just create and draw the polys... but why would you want to?, it's not flexible, it's not reusable and it would get REALLY messy as your scene gets more complex, can you imagine trying to render a car that way? or a person?

You don't HAVE to do it the way I propose, but its just good business

Not every graphic will come from a 3D model, thats true, you could for instance render a more procedural thing like linestrips representing collision boxes for graphic debug information, but once again, do you really want to be repeating all the code for the vertices, indexes and all that every time you want to do something like that? why not have a class that already knows how to do that and give it the parameters you need?

Game making is godlike

### #8Kyle Brechin  Members

Posted 28 January 2011 - 11:25 AM

I agree completely with your method.

But back to the original point of my post. Understanding how to create another rectangle manually and building up understanding of shown topics thusfar.

Pretend your book stops at the last page where we get the rectangle drawn. Using the same coding style of the book, manually drawing vertices, how would I take the code i wrote about an have it properly draw 2 more rectangles along the border of the original.

### #9NEXUSKill  Members

Posted 28 January 2011 - 12:46 PM

Well, as the book recommends, you might wanna take paper and pencil and draw the primitives you want to create to get a clear idea of where each vertex end up being located.

so, if the first rectangle was going between -1 and 1 in both axis, with center in (0,0), that means the rectangle has 2 units of width and height, if you want two more rectangles adyacent to each side, you need two new vertices on each side, two units apart from the original ones, so we'll go something like this:

vertices[0] = new VertexPositionNormalTexture(new Vector3(-3, -1, 0), Vector3.Forward, new Vector2(0, 0));
vertices[1] = new VertexPositionNormalTexture(new Vector3(-3, 1, 0), Vector3.Forward, new Vector2(0, 1));
vertices[2] = new VertexPositionNormalTexture(new Vector3(-1, -1, 0), Vector3.Forward, new Vector2(1, 0));
vertices[3] = new VertexPositionNormalTexture(new Vector3(-1, 1, 0), Vector3.Forward, new Vector2(1, 1));
vertices[4] = new VertexPositionNormalTexture(new Vector3(1, -1, 0), Vector3.Forward, new Vector2(0, 0));
vertices[5] = new VertexPositionNormalTexture(new Vector3(1, 1, 0), Vector3.Forward, new Vector2(0, 1));
vertices[6] = new VertexPositionNormalTexture(new Vector3(3, -1, 0), Vector3.Forward, new Vector2(1, 0));
vertices[7] = new VertexPositionNormalTexture(new Vector3(3, 1, 0), Vector3.Forward, new Vector2(1, 1));


I compressed it for more readability, and since the larger distribution doesn't save any news it doesn't make any difference.
This creates the vertices for three consecutive rectangles centered on (0,0,0) and with height and width of 2. Now for the indexes:

indices[0] = 0; indices[1] = 1; indices[2] = 2;
indices[3] = 1; indices[4] = 3; indices[5] = 2;
indices[6] = 2; indices[7] = 3; indices[8] = 4;
indices[9] = 3; indices[10] = 5; indices[11] = 4;
indices[12] = 4; indices[13] = 5; indices[14] = 6;
indices[15] = 5; indices[16] = 7; indices[17] = 6;


Just put these new arrays in the vertex and index buffers as before, update the number of primitives from 2 to 6 and you'll be getting three rectangles

Game making is godlike

### #10NEXUSKill  Members

Posted 28 January 2011 - 12:52 PM

Now, an interesting exercise is to change from TriangleList to TriangleStrip.

TriangleStrip delivers the same result taking much less indexes than TriangleList, it does this by using the last two indices of the previous triangle plus the next index to create the next triangle.

For example, to render two triangles it needs only 4 indices, it will assume that both triangles share the two indices in the middle.

Taking the vertices declared in my previous example, the index array to render the first two triangles is:

indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 3;


Much more simple.

Game making is godlike

### #11Kyle Brechin  Members

Posted 28 January 2011 - 01:29 PM

Hmm, that's pretty much the code i ended up with after I made the changes. I think I may have forgotten to update the vertex or index buffer though. Maybe that's why it wasn't showing up right.

### #12NEXUSKill  Members

Posted 31 January 2011 - 07:29 AM

Hmm, that's pretty much the code i ended up with after I made the changes. I think I may have forgotten to update the vertex or index buffer though. Maybe that's why it wasn't showing up right.

Don't forget to update the primitive count parameter on the draw call, it's a very common mistake when it is hardcoded as in the example, it should be determined in function of the primitive type automatically, in TriangleList the number is NIndex/3, in triangle strip its NIndex-2

Game making is godlike

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.