PDA

View Full Version : How to draw multi edged polygons



3DPrgmer
11-19-2016, 05:20 AM
Hi,

i read some vertex and polygons from a file. But i don't know at compile time whether these polygons are triangulated or not. Is there a way to draw mulit edged polygons and use this instead of drawTriangles, or would it better to triangulate the data first and draw after that?

GClements
11-19-2016, 07:15 AM
i read some vertex and polygons from a file. But i don't know at compile time whether these polygons are triangulated or not. Is there a way to draw mulit edged polygons and use this instead of drawTriangles, or would it better to triangulate the data first and draw after that?
If you're using the compatibility profile, you can use glDrawElements(GL_POLYGON) to draw a single polygon. I assume that you can use glMultiDrawElements() for multiple polygons. I don't know whether primitive restarting works with polygons.

But GL_POLYGON only works for convex polygons; the behaviour is undefined for non-convex polygons.

In general, it's preferable to tessellate polygons into triangles, regardless of convexity. Even if the OpenGL implementation does this itself, the exact behaviour will vary between implementations. Doing it yourself ensures consistent and predictable behaviour.

Non-convex polygons can be drawn as triangle fans, using stencilling to identify the interior. This can be an appropriate solution for very complex polygons if you're only drawing a few of them (e.g. maps, where region boundaries are often dictated by geographical features such as rivers or coastlines).

Silence
11-21-2016, 01:40 AM
I highly suggest to use GL_TRIANGLES instead. One of the reasons is that GL_POLYGON has been deprecated since.

3DPrgmer
11-21-2016, 02:21 AM
all right. I made an algorithem, that triangulate the multipoly in a simple way:
n polygon -> n-2 triangles:
0,1,2
0,2,3
0,3,4
0,4,5
0,n-2, n-1

3DPrgmer
11-21-2016, 06:19 AM
I need your help once more with this problem. My triangulation seams not to work.

i have multiple model chunks stored in vModels.
Each Model can have one ore more segments stored in segmLst.
and each Segment has one or more polygons stored in meshIndices
each polygon should have at least 3 vertices
and each vertex has 3 coordinates and 2 uv


for (auto& modIt : vModels) // for every model chunk
{
for (auto& segIt : modIt->segmLst) // for every cluster
{
for (auto& mshIt : segIt->meshIndices) // for every polygon
{
if (mshIt->size() >= 3) // multipoly
{
// for every triangle of the multi polygon
for (unsigned int tri = 0; tri < mshIt->size() - 2; tri++)
{
// for every edge of the triangle
for (int triEdge = 0; triEdge < 3; triEdge++)
{
Vertex tempVertex;
// every edge has 3 coordinates
for (int j = 0; j < 3; j++)
tempVertex.position[j] = (GLfloat)segIt->vertex[(*mshIt)[triEdge > 0 ? tri + triEdge : 0] * 3 + j];

// and 2 UV
if (segIt->uv == NULL)
{
tempVertex.uv[0] = 1.0;
tempVertex.uv[1] = 1.0;
}
else
{
for (int j = 0; j < 2; j++)
tempVertex.uv[j] = (GLfloat)segIt->uv[(*mshIt)[triEdge > 0 ? tri + triEdge : 0] * 2 + j];
}
tempBufferData.push_back(tempVertex);
}
}
}
else // this shouldn't happen (polygon with less then 3 vertex)
{
deleteVectors();
MessageBox(NULL, "You have polygons with less then 3 vertices!", "MeshViewer 2.0 Error", MB_OK | MB_ICONERROR);
return;
}
}
}
}

on the two first pictures you can see the result and my problem. The polygons are not triangulated correctly.

And on the last you can see my idea about triangulation. the n = 6 edged polygon is split into n - 2 = 4 triangles using the edges (0,1,2), (0,2,3), ..., (0, n-2, n-1)

2299

So there are two options:
1) my triangulation idea is stupid.
2) my code is wrong.

i guess it's 2) and i hope you can find the problem ;)

john_connor
11-21-2016, 10:59 AM
i'd say let "blender" do the job for you ;)
https://www.blender.org/

import your model into blender, export it using the "tiangulate faces" flag
by the way its a very useful tool to create models yourself

Silence
11-21-2016, 11:22 PM
Your triangulation algorithm looks good. Check this (https://www.siggraph.org/education/materials/HyperGraph/scanline/outprims/polygon1.htm) for example. I haven't checked your code.

You might however have a polygon winding issue. Ensure all generated triangles are clock-counter wise (or CW if relevant for you).

3DPrgmer
11-22-2016, 10:06 AM
Ok, i think i'll check that code tomorrow, because when i look at my result it feels like i even don't touch all vertices. So i think i did something wrong there.
About cw/ccw it's a bit crazy. the file format stores the polygons cw, ccw, cw, ccw, cw, ccw,... Don't ask me why it isn't only cw/ccw
http://schlechtwetterfront.github.io/ze_filetypes/msh.html#STRP

==EDIT==

i checked it and it looks like a problem of my data. Because my calculation builds the correct triangles 0,1,2 and 0,2,3
But it seams that my data is like that:
23
01

and not
01
23

you see?? the edges are not calculated one after the other

Silence
11-22-2016, 10:49 PM
From your given link, the first sentence says that you have triangle strips ! This is far different from having N-gons.

Have a look here (https://en.wikipedia.org/wiki/Triangle_strip#OpenGL_implementation) for example.

Since triangle strips are deprecated in GL 3.x, and if you don't want to get stuck with GL 2.x, I still suggest to move to triangles. Since now you know you have triangles strips, so since the third vertex, you add only vertex by vertex to fulfill a full triangle (with reversing its winding each time), then you can easily change your algorithm to create normal triangles.

GClements
11-23-2016, 03:18 AM
Since triangle strips are deprecated in GL 3.x

That's incorrect. Only GL_POLYGON, GL_QUAD_STRIP and GL_QUADS are deprecated.

Silence
11-23-2016, 04:10 AM
That's incorrect. Only GL_POLYGON, GL_QUAD_STRIP and GL_QUADS are deprecated.

My bad. Thanks for this useful correction.

Silence
11-23-2016, 04:12 AM
So, to the OP, you can then just use triangle strips to draw.

3DPrgmer
11-23-2016, 07:34 AM
yeah. i misunderstood the file format. It's that way:

Each polygon is saved with it's own strp as triangles. And that is done this way:
2-3
| |
1-0

triangle 1: 0,1,2
triangle 2: 2,0,3

For those who are interested, here is the final algo:

tempVertex.position[j] = (GLfloat)segIt->vertex[(*mshIt)[tri + triEdge - ((tri % 2) * (triEdge - 1) * 2)] * 3 + j];