PDA

View Full Version : Polygon 2D



opessoa
05-29-2013, 06:56 AM
Hi. Can anyone tell me why my polygon is drawing with extensions...

Like the picture:

https://lh3.googleusercontent.com/-vzS6NCyZSvI/UaYITfv6meI/AAAAAAAAOY8/odYgQiiGFeo/w506-h508-o/polygon.png

There is my code:



glPushMatrix();

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

CMTObject::Draw();

glBegin(GL_POLYGON);
for(CMTPolygon::iterator it = begin(); it != end(); it++)
{
glColor3f(1,0,0);
glVertex2d(it->x,it->y);
}
glEnd();

glVertexPointer(2, GL_DOUBLE, 0, data());

glColor3f(0,0,0);
glDrawArrays(GL_LINE_LOOP,0,size());


How I can paint my polygon interior (inside lineloop)?

RigidBody
05-29-2013, 07:43 AM
looks to me like a GL_POLYGON is internally drawn as a GL_TRIANGLE_FAN.
if you switch to glPolygonMode(GL_FRONT_AND_BACK, GL_LINE), you should see that all triangles start at one single point.
and since your polygon is not konvex, some triangles overlap.

btw, which country is that?

opessoa
05-29-2013, 08:06 AM
looks to me like a GL_POLYGON is internally drawn as a GL_TRIANGLE_FAN.
if you switch to glPolygonMode(GL_FRONT_AND_BACK, GL_LINE), you should see that all triangles start at one single point.
and since your polygon is not konvex, some triangles overlap.

btw, which country is that?

Its a city limits from Blumenau - Santa Catarina - Brasil...

This is a non convex polygon...

Dan Bartlett
05-29-2013, 08:15 AM
OpenGL only guarantees drawing convex polygons correctly with glBegin/glEnd. It states this here: http://www.opengl.org/sdk/docs/man2/xhtml/glBegin.xml
The bit that covers in in the compatibility spec is:

Only convex polygons are guaranteed to be drawn correctly by the GL. If aspecified polygon is nonconvex when projected onto the window, then the rendered
polygon need only lie within the convex hull of the projected vertices defining its
boundary

opessoa
05-29-2013, 09:13 AM
What is the best way to do this "painting" inside the non convex polygon?

trinitrotoluene
05-29-2013, 09:49 AM
What is the best way to do this "painting" inside the non convex polygon?
You can draw filled concave polygon with the stencil buffer. See this thread (http://www.opengl.org/discussion_boards/showthread.php/181055-Polygonizing-a-grid-after-subtracting-an-irregular-portion?p=1248461#post1248461) and this link (http://www710.univ-lyon1.fr/~jciehl/Public/OpenGL_PG/ch15.html#id11378).

Edit: with chromium on linux , open the link in a new tab otherwise the link bring me at the bottom of the web page.

opessoa
05-29-2013, 12:34 PM
Sorry trinitrotoluene... It's no work. :P

Im trying to use Tess, but steal not working, can you help me?



GLvoid tcbBegin(GLenum type)
{
glBegin(type);
}

GLvoid tcbVertex(GLvoid *vertex)
{
glVertex3dv((GLdouble*)vertex);
}

GLvoid tcbEnd()
{
glEnd();
}

GLvoid combineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut )
{
GLdouble *vertex;
vertex = (GLdouble *) malloc(3 * sizeof(GLdouble));
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
*dataOut = vertex;
}

GLvoid errorCallback(GLenum errorCode)
{
const GLubyte *estring;
estring = gluErrorString(errorCode);
fprintf(stderr, "Tessellation Error: %s\n", estring);
}

void draw()
{
double* dData = reinterpret_cast<double*>(data());

GLuint startList = glGenLists(2);

GLUtesselator* wall1 = gluNewTess();
gluTessCallback(wall1, GLU_TESS_VERTEX, (GLvoid (APIENTRY *) ()) &tcbVertex);
gluTessCallback(wall1, GLU_TESS_BEGIN, (GLvoid (APIENTRY *) ()) &tcbBegin);
gluTessCallback(wall1, GLU_TESS_END, (GLvoid (APIENTRY *) ()) &tcbEnd);
gluTessCallback(wall1, GLU_TESS_COMBINE, (GLvoid (APIENTRY *) ()) &combineCallback);
gluTessCallback(wall1, GLU_TESS_ERROR, (GLvoid (APIENTRY *) ()) &errorCallback);

glNewList(startList, GL_COMPILE);
glShadeModel(GL_SMOOTH);
gluTessProperty(wall1, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE);

gluTessBeginPolygon(wall1, NULL);
gluTessBeginContour(wall1);
for (int i = 0; i < size(); i+=3)
{
gluTessVertex(wall1, &dData[i], &dData[i]);
}
gluTessEndContour(wall1);
gluTessEndPolygon(wall1);

glEndList();

gluDeleteTess(wall1);
}

trinitrotoluene
05-29-2013, 01:19 PM
Try that with a simple concave polygon first:



//INIT CODE
glEnable(GL_DEPTH_TEST);


//DRAW CODE
glClear(GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);

