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.
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.
Suppose I have a triangle (3 vertices). I add a fourth vertex.I use GL_TRIANGLE_STRIP. Can I specify which two vertices of the original triangle should my new triangle share ?
No. A triangle strip is always built from the previous two vertices.
I am developing a real world application that is to render solid white polygons on the screen, and change their alpha values as time passes. I am trying to learn how to use GLTriangleBatch to perform this (I know C++ well, but not so much about OpenGL), and have not been able to find any good examples online. So far, I have found a few resources that led me to put together the following bit of code, but I am still confused on some portions:
GLTriangleBatch myTriangles;
myTriangles.BeginMesh(1000000); // Include how many vertices you have: 1???
myTriangles.AddTriangle(...); // Add a triangle: 2???
// Repeat for all triangles for this batch
myTriangles.End(); // Done adding triangles
myTriangles.Draw(); // Draw the triangles
I have marked the portions I am confused on with ???, and the questions appear below:
Question 1: Does this number of vertices have to be exact, or is it okay to over-estimate and / or underestimate? Furthermore, does this number of vertices represent the "batched" vertices, or the individual vertices of each triangle (e.g. would 2 connected triangles with 2 shared vertices require 6 vertices or 4?)
Question 2: The paramaters are:
M3DVector3f verts[3]: I assume the 3 vertices of the triangle
M3DVector3f vNorms: What is this, and how do I set it up?
M3DVector2f vTexCoords[3]: I assume this is something to do with texture, all I want is a white triangle, and to be able to vary the alpha value of it. How would I set this up?
This GLTriangleBatch class apparently is part of a framework provided with the OpenGL Super Bible book. It is not part of the OpenGL standard (OpenGL is a plain C API).
As for the first question, I assume the nMaxVerts parameter of BeginMesh() is the upper limit of vertexes you want to draw (each triangle = 3 verts). So you can set this to either an exact value or an over-estimate. But you'd have to find some documentation or look at the source to know for sure.
For the second question, yes verts[3] are the three positions that make the triangle.
vNorms is the Face Normal of the triangle. It is used for lighting calculation. And the last member, vTexCoords[3] are the Texture Coordinates of the triangle. These are used for texture mapping. You can set them to zero if you are not applying texture to your mesh.
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.
I have a triangle mesh and I'm trying to calculate the normals so I can apply them when drawing the mesh. I'm using immediate mode (will probably change to vertex arrays when I get time to understand how they work) and drawing the mesh with GL_TRIANGLE_STRIP.
I am having trouble calculating the vertex normals. More precisely deciding which neighbouring vertices to use in the calculations and then deciding when to set those normals. Consider this:
1_2
|/| Supposedly a square where the numbers represent the vertex number in a
3 4 triangle strip.
I know you have to compute the cross product of 2 vectors belonging to a plane in order to get the plane normal. So in that example the top triangle's normal could be calculated by doing (2-1)x(3-1), and the second one by doing (2-4)x(3-4). How do you then apply the normals when drawing the triangle strip in immediate mode?
What I was doing was setting the first normal when vtx 1 is set, the second when vtx 4 is set, the third when vtx 5 is set, etc. This however gives issues as you obviously end up by having different normals for each of the vertices of a triangle (when they should all be the same). For instance, triangle |2,3,4| would only have vertex 4 with the correct normal (since for vertices 2 and 3 the normal would be the one of the first triangle).
So how should it be done? Is there a way, or do I need to change to GL_TRIANGLES? (I don't want to stop using immediate mode for now as I don't have time).
If I'm correct you're still only computing a normal per triangle? This is correct, but after that you should computed what the normal is per vertex. This is simply the normalized sum of all triangle normals that the specific vertex is attached to.
Once completed you can proceed with your immediate mode drawing, specifying a normal per vertex.