Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL triangle adjacency indexing

Tags:

c++

c

opengl

I am currently trying to write a program which takes a mesh as input (consisting of vertex positions and an element array) and outputs indices for use with glDrawElements() in GL_TRIANGLES_ADJACENCY mode.

It occurred to me when trying to write the code that non-closed meshes have triangles which may not have three neighbours. For example, a mesh consisting of a single triangle has no neighbouring triangles.

Triangle adjacency diagram from OpenGL 4.3 spec.

In this case, what should the indices 2, 4 and 6 be? It seems like there should be a standard way to tell the geometry shader that one or more of the adjoining triangles do not exist. I could not find information on this in the OpenGL specification (v4.3), however.

The single triangle is a daft example, but there are plenty of meshes where not all triangles join onto three others - like a cylinder with open ends, for example.

Is there a standard way to handle cases like this? Apologies if I have missed something obvious in the spec.

Above image copied from the OpenGL 4.3 specification.

like image 638
Kaathe Avatar asked Sep 26 '13 19:09

Kaathe


People also ask

How does GL triangles work?

Draws triangles using each set of 3 vertices passed. If you pass 3 vertices, one triangle is drawn, where each vertex becomes one corner of the triangle. If you pass 6 vertices, 2 triangles will be drawn. To set up the screen for drawing in 2D, use GL.

How GL_LINE_LOOP works?

GL_LINE_LOOP: As line strips, except that the first and last vertices are also used as a line. Thus, you get n lines for n input vertices. If the user only specifies 1 vertex, the drawing command is ignored. The line between the first and last vertices happens after all of the previous lines in the sequence.

What is GL_LINE_LOOP?

GL_LINE_LOOP. Draws a connected group of line segments from the first vertex to the last, then back to the first. Vertices n and n + 1 define line n. The last line, however, is defined by vertices N and 1. N lines are drawn.

How many primitives in OpenGL?

OpenGL provides ten different primitive types for drawing points, lines, and polygons, as shown in Figure 2-1. Figure 2-1 OpenGL primitive types. OpenGL interprets the vertices and renders each primitive using the following rules: GL_POINTS— Use this primitive type to render mathematical points.


2 Answers

After reading your comments to BЈовић, I think it is clear that what you are looking for is the primitive restart index.

You can reserve an arbitrary index value to represent primitive restart by using the following API call: glPrimitiveRestartIndex (...). Often -1 is used, as in your original question.

Take a look at: OpenGL 4.3 Core Specification - 10.3.5 Primitive Restart - pp. 301 for more details.

I should also point out that index-based primitive restart is a feature that can be enabled / disabled, and it starts out disabled. So simply setting the restart index is not enough for it to actually do anything.

like image 32
Andon M. Coleman Avatar answered Sep 19 '22 10:09

Andon M. Coleman


This is not a simple problem to solve. Generally speaking, if a GS needs adjacency information, then you're probably doing something like GS-based tessellation, where you're using adjacent vertex information to generate the new triangle data.

In cases where there is no adjacent vertex information, you need to look to your tessellation algorithm for solutions. Many algorithms have ways of dealing with cases where there is no adjacent triangle. Some tessellation algorithms don't; they only work on perfectly regular meshes.

In those cases, you have a problem. Edges that have no adjacent triangles are probably supposed to be sharp edges. So, if your tessellation algorithm has no way to create sharp edges, then you'll need to modify it to create such a thing.

Failing that, you can always generate phantom vertices. For example, let's say that in your diagram, there is no vertex 6. You can create data for a vertex 6 by mirroring/projecting vertex 3, through the midpoint of the line created by vertices 1 and 5. That creates the effect of a regular mesh.

Again, how good this looks depends on your tessellation algorithm and your desired results.

like image 132
Nicol Bolas Avatar answered Sep 19 '22 10:09

Nicol Bolas