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.
source share