glEnable(GL_STENCIL_TEST);
glBindVertexArray(m_VAO);
//Dont write in the color buffer
//Dont write in the depth buffer
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
glDepthMask(GL_FALSE);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS,0x1,0x1);
glStencilOp(GL_KEEP,GL_KEEP,GL_INVERT);
glDrawArrays(GL_TRIANGLE_FAN,0,m_Vertices.size());


//Draw the triangle strip a second time but only where the stencil is one
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);

glStencilFunc(GL_EQUAL,0x1,0x1);
//NOT TESTED: using GL_INVERT as the last parameter permit to clear stencil value to 0 where
//stencil value is one and to draw multiple concave polygon in the same frame.
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
glDrawArrays(GL_TRIANGLE_FAN,0,m_Vertices.size());

glDisable(GL_STENCIL_TEST);




It work fine for me.

Also,when you create your rendering context with GLUT for example, you must ask for a depth buffer with a stencil buffer to be present when you call glutInitDisplayMode.

opessoa
05-31-2013, 04:25 AM
It's work, but with some pixels error.

https://lh3.googleusercontent.com/-3I3nFcNQ2n8/UaiH8bE0e4I/AAAAAAAAOaQ/48R4Gy5bp_A/w506-h504-o/polygon2.png

How to solve this?

trinitrotoluene
05-31-2013, 01:35 PM
Which algorithm are you using, the one with stencil buffer or the one with GLU tessellation (a deprecated library) ?

opessoa
05-31-2013, 01:52 PM
I'm using with stencil buffer.



glVertexPointer(3, GL_DOUBLE, 0, data());

glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);
glDepthMask(GL_FALSE);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS,0x1,0x1);
glStencilOp(GL_KEEP,GL_KEEP,GL_INVERT);
glDrawArrays(GL_TRIANGLE_FAN,0,size());

//Draw the triangle strip a second time but only where the stencil is one
glDepthMask(GL_TRUE);
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);

glStencilFunc(GL_EQUAL,0x1,0x1);
//NOT TESTED: using GL_INVERT as the last parameter permit to clear stencil value to 0 where
//stencil value is one and to draw multiple concave polygon in the same frame.
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
glDrawArrays(GL_TRIANGLE_FAN,0,size());

glDisable(GL_STENCIL_TEST);

//Desenha contorno
glColor3f(0,0,0);
glDrawArrays(GL_LINE_LOOP,0,size());

trinitrotoluene
05-31-2013, 02:06 PM
Can you put your vertices data on a hosting web site and put a link on this thread so I can test your data on my computer.

opessoa
05-31-2013, 04:56 PM
Can you put your vertices data on a hosting web site and put a link on this thread so I can test your data on my computer.

There is the points...

https://docs.google.com/file/d/0B8B-NIoST12WMjVjVjBvbjBteVE/edit?usp=sharing

trinitrotoluene
05-31-2013, 07:22 PM
I have tried your data and the algorithm with stencil buffer work as is.http://s14.postimg.org/4ajwqxt2l/image.jpg (http://postimg.org/image/4ajwqxt2l/) I think your problem is when you read your data in a file or when you pass the data to OpenGL. Check if the value of your points in the array is all valid.

opessoa
06-01-2013, 04:34 AM
I have tried your data and the algorithm with stencil buffer work as is.http://s14.postimg.org/4ajwqxt2l/image.jpg (http://postimg.org/image/4ajwqxt2l/) I think your problem is when you read your data in a file or when you pass the data to OpenGL. Check if the value of your points in the array is all valid.

These points are my debug Trace from my point vector.

Im using opengl with MFC window. Not using glut. May be some init parameter?

Have some settings to gradient color?

Because just setting color and drawvertex polygon it's painting with a gradient.

trinitrotoluene
06-01-2013, 06:02 AM
To test your data, I have computed the min and max for x and y. Then computed the mean value for both min max for each x,y and subtracted that value to each point. I do so because it easier to hardcode the value for the orthographic projection and I have read on this forum (but I don't remember well) that when you give large value for translatef, strange things can happen (Your vertices are far away the origin). When you call VertexPointer with GL_DOUBLE most if not all OpenGL implementations convert your data to GL_FLOAT type, but I don't think it will solve your problem.

I never used MFC so I can't help for this.

opessoa
06-02-2013, 05:33 AM
To test your data, I have computed the min and max for x and y. Then computed the mean value for both min max for each x,y and subtracted that value to each point. I do so because it easier to hardcode the value for the orthographic projection and I have read on this forum (but I don't remember well) that when you give large value for translatef, strange things can happen (Your vertices are far away the origin). When you call VertexPointer with GL_DOUBLE most if not all OpenGL implementations convert your data to GL_FLOAT type, but I don't think it will solve your problem.

I never used MFC so I can't help for this.

My ortho has the min and max x/y...

I will try to do this, subtract the min x and y to each point. And set my ortho do 0 and width of the limit map.

So I'll tell you what happened.

opessoa
06-03-2013, 09:42 AM
Trinitroluene, using glut it's working. Dammit! Thanks for all.