- void display()
- {
- glClear(GL_COLOR_BUFFER_BIT);
- glColor3f(1.0, 1.0, 1.0);
- glBegin(GL_POLYGON);
- {
- glVertex2i(380, 380);
- glVertex2i(320, 410);
- glVertex2i(180, 280);
- glVertex2i(90, 330);
- glVertex2i(50, 310);
- glVertex2i(50, 150);
- glVertex2i(90, 130);
- glVertex2i(180, 180);
- glVertex2i(320, 50);
- glVertex2i(380, 80);
- }
- glEnd();
- glLineWidth(2.0);
- glColor3f(1.0, 0.0, 0.0);
- glBegin(GL_LINE_LOOP);
- {
- glVertex2i(380, 380);
- glVertex2i(320, 410);
- glVertex2i(180, 280);
- glVertex2i(90, 330);
- glVertex2i(50, 310);
- glVertex2i(50, 150);
- glVertex2i(90, 130);
- glVertex2i(180, 180);
- glVertex2i(320, 50);
- glVertex2i(380, 80);
- }
- glEnd();
- glFlush();
- }
OpenGL中認爲合法的多邊形必須是凸多邊形,凹多邊形、自交多邊形、帶孔的多邊形等非凸的多邊形在OpenGL中繪製會出現出乎意料的結果。例如,在大多數系統中,只有多邊形的凸包被填充,而在有些系統中,並非所有的凸包都被填充。OpenGL之所以對合法多邊形類型做出限制,是爲了更方便地提供能夠對符合條件的多邊形進行快速渲染的硬件。簡單多邊形可被快速地渲染,而複雜多邊形難以快速檢測出來。爲了最大限度的提高性能,OpenGL假定多邊形是簡單的。
非凸多邊形最簡單的填充方法最簡單的應該是GLU 網格化對象GLUtesselator
就是GLUtesselator, 能將任意多邊形,簡化爲三角形或凸多邊形的組合,從而使OpenGL能繪製出任意形狀的多邊形。
1. gluNewTess(); //創建一個新的分格化對象2. gluTessCallback(); //註冊回調函數,完成分格化的一些操作,照着寫就行了。
3. gluTessProperty(); //可有可無的,設置一些分格化的屬性值
4. gluTessBeginPolygon(); //開始畫多邊形
draw polygon... //在這裏畫多邊形,一個一個點畫就可以,最後一個點會和第一個點自動連接起來
gluTessEdnPolygon(); //結束畫多邊形
5. gluDeleteTess(); //刪除分格化對象
- #include <stdio.h>
- #include <stdlib.h>
- #include <GL/glut.h>
- #pragma comment(lib,"glut32.lib")
- GLdouble quad[12][3] = {
- {-2,3,0}, {-2,0,0}, {2,0,0}, { 2,3,0},
- {-1,2,0}, {-1,1,0}, {1,1,0}, { 1,2,0},
- {-0.5,1,0}, {-0.5,2,0}, {0.5,2,0}, { 0.5,1,0} };
- void myIdle(void)
- {
- glutPostRedisplay();
- }
- //------------------------------------------------------------ OnDraw()
- //
- void CALLBACK vertexCallback(GLvoid *vertex)
- {
- const GLdouble *pointer = (GLdouble *) vertex;
- glColor3dv(pointer + 3);//在此設置顏色
- glVertex3dv(pointer);
- }
- void CALLBACK beginCallback(GLenum which)
- {
- glBegin(which);
- }
- void CALLBACK endCallback ()
- {
- glEnd();
- }
- void CALLBACK errorCallback(GLenum errorCode)
- {
- const GLubyte *estring;
- estring = gluErrorString(errorCode);
- fprintf(stderr, "Tessellation Error: %s\n", estring);
- exit(0);
- }
- void CALLBACK combineCallback(GLdouble coords[3],
- GLdouble *vertex_data[4],
- GLfloat weight[4], GLdouble **dataOut )
- {
- GLdouble *vertex;
- int i;
- vertex = (GLdouble *) malloc(6 * sizeof(GLdouble));
- vertex[0] = coords[0];
- vertex[1] = coords[1];
- vertex[2] = coords[2];
- for (i = 3; i < 7; i++)
- {
- vertex[i] = weight[0] * vertex_data[0][i]
- + weight[1] * vertex_data[1][i]
- + weight[2] * vertex_data[2][i]
- + weight[3] * vertex_data[3][i];
- }
- *dataOut = vertex;
- }
- void OnDraw()
- {
- // clear the screen & depth buffer
- glClear(GL_COLOR_BUFFER_BIT);
- // clear the previous transform
- glLoadIdentity();
- GLUtesselator *tobj = gluNewTess();
- if (!tobj) { return; }
- gluTessCallback(tobj, GLU_TESS_VERTEX, (void (CALLBACK *)())vertexCallback);
- gluTessCallback(tobj, GLU_TESS_BEGIN, (void (CALLBACK *)())beginCallback);
- gluTessCallback(tobj, GLU_TESS_END, (void (CALLBACK *)())endCallback);
- gluTessCallback(tobj, GLU_TESS_ERROR, (void (CALLBACK *)())errorCallback);
- gluTessCallback(tobj, GLU_TESS_COMBINE, (void (CALLBACK *)())combineCallback);
- // glShadeModel(GL_FLAT);
- // gluTessProperty(tobj,GLU_TESS_WINDING_RULE,GLU_TESS_WINDING_POSITIVE); //GLU_TESS_WINDING_ODD
- gluTessBeginPolygon(tobj, NULL);
- gluTessBeginContour(tobj);
- gluTessVertex(tobj, quad[0], quad[0]);
- gluTessVertex(tobj, quad[1], quad[1]);
- gluTessVertex(tobj, quad[2], quad[2]);
- gluTessVertex(tobj, quad[3], quad[3]);
- gluTessEndContour(tobj);
- gluTessBeginContour(tobj); // inner quad (hole)
- gluTessVertex(tobj, quad[4], quad[4]);
- gluTessVertex(tobj, quad[5], quad[5]);
- gluTessVertex(tobj, quad[6], quad[6]);
- gluTessVertex(tobj, quad[7], quad[7]);
- gluTessEndContour(tobj);
- gluTessBeginContour(tobj); // inner quad (hole)
- gluTessVertex(tobj, quad[8], quad[8]);
- gluTessVertex(tobj, quad[9], quad[9]);
- gluTessVertex(tobj, quad[10], quad[10]);
- gluTessVertex(tobj, quad[11], quad[11]);
- gluTessEndContour(tobj);
- gluTessEndPolygon(tobj);
- gluDeleteTess(tobj);
- glutSwapBuffers();
- }
- //------------------------------------------------------------ OnInit()
- //
- void OnInit()
- {
- //glClearColor(1,1,1,0);
- }
- //------------------------------------------------------------ OnExit()
- //
- void OnExit()
- {
- }
- //------------------------------------------------------------ OnReshape()
- //
- void OnReshape(int w, int h)
- {
- // prevents division by zero when minimising window
- if (h == 0)
- { h = 1; }
- // set the drawable region of the window
- glViewport(0, 0, w, h);
- // set up the projection matrix
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- // just use a perspective projection
- //gluPerspective(45,(float)w/h,0.1,100);
- if(w <= h)
- {
- glOrtho(-4.0, 4.0, -4.0 * (GLfloat)h / (GLfloat)w, 4.0 * (GLfloat)h / (GLfloat)w, 0.0, 100.0);
- }
- else
- {
- glOrtho(-4.0, 4.0, -4.0 * (GLfloat)h / (GLfloat)w, 4.0 * (GLfloat)h / (GLfloat)w, 0.0, 100.0);
- }
- // go back to model view matrix so we can move the objects about
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- }
- //------------------------------------------------------------ main()
- //
- int main(int argc,char** argv)
- {
- // initialize glut
- glutInit(&argc,argv);
- // request a depth buffer, RGBA display mode, and we want double buffering
- glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
- // set the initial window size
- glutInitWindowSize(480, 480);
- // create the window
- glutCreateWindow("filling");
- // run our custom initialisation
- OnInit();
- // set the function to use to draw our scene
- glutDisplayFunc(OnDraw);
- // set the function to handle changes in screen size
- glutReshapeFunc(OnReshape);
- // glutIdleFunc(&myIdle);
- // set the function to be called when we exit
- atexit(OnExit);
- // this function runs a while loop to keep the program running.
- glutMainLoop();
- return 0;
- }
- #include <stdio.h>
- #include <stdlib.h>
- #include <GL/glut.h>
- #pragma comment(lib,"glut32.lib")
- GLdouble quad[12][3] =
- {
- {5,5,0}, {15,5,0}, {15,-5,0}, { 5,-5,0},
- {0,5,0}, {-15,10,0}, {-5,-10,0}, { -10,5,0},
- {-0.5,1,0}, {-0.5,2,0}, {0.5,2,0}, { 0.5,1,0}
- };
- void myIdle(void)
- {
- glutPostRedisplay();
- }
- //------------------------------------------------------------ OnDraw()
- //
- void CALLBACK PolyLine3DBegin(GLenum type)
- {
- glBegin(type);
- }
- void CALLBACK PolyLine3DVertex ( GLdouble * vertex)
- {
- const GLdouble *pointer = (GLdouble *) vertex;
- glColor3d(1.0,0,0);//在此設置顏色
- glVertex3dv(pointer);
- }
- void CALLBACK PolyLine3DEnd()
- {
- glEnd();
- }
- GLUtesselator* tesser()
- {
- GLUtesselator * tess;
- tess=gluNewTess();
- gluTessCallback(tess,GLU_TESS_BEGIN,(void (CALLBACK*)())&PolyLine3DBegin);
- gluTessCallback(tess,GLU_TESS_VERTEX,(void (CALLBACK*)())&PolyLine3DVertex);
- gluTessCallback(tess,GLU_TESS_END,(void (CALLBACK*)())&PolyLine3DEnd);
- return tess;
- }
- /////////////////////////////////////////////////////////////////////////////////
- void OnDraw()
- {
- glClear(GL_STENCIL_BUFFER_BIT);
- GLUtesselator* tess = tesser();
- if (!tess) return;
- gluTessBeginPolygon(tess,NULL);
- gluTessBeginContour(tess);
- for(int i = 0; i < 4; i++)
- {
- gluTessVertex(tess, quad[i], quad[i]);
- }
- gluTessEndContour(tess);
- gluTessBeginContour(tess);
- for(int i = 4; i < 8;i++)
- {
- gluTessVertex(tess, quad[i], quad[i]);
- }
- gluTessEndContour(tess);
- gluTessEndPolygon(tess);
- glutSwapBuffers();
- }
- //------------------------------------------------------------ OnInit()
- //
- void OnInit()
- {
- //glClearColor(1,1,1,0);
- }
- //------------------------------------------------------------ OnExit()
- //
- void OnExit()
- {
- }
- //------------------------------------------------------------ OnReshape()
- //
- void OnReshape(int w, int h)
- {
- // prevents division by zero when minimising window
- if (h == 0)
- {
- h = 1;
- }
- // set the drawable region of the window
- glViewport(0, 0, w, h);
- // set up the projection matrix
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- // just use a perspective projection
- //gluPerspective(45,(float)w/h,0.1,100);
- if(w<=h)
- {
- glOrtho(-20.0, 20.0, -20.0 * (GLfloat)h / (GLfloat)w, 20.0 * (GLfloat)h / (GLfloat)w, 0.0, 100.0);
- }
- else
- {
- glOrtho(-20.0, 20.0, -20.0 * (GLfloat)h / (GLfloat)w, 20.0 * (GLfloat)h / (GLfloat)w, 0.0, 100.0);
- }
- // go back to model view matrix so we can move the objects about
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- }
- //------------------------------------------------------------ main()
- //
- int main(int argc, char** argv)
- {
- // initialize glut
- glutInit(&argc, argv);
- // request a depth buffer, RGBA display mode, and we want double buffering
- glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
- // set the initial window size
- glutInitWindowSize(480, 480);
- // create the window
- glutCreateWindow("fill tess");
- // run our custom initialization
- OnInit();
- // set the function to use to draw our scene
- glutDisplayFunc(OnDraw);
- // set the function to handle changes in screen size
- glutReshapeFunc(OnReshape);
- // glutIdleFunc(&myIdle);
- // set the function to be called when we exit
- atexit(OnExit);
- // this function runs a while loop to keep the program running.
- glutMainLoop();
- return 0;
- }
Reference:
其他填充方法:
http://www.cnblogs.com/mazhenyu/archive/2010/05/18/1738487.html
函數簡介:
http://hi.baidu.com/zhujianzhai/item/6ed52336d67e7b9ab80c03eb
http://bbs.csdn.net/topics/100086684
各種填充算法詳細講解:
http://blog.csdn.net/orbit/article/details/7368996
http://blog.csdn.net/yangtrees/article/details/9040257
轉自:http://blog.csdn.net/augusdi/article/details/20032185