How do I draw a TriangleStrip / Filling it in XNA? - c#

I'm trying to wrap my head around:
http://msdn.microsoft.com/en-us/library/bb196409.aspx
And the reference isn't much to go on. It's short, vague and nothing that you can learn from.
I want to create a method that that takes a list of Triangle = (A class of 3 Vectors), and render it, and later be able to fill it with a color or a texture.
Can someone explain the above mentioned method? Because what I'm trying simply isn't working. I've tried adding one triangle. My understanding below, please correct me where I'm wrong.
Method when creating "One Triangle":
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>
(
PrimitiveType.TriangleStrip,
"array of 3 VertexPositionColor?",
0,
(3? 9?),
"I have no clue what to put here and why I should put it here?",
"What do I put here?",
"If 1 triangle, value should be = 1? 1 Triangle = 1 Primitive"
);
What do I need to make this work? Depending on how many Triangles I pass on to my methods, do I render and what values do change depending on how many Triangles there are?
...and if successful (hopefully sometime) how do I fill it?
Please, no vague short answers because the reference does that very very well.

One clarification to your way of thinking before we begin. In XNA - you draw a wireframe (outline) triangle, or a filled triangle or a textured triangle. There isn't anything lile "draw now" and "fill later". You can only draw something else on top of what's already in the framebuffer.
Also here is some background on what an indexed mesh is. This is the data fed into DrawUserIndexedPrimitives (vertices and triangles composed of indices into the sett of vertices).
Given that, here's how the draw call works
_effect.Texture = texture; // This sets the texture up so the
// shaders associated with this effect can access it
// The color in each vertex is modulated with the texture color
// and linearly interpolated across vertices
_effect.VertexColorEnabled = true;
foreach (var pass in _effect.CurrentTechnique.Passes)
{
pass.Apply(); // This sets up the shaders and their state
// TriangleList means that the indices are understood to be
// multiples of 3, where the 3 vertices pointed to are comprise
// one triangle
_device.DrawUserIndexedPrimitives(PrimitiveType.TriangleList,
// The vertices. Note that there can be any number of vertices in here.
// What's important is the indices array (and the vertexOffset, primitivecount, vertexCount) that determine
// how many of the provided vertices will actually matter for this draw call
_vertices,
// The offset to the first vertex that the index 0 in the index array will refer to
// This is used to render a "part" of a bigger set of vertices, perhaps shared across
// different objects
0,
// The number of vertices to pick starting from vertexOffset. If the index array
// tried to index a vertex out of this range then the draw call will fail.
_vertices.Count,
// The indices (count = multiple of 3) that comprise separate triangle (because we said TriangleList -
// the rules are different depending on the primitive type)
_indices,
// Again, an offset inside the indices array so a part of a larger index array can be used
0,
// Number of indices. This HAS to be a multiple of 3 because we said we're rendering
// a list of triangles (TrangleList).
kvp.Value.Indices.Count / 3);
}
I hope that is clear. Do let me know if you have any specific questions about each of the parameters and/or concepts and I can edit this post to clarify those points.
Hope this helps!

Related

Best approach for storing elements in C# that have within epsilon definition of equality

The program uses vertices in R^2 as nodes and there are edges between nodes, and ultimately more is built from there. There are a high number of circuitous ways that a point (x,y) in R^2 might be reached that may rely on layer after layer of trig functions. So it makes sense to define one vertex as the canonical vertex for all points in a square with side length 2*epsilon centered at the point. So various calculations happen, out comes a point (x,y) where I wish to put a vertex, a vertex factory checks to see if there is already vertex deemed as canonical that should be used for this point, if so it returns that vertex, if not a new vertex is created with the coordinates of the point and that vertex is now deemed canonical. I know this can lead to ambiguities given the possibility for overlap of the squares but that is immaterial for the moment, epsilon can be set to make the probability of such a case vanishingly small.
Clearly a list of canonical vertices must be kept.
I have working implementations using List<Vertex> and HashSet<Vertex>, however the vertex creation process seems to scale poorly when the number of vertices grows to over over 100,000 and incredibly poorly if the number gets anywhere near 1,000,000.
I have no idea how to efficiently implement the VertexFactory. Right now Vertex has method IsEquivalentTo(Vertex v) and returns true if v is contained in the square around the instance vertex calling it, false otherwise.
So the the vertex creation process looks like this:
Some point (x,y) get calculated and requests a new vertex from the vertex manager.
VertexManager creates a temporary vertex temp then uses a foreach to iterate over every vertex in the container using IsEquivalentTo(temp) to find a match and return it, if no match is found then add temp to the container and return it. I should state that if a match is found obviously it breaks out of the foreach loop.
I may be way off but my first guess would be put an order on the vertices such as
v1 < v2 iff ( (v1.X < v2.X) || ( (v1.X == v2.X) && (v1.Y < v2.Y) ) )
and then store the vertices in a sorted container. But to be honest I do not know enough about about the various containers to know which is the most appropriate for the purpose, standard C# best practices, etc
Edit:
I cannot mark the comment as an answer so thanks to GSerg whose comment guided me to kd-trees. This is exactly what I was looking for.
Thanks

