Triangle strip does not show properly with OpenGL - c++

I implemented a function in C++ to generate a N segments for a triangle strip (2 x N triangles) to be printed later (as GL_TRIANGLE_STRIP) by another function. Here I show you what I've got so far:
void strip(
std::uint32_t N,
std::vector<glm::vec3>* vertices)
{
vertices->clear();
for (std::uint32_t j=0; j<=N; ++j)
{
for (std::uint32_t i=1; i<=N; ++i)
{
float x = (float)i/(float)N;
float y = (float)j/(float)N;
vertices->push_back(glm::vec3(x, y, 0));
}
}
}
So it would be seem like the following figure (For N = 3):
^
| ----------
| | /| /| /|
y | |/ |/ |/ |
| ----------
|
|-------------->
x
But in fact it appears like this:
Any advice about it? My thoughts is that I'm not generating the points in the correct order.

Your logic is not good to generate a strip of triangles. Let me try to explain mine:
^
| 0--2--4--6
| | /| /| /|
y | |/ |/ |/ |
| 1--3--5--7
|
|-------------->
x
As you can, triangle 0 is composed of vertices 0, 1 and 2, while triangle 1 is composed by vertices 1, 2 and 3, and so on. So, to generate this strip, you need to generate the odd indices in a row, and the even indices in another row. Let us try with code, generating, in this case, vertices:
void strip(std::uint32_t N, std::vector<glm::vec3>* vertices)
{
vertices->clear();
for (std::uint32_t j=0; j < N + 1; ++j)
{
float x = (float)j/(float)N;
vertices->push_back(glm::vec3(x, 1, 0)); // even row
vertices->push_back(glm::vec3(x, 0, 0)); // odd row
}
}

A triangle strip with the vertices A,B,C,D,E,... will form the triangles ABC, BCD, CDE, and so on.
My thoughts is that I'm not generating the points in the correct order.
Yes. What you generate is
0 1 2 3
4 5 6 7
8 9 10 11
So you're getting lots of deformed triangles with no area at all, and only get some weird triangles connecting the different lines (like 2 3 4 and 3 4 5).
What you should generate is
0 2 4 6
1 3 5 7
Note that when you add an additional row, you will have to repeat the bottom vertices from the previous row as the top vertices of the new row. ALso note that you have to re-start the triangle strip for each row.
A more efficient approach could be that you generate the vertices just as you are now, and look into indexed rendering, which will allow you to just re-use the vertices between different primitives.

Related

What is the purpose of using (n/8) and (n*7/8) in the lines of the C++ code below?

I'm working on the C++ code of the A-star algorithm and the code in this link:
http://code.activestate.com/recipes/577457-a-star-shortest-path-algorithm/
// fillout the map matrix with a '+' pattern
for(int x=n/8;x<n*7/8;x++)
{
map[x][m/2]=1;
}
for(int y=m/8;y<m*7/8;y++)
{
map[n/2][y]=1;
}
Those are just numerical values. If you think about that 2D map as of linear 2D space, n/8 and n*7/8 will give you 1/8th and 7/8th of he space, respectively. E.g. for a map sized 8x8, the result will look like this:
01234567 n
0 ........
1 ....1... ---\ starts at m/8
2 ....1... |
3 ....1... |
4 .111111. |
5 ....1... |
6 ....1... ---/ ends at one less than m*7/8
7 ........
m \-------- positioned at n/2
Since n == m == 8, n/8 = 1, and n*7/8 == 7 (but the loop is specified to end 1 before 7).

3D to 1D mapping function confusion

