Drawing a concave polygon in OpenGL

I have a concave polygon I need to draw in OpenGL.
A polygon is defined as a list of points that form its outer ring and a list of lists of points that define its inner rings (exclusion zones).

I can already deal with exceptions, so the decision on how to draw a polygon without inner rings would also be a good one.

A solution with Boost.Geometry would be a good one since I already use it heavily in my application.

I need this to work on the iPhone, namely OpenGL ES (an older version with a fixed pipeline).

How can i do this?

+6
source share
3 answers

Try OpenGL tessellation objects . You can use it to convert a complex polygon into a set of triangles that you can visualize directly.

EDIT (in response to comment): OpenGL ES does not support tessellation features. In this case, if the polygon is static, you can generate tessellation offline using OpenGL on your desktop or laptop.

If the form is dynamic, you're out of luck with OpenGL ES. However, there are many libraries (such as CGAL ) that will perform the same function.

+6
source

This is a bit complicated and resource-intensive method, but any concave polygon can be made using the following steps (note that these methods work, of course, on flat polygons, but I also assume that you are trying to draw on a flat surface or in 2D orthogonal mode) :

  • enable stencil test, use glStencilFunc(GL_ALWAYS,1,0xFFFF)
  • disable color mask to prevent unwanted draws: glColorMask(0,0,0,0)
  • I think you have vertices in a double array or in another form (highly recommended since this method reuses the same polygon repeatedly, but you can also use glList or glBegin-glEnd)
  • set glStencilOp(GL_KEEP,GL_KEEP,GL_INCR)
  • draw a polygon as GL_TRIANGLE_FAN

Now on the stencil layer you have set bits> 0, where the polygon triangles were drawn. The trick is that the entire admissible region of the polygon is filled with values ​​having mod2 = 1, this is because the pattern of the triangular fan runs along the surface of the polygon, and if the selected triangle has an area outside the polygon, it will be drawn twice (once with the current sequence, then in the following figures, when the actual areas are drawn) This can happen many times, but in all cases the pixels outside the polygon are drawn even times, the pixels inside are drawn odd times. Some exceptions may occur when the order of the pixels causes the outer areas to not be drawn again. To filter these cases, you need to conduct a reverse array of vertices (all these cases work correctly when switching orders): - set glStencilFunc (GL.GL_EQUAL, 1,1) to prevent these errors in the opposite direction (you can only draw areas inside the polygon drawn for the first time, so errors occurring in the other direction will not be apperar, logically this generates intersectoin from two half-solutions) - draw the polygon in the reverse order, keeping glStencilFunc to increase the values ​​of the cleaned pixels Now we have ht stencil layer pixel_value% 2 = 1 where a pixel is indeed inside the polygon. The last step is to draw the polygon itself: - set glColorMask(1,1,1,1) to draw a visible polygon - hold glStencilFunc (GL_EQUAL, 1,1) to draw the correct pixels - draw a polygon in the same mode (vertex arrays and etc.), or if you draw without lighting / texturing, you can also draw one rectangle of the entire screen (faster than drawing all the vertices, and only valid polygon pixels will be set)

If everything goes well, the polygon is drawn correctly, make sure that after this function you reset the stencil (stencil test) and / or clear the stencil buffer if you also use it for other purposes.

+2
source

Check for glue that has tessellation features that can process concave polygons.

0
source

Source: https://habr.com/ru/post/898875/


All Articles