How to randomly place objects as player move around in an infinity map without overlap?

I trying to make a game where player only move forward in an infinity map, and the path (just thing of them like points, the path is only the visual) is procedurally generated. I want those path to have different length (something like the tree of life, but only branches of the selected path are generated).
This is how I generate branches without overlap:
List<Vector3> everyPos; //predetermined position
public void Spawn(int amount)
{
List<Vector3> possiblePos = new List<Vector3>(everyPos);
for (int i = 0; i < amount; i++)
{
int index = Random(0, possiblePos.Count); //Find a random position
SpawnObjectAt(currentPosition+possiblePos[index]));//Create a point there
possiblePos.RemoveAt(index); //Remove that position from the list
}
}
The problem is , look at this image(I can't embed image yet):
Red is where player start, green is possible spawn position in the first move.
If there are 2 point spawned at 1 and 2, player choose point1, then the possible position in the second time will be a point in the black zone, which include point2, so if I keep continue there will eventually overlap.
How can I avoid this? I'm making a mobile game so I don't want to cache every single point. Any help would be really appreciated! Thanks!
This is a small web game that have somewhat similar mechanic to what I trying to achieve: newgrounds.com/portal/view/592325/
This is an attempt here to answer, but honestly, you need to provide more information.
Depending on the language you are writing in, you can handle this differently. You may need dynamic allocation, but for now lets assume, since your idea is quite small, that you can just do one large array predefined before compile time.
I assume you know how to make an array, so create one with say, 500 length to start. If you want to 'generate' a link like they did in that game, you simply need a random function, (there is a built in library in pretty much every language I think) and you need to do a little math.
Whatever language you use will surely have a built in graphics library, or you can use a popular easy to use one. I'll just draw a picture to make this clear.
There are a number of ways you can do this mathematically as shown in the image, using angles for example, the simplest way, however, is just to follow the boxes.
If you have worked with graphics before, you know what a vector is, if not, you will need to learn. The 9 vectors presented in this image (0,1) (1,0) (1,1) etc. can be created as vector objects, or even stored as individual ints.
To make your nodes 'move' into another path, you can simply do a rand 1-9 and then correlated the result to one of 9 possible vectors, and then add them to your position vector. It is easiest to do this in array and just use the rand int as the index. In most c derived languages you do that like this:
positionVector += changeVectorArray[rand(1,9)];
You then increment your position vector by one of the 9 vectors as shown above.
The simplest way of making the 'path' is to copy the position before you add the change vector, and then store all of the changes sequentially in another 'path' array.
To show the path on screen, simply draw a line between the first and second, second and third, third and forth elements of your path array. This formula (of joining lines) is discrete mathematics if I'm not mistaken, and you can do much more complicated path shapes if you want, but you get the gist.
That should at least start you off. Without more info I can't really help you.
I could go off on a tangent describe a bunch of different ways you can make this happen differently but its probably easier if you just ask for specifics.
EDIT>>>
Continuing with this answer, yes, looking at it now, the nodes can definitely overlap. To solve this problem you could use collision detection, every time you generate a new 'position', before adding it and drawing the line you have to loop through your array like this:
boolean copy = true;
for(int i = 0; i < getLength(pathArray); i++){
if( newVector == pathArray[i]){
copy=false;
}
}
Then of course, if copy still is true, copy the new position int the pathArray. NOTE: this whole solution is sloppy as hell, and as your array gets larger, your program is going to take longer and longer to search through that loop. This may not also guarantee that the path goes in one direction, but it is likely. And note that the lines will still be able to overlap each other, even though the position vectors can't be on top of one another.
All this considered, I think it will work, the optimization is up to you. I would suggest that there is probably a much more efficient solution using a discrete formula. You can also use such a formula to make the path go in particular directions and do other more complicated things.
You could also quite easily apply constraints on your random rolls if you want to make the path go in a particular direction. But there are so many ways of doing this I can't begin to explain. You could google path-finding algorithms for that.
Good luck.

Draw segments of circle on xna

How do I draw a circle sector (as in a slice of pizza shape) in xna?
I'd like to use one as a timer indicator, so would like to be able change its angle dynamically.
In an ideal world I'm looking for something like this:
Drawsector (float startAngle, float endAngle, ... )
Does such a thing exist?
And if it does - how would I go about drawing a more graphically involved one (as opposed to just block colour)
No. XNA only provides an API for drawing primitive elements called surprisingly primitives.
All is not lost because drawing a circle can be viewed as simply drawing a series of very short interconnected line segments, small enough that you can't tell they are lines, but not too small so as to be inefficient.
In XNA you would draw a PrimitiveType.LineStrip.
MSDN:
The data is ordered as a sequence of line segments; each line segment is described by one new vertex and the last vertex from the previous line seqment. The count may be any positive integer.
e.g. (from MSDN)
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
PrimitiveType.LineStrip,
primitiveList,
0, // vertex buffer offset to add to each element of the index buffer
8, // number of vertices to draw
lineStripIndices,
0, // first index element to read
7 // number of primitives to draw
);
You would need to create your own function to determine the vertices that match the arc you want to draw. You should save that into a permanent index and vertice buffer rather than performing a DrawSector() all the time in your game loop.
Tell me more
Drawing 3D Primitives using Lists or Strips

