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.
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.
Let there be a vertex which is part of a triangle, and of a quad.
To my best understanding, the normal of that vertex is the average of the normal of the quad and the normal of the triangle.
The triangle is drawn before the quad. When should I call glNormal and with what vector?
Should I call glNormal 2 times, each time with the same vector (the average normal vector)?
Should I call glNormal the last time the vertex is drawn, with the average normal vector?
To my best understanding, the normal of that vertex is the average of
the normal of the quad and the normal of the triangle.
Ideally, the normal vector should be orthogonal to the surface that you are rendering, on any point. However, the GL only supports rendering surfaces only as polygonal models (at least directly). So there are two principal possibilities:
The polygonal representation does exactly represent the object you want to visualize. A simple example would be a cube.
The polygonal represantation is just an (picewise linear) approximation of the surface you want to visualize. Think of smooth surfaces.
In case 1, you need one nomral per triangle (as the normal is unchaning for a flat surface defined by a triangle). However, this means that either for neighboring triangles who share an edge or corner, the normals will have to be different. From GL's point of view, each of the trianlges use different vertices, even if those vertices share the position in space. A vertex is the set of all attributes, not just the position. For the cube, that means that you will need not just 8 different vertices, but 24, so you have 3 at each corner.
In case 2, you do want to cover up the polygonal structure of the model as good as possible. One aspect of this is using smooth shading techniques. Averaging the normales of adjacent traingles at each vertex is one heuristic of doing so. In this case, neighboring primitives actually can share vertices, as the normal and the position of some corner point is the same for any triangle connected to it.
This heuristic has some drawbacks, especially if your surface does contain both smooth parts and "sharp edges" you want to preserve. There are some improved heuristics which try to detect sharp edges and splitting vertices to allow different normals for the connected triangles to not shooth such edges. But all such heuristics might fail in some cases - ideally, the normals are provided when the model is created in the first place.
The triangle is drawn before the quad. When should I call glNormal and
with what vector?
OpenGL is a state machine, meaning that things you set kepp that way until you channge them again - and setting normals is no exception. The second thing to note is that normals are a vertex attribute. So for every vertex, every arrtibute has always some value (but depending on the rest of your GL state, not all of these attributes are used when rendering).
Since you use the fixed-function GL, normals are builtin vertex attributes - so every vertex you issue in some way has some value as its normal attribute - in immediate mode rendering with glBegin()/End(), it will be the one you set with the most recent glNormal() call (or it will have the initial default value if you never called glNormal()).
So to answer you question:
YOu have to set that normal before you issue the glVertex() call for that particular vertex for the first time, and you have to re-issue that normal command for the second time drawing with "this" vertex (which technically is a different vertex anyway) if you did change it inbetween when specifying some other vertices.
To my best understanding, the normal of that vertex is the average of the normal of the quad and the normal of the triangle.
No. The normal of a plane is a vector pointing 'out of' the plane at a 90 degree angle. In OpenGL, this is used in shading calculations, and to support various effects, OpenGL lets you specify whatever normal you want instead of calculating it from the primitive. For flat lighting, the normal should be set to the mathematical definition of the normal for each primitive, while for smooth lighting, the normal should be set to the average normal of all primitives that share the vertex.
glNormal sets a value in OpenGL that is read whenever you call glVertex, and is persistent until you call glNormal again. So this code
glNormal3d(0,0,1)
glVertex3d(1,0,0)
glVertex3d(1,1,0)
glVertex3d(0,1,0)
glVertex3d(0,0,0)
specifies 4 vertices, each with a normal of (0,0,1).
I'm writing the class for storing, loading and rendering the static mesh in my DirectX application.
I know that Box model can uses 8 vertices, but usually it uses 24 or 36 (because one "vertex in space" is de facto 3 vertices with the same positions and different texture coord/normals).
My question is: how about meshes (e.g. character mesh exported from 3ds max or similar application)?
I'm working on the exporter plug-in now for my application. Should I:
For each vertex in mesh, exports it (as position, normal, texture coordinates) - will it be enough always/for some cases?
or maybe:
For each face, export 3 vertices (pos, normal, tex coord)
?
I'm not sure if the texture coordinates/normals will be different for the same "vertex" in 3ds max (same position but different normals/tex coord?).
The second aprouch should works fine with D3DPT_TRIANGLELIST, but for 5.000 vertices mesh from 3ds max I will get 15.000 "real" vertices (+/- each 3 will have same pos and different tex coord/normals).
Also, on the example below, the object consists of two parts - top one has #1 smoothing group and bottom one has #2 smoothing group -will my problem looks different for vertex "inside" smoothing group and between two groups (e.g. connection of top/bottom)?
In other words: is the black circled "vertex" one "real" vertex with same pos/tex coord/normals or it's 4 vertices with same positions only (4 vertices with same everything makes sense?)?
And what about red one?
I'm using indexed buffers.
Exporting three vertices for each triangle is always sufficient, but may involve duplicating data unnecessarily. If adjacent triangles have disjoint texture coordinates or other properties, you must duplicate in order to produce correct rendering results. If you want, you can merge duplicate vertices in a post-processing step.
Regarding your reference images, it doesn't look like there is any texture applied to the surface, so the red circled vertex must be two distinct vertices in the buffer in order to create the color discontinuity, as it should be. The black circled vertex doesn't need to be, but it still may be duplicated. In general, you should share vertices within a smoothing group, and not worry about deduplicating across groups. If vertex throughput ends up being an issue, you can look into optimizing it, but for most workloads you'll be pixel or fillrate bound.
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.
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.