I need an example of a polygon that can be done only by GL_TRIANGLE_STRIP and another polygon that can be done only by GL_TRIANGLE_FAN.
When knowing the difference between Triangle Strip and Triangle Fan a shape will be easy to make.
Triangle Strip
For instance a Triangle Strip is a set of connected triangles which share vertices.
Example of Triangle Strip
Using Triangle Strip we will be able to get the following output, using those given vertices.
Triangle Fan
Where a Triangle Fan is also a set of connected triangles, though all these triangles have a common vertex, which is the central vertex.
In OpenGL the central vertex is the first given vertex, in the Triangle Fan.
Example of Triangle Fan
Using Triangle Fan and the same vertices as in the other example, we will only be able to get the colored area as output. That is due to the importance of the arranged order of the vertices in Triangle Fan. Basically, all the vertices need to go around the central vertex.
Conclusion
As you can see on our 2 example sets of vertices those "output shapes" are unique to both Triangle Strip and Triangle Fan.
Note: The image examples uses clockwise winding order, while in OpenGL the front side uses counter-clockwise winding order, i.e. the examples are literally facing away from the camera. This is an important detail if face culling is enabled.
Extra
I made a similar answer here, you can read it if you want, I actually used the same images since the questions are closely related.
Difficult to answer in pure text. For Fan, an S shape would be impossible (in general, remember that fan is limited in that there is a point common to every triangle).
As for the other way around - it's a trick question. triangle_strip can do every triangle_fan polygon, although it requires a little trickery.
Consider the following polygon (ordering shown is for triangle_fan)
3--4--5
|\ | /|
2--1--6
| \|
8--7
This could be done as follows
2-----4
| \ /|
1--3/7|
| \|
6--5
Note the overlapping polygons. If you don't allow double-sided polys or overlap, then this would be an example of a fan only poly, I suppose.
Related
I have created a regular grid which originates from a 2D image, i.e. each pixels has a vertex. There are two triangles per four pixels so that I have a triangle in the top right and in the bottom left. I use vertex and index buffers for that.
Now I dynamically remove triangles / faces at the border of two different kinds of vertices (according to my application) because else there would be distortions. I wrote a geometry shader which takes a triangle and outputs the triangle or nothing (see first picture). The shader recognizes if a triangle is "faulty" (has orange edges) and omits it.
Now this works fine, but I may lose some details because of my vertex geometry. I can add complementary triangles to the mesh (see second picture, new triangles with dashed orange line).
How do I accomplish this in OpenGL?
My first idea is to create one quad instead of two triangles, check for the four possible triangles cases and create those triangles dynamically in the geometry shader. But this might be slow; GL_QUADs are deprecated and alternatives might be slow too. What do you have in mind?
Here's my idea:
Put the whole grid in a buffer/texture.
Build four triangles for each four pixels. They cross each other, yes.
In the geometry shader you can tell if a triangle is "faulty" because it connects two wrong regions. Or, sampling form the texture, because the crossing triangle is valid, so this new one can be discarded.
EDIT: Another approach
Use the texture. Draw instanced with GL_POINTS. With some order and the help of the instanceID the shader knows where the point is.
For this point test the four possible triangles. If you instance top to down and left to right, only a point to the right and the two below are used for the four triangles. And you avoid repeating tests.
Emit only those you choose.
I am learning openGL, and i have come across triangle fans using vertex buffer objects. If given an array of vertices to render, how does openGL decide how many of those vertices must be used to construct a triangle fan. It seems like an arbitray number of the vertices could be used.
This can easily be explained by comparing Triangle Strips with Triangle Fans.
Triangle Strip
As you probably know, a Triangle Strip is a set connected triangles which share vertices, this allows for more efficient memory usage. (We save memory because we don't store all duplicated vertices)
Example of a Triangle Strip
Triangle Fan
On the other hand we have a Triangle Fan, this is also a set of connected triangles. Though all these triangles have one vertex in common, which is the central vertex. (The first vertex is always the center)
With that said we can take the same image above and change the order of the vertices. When that done the Triangle Fan would look like this. (Where A, is the first and central vertex)
Example of a Triangle Fan
In the image above the Triangle Fan will only work in the colored area, because of how the vertices need to be arranged according to be a Triangle Fan.
Visually, this is how a triangle fan works:
Each triangle shares the central vertex A, and re-uses the last vertex addressed. Thus after defining ABC each following triangle only requires 1 point (e.g. D, E, F).
Indices: A,B,C,D,E,F [Count: 6]
Triangles: (A,B,C)
(A) (C,D)
(A) (D,E)
(A) (E,F) [N=4] --> 4+2 = 6
Another way of thinking about this is that each triangle shares an edge radiating from a central vertex with the prior triangle; literally like a folding a paper fan.
You need N+2 vertices, where N is the number of triangles in your fan.
Look here: GL_TRIANGLE FAN Explanation
The more vertices you give to openGL, the more triangles you get. The first vertex will be common to all triangles. First triangle consists of the vertices 1, 2 and 3. Second triangle consists of 1, 3 and 4. And so on.
You get n - 2 triangles for n vertices.
That is specified by the command which you use to do the rendering. For example both drawArrays() and drawElements() have a count parameter which specifies the number of vertices to use.
If one puts the same vertex A into a triangle strip several times, then takes another vertex B and puts this one several times into the triangle strip also (the amount depending on the triangle orientation one wants to continue with), then one effectively can have two separate triangle strips to be rendered with only one draw call (the first containing all triangles before vertex A and the second consisting of all triangles after vertex B).
My question:
I am afraid, even though the complete triangle strip draw call will draw a geometrically simply connected mesh, I will encounter problems when attempting to texture the mesh due to the jumps in between. I am not quite there yet, so I cannot test it. Is my assumption correct?
Is my jumping in the triangle strip at any rate a valid technique in the "drawing meshes" industry? Is there any way to texture the result appropriately, or an equivalent better behaving alternative to the jumping?
Consider a 'mesh' consisting of a triangle subdivided into 4 similar triangles:
2
/\
/ \
1 /____\3
/\ /\
/ \ / \
0 /____\/4___\5
Assume CCW (glFrontFace) winding, the triangles: {0,4,1}, {1,4,3}, {3,2,1} are encoded as a strip: {0,4,1,3,2}. The trick is adding the triangle: {4,5,3} by adding degenerate (zero-area) triangles, while maintaining the correct winding. In short:
{0,4,1,3,2,2,3,3,5,4}, adds the zero-area triangles: {3,2,2}, {2,2,3}, {3,3,5}.
This adds a negligible amount of extra geometry for a larger mesh, provided that efficient mesh striping is used.
Rasterizers draw the area of a triangle. A "triangle" that has two points that are the same has no area. Therefore, there is no area of the triangle to render.
Degenerate triangles (the technical term for triangles where two of the points are the same) are a common technique for connecting multiple strips. This is typically done in the index array by just adding more indices; nothing about the actual topology of the mesh needs to change.
If I've got 4 vertices which I render in this order:
2-3
|\|
0-1
using GL_TRIANGLE_STRIP and then I enable back-face culling with the front face defined as CCW, then would the bottom-left triangle be facing me and the other one not? If so, what's the most efficient way of rendering a square so that both faces are visible? Do I have to use GL_TRIANGLES and pass down 6 vertices instead of 4?
The strip primitive does the right thing with respect to backface culling. You can think of the tris' winding order as being managed so that the order is consistent for each triangle in the strip - e.g. you can think of the GPU rendering (0,1,2), (2,1,3) ...
All triangles in triangle strip maintain same direction/winding order.
They don't flip one after another. So either both triangles will be towards you or away from you (assuming your primitive is flat square shape (that is convex and doesn't intersect itself) where all vertices belong to same plane).
P.S. You know, you COULD render trianglestrip primitive in OpenGL application with culling enabled and see for yourself.
I am new to openGL and I am reading the redbook. Now, as an exercise I want to manually draw a sphere. For that I am dividing the sphere into slices and stacks, and thus I get multiple rectangles, but near the poles of the sphere I get triangles. (hope this was clear what I am doing). Now I know that if you draw a polygon with GL_POLYGON and it happens to intersect itself, the behavior is undefined. My question is this: given three points v1, v2, v3 which are not on one line, is it undefined behavior to do this:
glBegin(GL_POLYGON)
vertex v1
vertex v1
vertex v2
vertex v3
glEnd();
This may be combining two unrelated questions into one, but I am wondering also this: if I choose to divide the rectangles in my sphere routine into triangles, does it matter how I do it, that is, by which diagonal I divide the rect into two triangles? I am guessing that for drawing a single-colored sphere it won't matter, but I don't know about textures, shaders, lighting etc.
When I was doing openGL stuff, I quickly stuck to using just triangles. They are special in that a triangle is not ambiguous in any way.
You example though, I would imagine this will work, though probably with artefacts.
how you split a rectangle shouldn't matter, just as long as you pay attention to which way your triangles are wound, which way you define the points as this is what dictates their front and back.
But definitely stick to triangles, images these four points of a square
(0,0,0) (1,0,0) (1,0,1) (0,0,1)
Fairly easy to see it is a flat square, but what if I change them to
(0,1,0) (1,0,0) (1,1,1) (0,0,1)
what do you have now? it could be drawn like a valley or like a hill. if I defined this shape with triangles, you know exactly what I am describing
(0,1,0) (1,0,0) (1,1,1)
(1,1,1) (1,0,1) (0,1,0)
A hill like shape
ok... so I side tracked a little here... my point is, I don't know what your code would do in practice, but I don't think you should use it any way. and how you split up rectangles shouldn't matter as long as your triangles are described the right way around.
This is no problem whatsoever. OpenGL always has to be able to deal with the possibility of rasterising geometry where multiple vertices fall in the same location since even different input points may end up as the same output point depending on your modelview and projection matrices (or your geometry and/or vertex shader if you're on the programmable pipeline). It is designed to deal in the mathematically correct way under a wide variety of edge cases.
OpenGL's primary test for whether to paint a pixel with geometry is whether its centre falls within the mathematical bounds of the primitive being drawn*. So OpenGL can render polygons that paint non-continuous sets of pixels (which generally happens when they become almost vanishingly thin) or that paint no pixels whatsoever (which tends to be when they end up really small, but they may technically be of arbitrarily large size as long as they squeeze between pixel centres).
The exact tests used at the hardware level may vary from vendor to vendor and are guaranteed to be correct only for geometry that is convex on screen — which is why most people say stick to triangles, since they're unavoidably convex.
(*) a separate screen-oriented test being applied to pixels exactly on a boundary to ensure they're attributed to only exactly one polygon where polygons meet along a common edge