XNA 4.0 draw a cube with DrawUserIndexedPrimitives method

EDIT
Since I read what Mark H suggested (thanks a lot, I found it very useful) I think my question can become clearer structured this way:
Using XNA 4.0, I'm trying to draw a cube.
Im using this method:
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
PrimitiveType.LineList,
primitiveList,
0, // vertex buffer offset to add to each element of the index buffer
8, // number of vertices in pointList
lineListIndices, // the index buffer
0, // first index element to read
7 // number of primitives to draw
);
I got the code sample from this page which simply draw a serie of triangles.
I want to modify this code in order to draw a cube. I was able to slitghly move the camera so I can have the perception of solidity, I set the vertex array to contain the 8 points defining a cube. But I can't fully understand how many primitives I have to draw (last parameter) for each of PrimitiveType.
So, I wasn't able to draw the cube (just some of the edges in a non-defined order).
More in detail:
to build the vertex index list, the sample used
// Initialize an array of indices of type short.
lineListIndices = new short[(points * 2) - 2];
// Populate the array with references to indices in the vertex buffer
for (int i = 0; i < points - 1; i++)
{
lineListIndices[i * 2] = (short)(i);
lineListIndices[(i * 2) + 1] = (short)(i + 1);
}
I'm ashamed to say I cannot do the same in the case of a cube.
what has to be the size of the lineListIndices?
how should I populate it? In which order?
And how do these things change when I use a different PrimitiveType?
In the code sample there are also another couple of calls which I cannot fully understand, which are:
// Initialize the vertex buffer, allocating memory for each vertex.
vertexBuffer = new VertexBuffer(graphics.GraphicsDevice, vertexDeclaration,
points, BufferUsage.None);
// Set the vertex buffer data to the array of vertices.
vertexBuffer.SetData<VertexPositionColor>(pointList);
and
vertexDeclaration = new VertexDeclaration(new VertexElement[]
{
new VertexElement(0, VertexElementFormat.Vector3, VertexElementUsage.Position, 0),
new VertexElement(12, VertexElementFormat.Color, VertexElementUsage.Color, 0)
}
);
that is, for VertexBuffer and VertexDeclaration I could not find and significant (monkey-like) guide. I reported them too because I think they could be involded in understanding things.
I think I also have to understand something related to the order the vertexes are stored in the array. But actually I have no clue of what I should learn to have this function drawing a cube. So, if anybody could point me to the right direction, it wil be appreciated.
Hope to have made myself clear this time
Eventually I was able to find a worthful guide to draw a cube. In there they use DrawUserPrimitive<T> method but the difference is quite a thin one. I had no difficulties in using both methods. As you will see, this guide includes explainations on every concern of drawing a cube, like the order vertexes have to be stored and then drawn, and number of primitives to pass the drawing method.
Hope this could be of help to anyone who will be struggling with this problem such as I was.