I just finished coding a C++ program to manage a 3D matrix with dynamically allocated memory.
In order to use a contiguous chunk of memory, I decided to use a mapping function to physically store the elements of my matrix to 1D array.
For this purpose, I have a T *_3D_matrix pointer to the array, which is defined as
_3D_matrix = new T[height * width * depth];
where height, width and depth are input parameters for the constructor.
The program works just fine, I even tested it with Valgrind and no memory problems happen.
What I don't get is: my array has got height * width * depth = 12 elements, and the mapping function seems to map some elements out of the [0..11] range.
What am I missing here?
EDIT:
This is the output I get from recreating the same matrix and printing it in my program.
Lets say we have a "3D" array defined as
some_type m[1][3][2];
That would look something like this if we draw it:
+------------+-------------+------------+-------------+------------+------------+
| m[0] |
+------------+-------------+------------+-------------+------------+------------+
| m[0][0] | m[0][1] | m[0][2] |
+------------+-------------+------------+-------------+------------+------------+
| m[0][0][0] | m[0][0][1] | m[0][1][0] | m[0][1][1] | m[0][2][0] | m[0][2][1] |
+------------+-------------+------------+-------------+------------+------------+
If x represents the first "dimension", y the second, and z the third, then an expressions such as m[x][y][z] would with a flat array be like m[x * 3 * 2 + y * 3 + z]. The number 3 is the number of elements in the second dimension, and 2 is the number of elements in the third dimension.
Generalized, an array like
some_type m[X][Y][Z];
would as a flat array have the formula x * Y * Z + y * Z + z for the index. Compared to your formula the x and the y have been switched.
You computed the mapped index for out-of-bounds values of y.
You said height * width * depth= 12, and:
index = y * width * depth + x * depth + z
And we see in your table:
#.| Y | X | Z | index
--+---+---+---+------
1 | 0 | 1 | 0 | 2
2 | 1 | 0 | 0 | 6
This implies:
0 * width * depth + 1 * depth + 0 = 2 => depth = 2
1 * width * depth + 0 * depth + 0 = 6 => width * depth + 6 => width = 3
height * width * depth= 12 => height = 2
Thus:
y is in [0, 1]
x is in [0, 2]
z is in [0, 1]
The maximum index is at {x, y, z} = {2, 1, 1} and its value is 1 * 2 * 3 + 2 * 2 + 1 = 11.
Assuming from your example:
width = 2, height = 3, and depth = 2
x is in [0, width), y is in [0, height), z is in [0, depth)
Mapping second element should be:
1*2*2 + 0*2 + 0 = 4, but you get 6. I think the reason is that some of the dimensions or indices are swapped somewhere else in your code. Seems that width or depth is 3 in your case.

What is the significance of initializing direction arrays below with given values when developing chess program?

I am new to competitive programming, and I noticed frequently, many of the great coders have these four lines in their code (particularly in those involving arrays):
int di[] = { 1, -1, 0, 0, 1, -1, 1, -1 };
int dj[] = { 0, 0, 1, -1, 1, -1, -1, 1 };
int diK[] = { -2, -2, -1, 1, 2, 2, 1, -1 };
int djK[] = { -1, 1, 2, 2, 1, -1, -2, -2 };
What does this really signify and what is technique used for?
This is a technique to encode all directions as arrays - every pair of di[i],dj[i] is a different direction.
If we imagine we have a piece at a location x,y, and we want to add onto its x and its y value to move it to a nearby location, 1,0 is east, -1,0 is west, 0,1 is south, 0,-1 is north and so on.
(Here I have said top left is 0,0 and bottom right is 4,4 and shown what move each index of the arrays will make from the central point, X, at 2,2.)
.....
.536.
.1X0.
.724.
.....
The way it is set up, if you do ^1 (^ being bitwise XOR) on the index you get the opposite direction - 0 and 1 are opposites, 2 and 3 are opposites and so on. (Another way to set it up is to go clockwise starting at north - then ^4 gets you the opposite direction.)
Now you can test all directions from a given point by looping over your di and dj arrays, instead of needing to write out each direction on its own line (for eight in total!) (Just don't forget to do bounds checking :) )
diK and djK form all knights directions instead of all adjacent directions. Here, ^1 will flip along one axis, ^4 will give the opposite knight leap.
.7.6.
0...5
..K..
1...4
.2.3.
For those finding Patashu's explanation difficult to follow, I'll attempt to clarify.
Imagine you are trying to consider every possible move from a given point on a chess board.
If you loop over the di and dj arrays, interpreting the di values as x offsets and the dj values as y offsets, you cover each of the possible 8 directions.
Assuming positive x is east and positive y is south (as in Patashu's answer), you get the following;
| di/x | dj/y | Direction
--+------+------+-----------
0 | 1 | 0 | east
1 | -1 | 0 | west
2 | 0 | 1 | south
3 | 0 | -1 | north
4 | 1 | 1 | south-east
5 | -1 | -1 | north-west
6 | 1 | -1 | north-east
7 | -1 | 1 | south-west
The diK and djK arrays can be interpreted the same way to establish the possible moves for the Knight piece. If you're not familiar with chess, the Knight moves in an L pattern - two squares in one direction, and then one square at right angles to that (or vice versa).
| diK/x | djK/y | Direction
--+-------+-------+----------------
0 | -2 | -1 | 2 west, 1 north
1 | -2 | 1 | 2 west, 1 south
2 | -1 | 2 | 1 west, 2 south
3 | 1 | 2 | 1 east, 2 south
4 | 2 | 1 | 2 east, 1 south
5 | 2 | -1 | 2 east, 1 north
6 | 1 | -2 | 1 east, 2 north
7 | -1 | -2 | 1 west, 2 north
A small snippet of code to check the amount of moves possible in all directions, which uses the defined arrays.
int di[] = { 1, -1, 0, 0, 1, -1, 1, -1 };
int dj[] = { 0, 0, 1, -1, 1, -1, -1, 1 };
int movesPossible[8];
int move = 0;
int posx, posy; // position of the figure we are checking
for (int d=0; d<8; d++) {
for (move = 1; board.getElt(posx+di[d]*move, posy+dj[d]*move)==EMPTY; move++) ;
movesPossible[d] = move-1;
}

SDL Coordinate System, from (0,0) to (w,h) or (w-1, h-1)?

I have been learning OpenGL and SDL lately and I've become rather confused about the coordinate system in SDL and glOrtho. I've read a few tutorials about the SDL's coordinate system that says the coordinates go from (0,0) to (w, h) which does not make sense to me. If if the width goes from 0 to w then that means there is one extra pixel.
Also, with the OpenGL glOrtho function, I've seen all examples where the coordinate system is changed to one that's similar to SDL take the following form:
glOrtho (0, screenWidth, screenHeight, 0, 1, -1);
However doesn't it make more sense to make it this instead?:
glOrtho (0, screenWidth-1, screenHeight-1, 0, 1, -1);
Hope you guys can clarify this for me, thanks.
Kind of the same confusion like the beginning of the new millenia. I'll try to explain:
Take some piece of grid-ruled paper and mark some grid crossing as your origin, i.e. 0,0 coordinate. Measure a width of, say 9 grid units in one direction, mark it. Now count the number of cells you measured. Let me illustrate:
0 1 2 3 4 5 6 7 8 9 <- grid lines; coordinate range
| | | | | | | | | |
| | | | | | | | | |
| | | | | | | | | |
|0|1|2|3|4|5|6|7|8| <- cell index/offset
So you've got a grid of width 9, but there are only 9-1=8 cells (e.g. pixels) within. The ranges you give to glOrtho are the limits of the range.

Calculating a boundary around several linked rectangles

I am working on a project where I need to create a boundary around a group of rectangles.
Let's use this picture as an example of what I want to accomplish.
EDIT: Couldn't get the image tag to work properly, so here is the full link:
http://www.flickr.com/photos/21093416#N04/3029621742/
We have rectangles A and C who are linked by a special link rectangle B. You could think of this as two nodes in a graph (A,C) and the edge between them (B). That means the rectangles have pointers to each other in the following manner: A->B, A<-B->C, C->B
Each rectangle has four vertices stored in an array where index 0 is bottom left, and index 3 is bottom right.
I want to "traverse" this linked structure and calculate the vertices making up the boundary (red line) around it. I already have some small ideas around how to accomplish this, but want to know if some of you more mathematically inclined have some neat tricks up your sleeves.
The reason I post this here is just that someone might have solved a similar problem before, and have some ideas I could use. I don't expect anyone to sit down and think this through long and hard. I'm going to work on a solution in parallell as I wait for answers.
Any input is greatly appreciated.
Using the example, where rectangles are perpendicular to each other and can therefore be presented by four values (two x coordinates and two y coordinates):
1 2 3 4 5 6
1 +---+---+
| |
2 + A +---+---+
| | B |
3 + + +---+---+
| | | | |
4 +---+---+---+---+ +
| |
5 + C +
| |
6 +---+---+
1) collect all the x coordinates (both left and right) into a list, then sort it and remove duplicates
1 3 4 5 6
2) collect all the y coordinates (both top and bottom) into a list, then sort it and remove duplicates
1 2 3 4 6
3) create a 2D array by number of gaps between the unique x coordinates * number of gaps between the unique y coordinates. It only needs to be one bit per cell, so in c++ a vector<bool> with likely give you a very memory-efficient version of this
4 * 4
4) paint all the rectangles into this grid
1 3 4 5 6
1 +---+
| 1 | 0 0 0
2 +---+---+---+
| 1 | 1 | 1 | 0
3 +---+---+---+---+
| 1 | 1 | 1 | 1 |
4 +---+---+---+---+
0 0 | 1 | 1 |
6 +---+---+
5) for each cell in the grid, for each edge, if the cell beside it in that cardinal direction is not painted, draw the boundary line for that edge
In the question, the rectangles are described as being four vectors where each represents a corner. If each rectangle can be at arbitrary and different rotation from others, then the approach I've outlined above won't work. The problem of finding the path around a complex polygon is regularly solved by vector graphics rasterizers, and a good approach to solving the problem is using a library such as Cairo to do the work for you!
The generalized solution to this problem is to implement boolean operations in terms of a scanline. You can find a brief discussion here to get you started. From the text:
"The basis of the boolean algorithms is scanlines. For the basic principles the book: Computational Geometry an Introduction by Franco P. Preparata and Michael Ian Shamos is very good."
I own this book, though it's at the office now, so I can't look up the page numbers you should read, though chapter 8, on the geometry of rectangles is probably the best starting point.
Calculate the sum of the boundaries of all 3 rectangles seperately
calculate the overlapping rectangle of A and B, and subtract it from the sum
Do the same for the overlapping rectangle of B and C
(to get the overlapping rectangle from A and B take the middle 2 X positions, together with the middle 2 Y positions)
Example (x1,y1) - (x2,y2):
Rectangle A: (1,1) - (3,4)
Rectangle B: (3,2) - (5,4)
Rectangle C: (4,3) - (6,6)
Calculation:
10 + 8 + 10 = 28
X coords ordered = 1,3,3,5 middle two are 3 and 3
Y coords ordered = 1,2,4,4 middle two are 2 and 4
so: (3,2) - (3,4) : boundery = 4
X coords ordered = 3,4,5,6 middle two are 4 and 5
Y coords ordered = 2,3,4,6 middle two are 3 and 4
so: (4,3) - (5,4) : boundery = 4
28 - 4 - 4 = 20
This is my example visualized:
1 2 3 4 5 6
1 +---+---+
| |
2 + A +---+---+
| | B |
3 + + +---+---+
| | | | |
4 +---+---+---+---+ +
| |
5 + C +
| |
6 +---+---+
A simple trick should be:
Create a region from the first rectangle
Add the other rectangles to the region
Get the boundary of the region (somehow? :P)
After some thinking I might end up doing something like this:
Pseudo code:
LinkRectsConnectedTo(Rectangle rectangle,Edge startEdge) // Edge can be West,North,East,South
for each edge in rectangle starting with the edge facing last rectangle
add vertices in the edge to the final boundary polygon
if edge is connected to another rectangle
if edge not equals startEdge
recursively call LinkRectsConnectedTo(rectangle,startEdge)
Obvisouly this pseudo code would have to be refined a bit and might not cover all cases, but I think I might have solved my own problem.
I haven't thought this out completely, but I wonder if you couldn't do something like:
Make a list of all the edges.
Get all the edges where P1.X = P2.X
In that list, get the pairs where X are equal
For each pair, replace with one or two edges for the parts where they DON'T overlap
Do something clever to get the edges in the right order
Will your rectangles always be horizontally aligned, if not you'd need to do the same thing but for Y too?
And are they always guaranteed to be touching? If not the algorithm wouldn't be broken, but the 'right order' wouldn't be definable.