How To Make a Tetris Clone?

I am working on coding a Tetris clone in XNA C# and am unsure of the best way to approach the data structure side of the game on a high level.
I am totally fine with the collision detection, rotations, animation etc. What I need to know the best way to do the storing of "dropped blocks" - ie blocks that are no longer under tha player's control.
I think that each Tetromino block should be stored in its own class that consists of a 4x4 array so that the block can easily be rotated. The problem is then how to I store the tetromino's final position into the game grid by then cutting the tetromino up into individual blocks(for each cell) and then set the main game grid's corresponding positions to hold these same blocks, then disappearing the tetromino once it has reached its final position. Maybe there is some drawback to my method.
Should I create a 10x20 matrix for the main game grid which can then store? or should I use stacks or queues to somehow store the dropped blocks. Or maybe there is some better method/data structure to store things?
I am sure my way would work, but I am reaching out to see if anybody knows a better way or if my way is good enough?
P.S. Not homework, this will be a project for my portfolio. Thanks.
Once a block is immobile, there's nothing that distinguishes it from any other block that is now immobile. In that regard, I think it makes the most sense to store the entire grid as a matrix, where each square is either filled or not (along with the color of the block if it is).
I feel like the matrix has many advantages. It'll make collision detection simple (no having to compare with multiple objects, just locations on a matrix). Storing it as a matrix will also make it easier to determine when a full line has been created. On top of that, you don't have to worry about splicing an immobile Tetromino when a line disappears. And when one does, you can just shift the entire matrix down in one fell swoop.
This smells like homework, but my take on an object-oriented approach to Tetris would be to have each individual square be an object, and both "blocks" (tetrominos) and the grid itself would be collections of the same square objects.
Block objects manage the rotation and position of the falling squares, and the grid handles displaying them and detroying completed rows. Each block would have a colour or texture associated with it that would be provided by the original block object it came from, but otherwise squares at the base of the grid would have no other indication that they were ever part of the same original block.
To elaborate, when you create a new block object, it creates a set of 4 squares with the same colour/texture on the grid. The grid manages their display. So when the block hits the bottom, you just forget about the block, and the squares remain referenced by the grid.
Rotations and dropping are operations only a block need deal with, and only one its four squares (though it will need to be able to query the grid to make sure the rotation can fit).
Not making blocks actually look like autonomous blocks is - in my opinion - a big failing of many a Tetris clone. I put special effort into ensuring my clone always looked right, whether the block is still "in play" or dropped. This meant going slightly beyond the simple matrix data structure and coming up with something that supported the concept of "connection" between block parts.
I had a class called BlockGrid that is used as a base class for both a Block and the Board. BlockGrid has an abstract (pure virtual in C++) method called AreBlockPartsSameBlock that subclasses must override to determine whether two different block parts belong to the same block. For the implementation in Block, it simply returns true if there are block parts at both locations. For the implementation in Board, it returns true if both locations contain the same Block.
The BlockGrid class uses this information to "fill in" the details in the rendered blocks, so that they actually look like blocks.
Using arrays would be the easiest way to handle tetris. There is a direct correlation between what you see on screen and the structures used in memory. Using stack/queues would be an overkill and unnecessarily complicated.
You can have 2 copies of a falling block. One will be for display (Alpha) and the other one will be movement (Beta).
You will need a structure like
class FallingBlock
{
int pos_grid_x;
int pos_grid_y;
int blocks_alpha[4][4];
int blocks_beta[4][4];
function movedDown();
function rotate(int direction();
function checkCollision();
function revertToAlpha();
function copyToBeta()
};
The _beta array would be move or rotated and checked against the board for collisions. If there is a collision, revert it to _alpha, if not, copy _beta onto _alpha.
And if there is a collision on movedDown(), the block's life is over and the _alpha grid would have to copied onto the game board and the FallingBlock object deleted.
The board would of course have to be another structure like:
class Board
{
int gameBoard[10][20];
//some functions go here
}
I used int to represent a block, each value (like 1,2,3) representing a different texture or color (0 would mean an empty spot).
Once the block is part of the gameboard, it would only need a texture/color identifier to be displayed.
I actually just did this a few days ago except in WPF rather than XNA. Here's what I did:
Edit:
Seems like I define "Block" differently than other people. What I define as a Block is one of 4 cells that make up a Tetromino, and an actual Tetromino itself as a Piece.
Have a Block as a struct that had X, Y coordinates and Color. (I later added a bool IsSet to indicate whether it was in a floating piece or on the actual board, but that was just because I wanted to distinguish them visually)
As methods on Block, I had Left, Right, Down, and Rotate(Block center) which returned a new shifted Block. This allowed me to rotate or move any piece without knowing the shape or orientation of the piece.
I had a generic Piece object that had a List of all the blocks it contained and the index of the Block that was the center, which is used as the center of rotation.
I then made a PieceFactory that could produce all the different pieces, and with a Piece not needing to know what kind of piece it was, I could (and did) easily add variation of Pieces consisting of more or less than 4 Blocks without needing to create any new classes
The Board consisted of a Dictionary which was all the blocks that were currently on the board, as well as the dimensions of the board that was configurable. You can use a Matrix just as well probably, but with a Dictionary I only needed to iterate through Blocks without white spaces.
My Solution (design), with examples in Python as a good substitute for pseudo code.
Use a grid 20 x 10, that the tetrominoes fall down.
Tetrominoes are made up of blocks, which have attributes of coordinate (x,y) and colour.
So, for example, the T-shape tetrominoe looks like this...
. 4 5 6 7 8 .
.
19 # # #
20 #
.
Thus, the T-shape is a collection of blocks with the coords (5,19), (6,19), (7,19), (6,20).
Moving the shape is a matter of applying a simple transformation to all the coords in the group. e.g. to move the shape down add (0,1), left (-1,0) or right (1,0) to all coords in the collection that make the shape.
This also lets you use some simple trig to rotate the shape by 90-degrees. The rule is that when rotating 90-degrees relative to an origin, then (x,y) becomes equal to (-y,x).
Here is an example to explain it. Taking the T-shape from above, use the (6,19) as the centre block to rotate around. For simplicity, make this the first coordinate in the collection, so...
t_shape = [ [6,19], [5,19], [7,19], [6,20] ]
Then, here is a simple function to rotate that collection of coordinates by 90-degrees
def rotate( shape ):
X=0 # for selecting the X and Y coords
Y=1
# get the middle block
middle = shape[0]
# work out the coordinates of the other blocks relative to the
# middle block
rel = []
for coords in shape:
rel.append( [ coords[X]-middle[X], coords[Y]-middle[Y] ] )
# now rotate 90-degrees; x,y = -y, x
new_shape = []
for coords in rel:
new_shape.append( [ middle[X]-coords[Y], middle[Y]+coords[X] ] )
return new_shape
Now, if you apply this function to our collection of coordinate for the T-shape...
new_t_shape = rotate( t_shape )
new_t_shape
[[6, 19], [6, 18], [6, 20], [5, 19]]
Plot this out in the coordinate system and it looks like this...
. 4 5 6 7 8 .
.
18 #
19 # #
20 #
.
That was the hardest bit for me, hope this helps someone.
Keep in mind that a previous winner of the Obfuscated C Code Contest implemented a pretty good tetris game (for VT100 terminals on BSD unix) in fewer than 512 bytes of obfuscated C:
long h[4];t(){h[3]-=h[3]/3000;setitimer(0,h,0);}c,d,l,v[]={(int)t,0,2},w,s,I,K
=0,i=276,j,k,q[276],Q[276],*n=q,*m,x=17,f[]={7,-13,-12,1,8,-11,-12,-1,9,-1,1,
12,3,-13,-12,-1,12,-1,11,1,15,-1,13,1,18,-1,1,2,0,-12,-1,11,1,-12,1,13,10,-12,
1,12,11,-12,-1,1,2,-12,-1,12,13,-12,12,13,14,-11,-1,1,4,-13,-12,12,16,-11,-12,
12,17,-13,1,-1,5,-12,12,11,6,-12,12,24};u(){for(i=11;++i<264;)if((k=q[i])-Q[i]
){Q[i]=k;if(i-++I||i%12<1)printf("\033[%d;%dH",(I=i)/12,i%12*2+28);printf(
"\033[%dm "+(K-k?0:5),k);K=k;}Q[263]=c=getchar();}G(b){for(i=4;i--;)if(q[i?b+
n[i]:b])return 0;return 1;}g(b){for(i=4;i--;q[i?x+n[i]:x]=b);}main(C,V,a)char*
*V,*a;{h[3]=1000000/(l=C>1?atoi(V[1]):2);for(a=C>2?V[2]:"jkl pq";i;i--)*n++=i<
25||i%12<2?7:0;srand(getpid());system("stty cbreak -echo stop u");sigvec(14,v,
0);t();puts("\033[H\033[J");for(n=f+rand()%7*4;;g(7),u(),g(0)){if(c<0){if(G(x+
12))x+=12;else{g(7);++w;for(j=0;j<252;j=12*(j/12+1))for(;q[++j];)if(j%12==10){
for(;j%12;q[j--]=0);u();for(;--j;q[j+12]=q[j]);u();}n=f+rand()%7*4;G(x=17)||(c
=a[5]);}}if(c==*a)G(--x)||++x;if(c==a[1])n=f+4**(m=n),G(x)||(n=m);if(c==a[2])G
(++x)||--x;if(c==a[3])for(;G(x+12);++w)x+=12;if(c==a[4]||c==a[5]){s=sigblock(
8192);printf("\033[H\033[J\033[0m%d\n",w);if(c==a[5])break;for(j=264;j--;Q[j]=
0);while(getchar()-a[4]);puts("\033[H\033[J\033[7m");sigsetmask(s);}}d=popen(
"stty -cbreak echo stop \023;cat - HI|sort -rn|head -20>/tmp/$$;mv /tmp/$$ HI\
;cat HI","w");fprintf(d,"%4d on level %1d by %s\n",w,l,getlogin());pclose(d);}
http://www.ioccc.org/1989/tromp.hint
I'm by no means a Tetris expert, but as you described a 10x20 matrix seems like a natural choice to me.
It will make it very easy when the time comes to check if you have completed a line or not, and dealing with it. Simply iterating over the 2d-array looking at boolean values of each position to see if they add up to 10 block positions.
However, you'll have some manual clean up to do if there is a completed line. Having to shift everything down. All though it isn't that big of a deal when it comes down to it.
Using Simon Peverett logic, here is what I ended up with in c#
public class Tetromino
{
// Block is composed of a Point called Position and the color
public Block[] Blocks { get; protected internal set; }
// Constructors, etc.
// Rotate the tetromino by 90 degrees, clock-wise
public void Rotate()
{
Point middle = Blocks[0].Position;
List<Point> rel = new List<Point>();
foreach (Block b in Blocks)
rel.Add(new Point(b.Position.x - middle.x, b.Position.y - middle.y));
List<Block> shape = new List<Block>();
foreach (Point p in rel)
shape.Add(new Block(middle.x - p.y, middle.y + p.x));
Blocks = shape.ToArray();
}
public void Translate(Point p)
{
// Block Translation: Position+= p;
foreach (Block b in Blocks)
b.Translate(p);
}
}
Note: Using XNA, Point structure could be swapped for Vector2D
in my example (Java) - all figures have lists of blocks - which can be removed whenever needed. Also in my Board class I have a list of figures and a field variable figure - which is controlled by the user. When the figure is "landed" - it goes into the list of other figures, and a new figure is made controllable by the user.
A better explanation here: http://bordiani.wordpress.com/2014/10/20/tetris-in-java-part-i-overview/

Categories

Resources