OpenGL實現(xiàn)貝塞爾曲線或曲面
本文實例為大家分享了OpenGL實現(xiàn)貝塞爾曲線或曲面的具體代碼,供大家參考,具體內(nèi)容如下
理論基礎(chǔ)
貝塞爾曲線和曲面:OpenGL只能直接繪制基本圖元,對于曲線和曲面我們一般采用一系列線段或多邊形來模擬的,這樣當線段或多邊形增多時必定很耗性能。其實對于這種曲線和曲面,我們可以使用一些控制點,通過求值器程序先計算出坐標等信息,然后直接用這些數(shù)據(jù)繪制,這樣不僅節(jié)省內(nèi)存,還提高了模擬曲線或曲面的精度(本質(zhì)還是通過線段或多邊形繪制的,只是求值器提前算出了曲線或曲面的頂點信息)。
求值器使用一般步驟:1.啟用求值器 2.定義求值器 3.執(zhí)行求值器。
注釋:OpenGl3.1后,本節(jié)內(nèi)容都已經(jīng)廢棄了,這些頂點著色器都可以實現(xiàn)了。
代碼示例
1、曲線
#include "GLTools.h" #ifdef __APPLE__ #include <glut/glut.h> #else #define FREEGLUT_STATIC #include <GL/glut.h> #endif //控制點 GLfloat ctrlpoints[4][3] = { { -4.0, -4.0, 0.0}, { -2.0, 4.0, 0.0}, {2.0, -4.0, 0.0}, {4.0, 4.0, 0.0}}; void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); //定義一維求值器 glMap1f(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, 4, &ctrlpoints[0][0]); //啟動求職器 glEnable(GL_MAP1_VERTEX_3); } void display(void) { int i; glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glBegin(GL_LINE_STRIP); for (i = 0; i <= 30; i++) glEvalCoord1f((GLfloat) i/30.0);//執(zhí)行求值器,每執(zhí)行一次產(chǎn)生一個坐標 glEnd(); //繪制4個控制點 glPointSize(5.0); glColor3f(1.0, 1.0, 0.0); glBegin(GL_POINTS); for (i = 0; i < 4; i++) glVertex3fv(&ctrlpoints[i][0]); glEnd(); glFlush(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-5.0, 5.0, -5.0*(GLfloat)h/(GLfloat)w, 5.0*(GLfloat)h/(GLfloat)w, -5.0, 5.0); else glOrtho(-5.0*(GLfloat)w/(GLfloat)h, 5.0*(GLfloat)w/(GLfloat)h, -5.0, 5.0, -5.0, 5.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc (keyboard); glutMainLoop(); return 0; }
2、曲面
#include "GLTools.h" #ifdef __APPLE__ #include <glut/glut.h> #else #define FREEGLUT_STATIC #include <GL/glut.h> #endif GLfloat ctrlpoints[4][4][3] = { {{ -1.5, -1.5, 4.0}, { -0.5, -1.5, 2.0}, {0.5, -1.5, -1.0}, {1.5, -1.5, 2.0}}, {{ -1.5, -0.5, 1.0}, { -0.5, -0.5, 3.0}, {0.5, -0.5, 0.0}, {1.5, -0.5, -1.0}}, {{ -1.5, 0.5, 4.0}, { -0.5, 0.5, 0.0}, {0.5, 0.5, 3.0}, {1.5, 0.5, 4.0}}, {{ -1.5, 1.5, -2.0}, { -0.5, 1.5, -2.0}, {0.5, 1.5, 0.0}, {1.5, 1.5, -1.0}} }; GLfloat texpts[2][2][2] = {{{0.0, 0.0}, {0.0, 1.0}}, {{1.0, 0.0}, {1.0, 1.0}}}; void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glEvalMesh2(GL_FILL, 0, 20, 0, 20);//glMapGrid2f()均勻產(chǎn)生坐標值,這里執(zhí)行繪制 glFlush(); } #define imageWidth 64 #define imageHeight 64 GLubyte image[3*imageWidth*imageHeight]; //紋理數(shù)據(jù) void makeImage(void) { int i, j; float ti, tj; for (i = 0; i < imageWidth; i++) { ti = 2.0*3.14159265*i/imageWidth; for (j = 0; j < imageHeight; j++) { tj = 2.0*3.14159265*j/imageHeight; image[3*(imageHeight*i+j)] = (GLubyte) 127*(1.0+sin(ti)); image[3*(imageHeight*i+j)+1] = (GLubyte) 127*(1.0+cos(2*tj)); image[3*(imageHeight*i+j)+2] = (GLubyte) 127*(1.0+cos(ti+tj)); } } } void init(void) { //定義了兩個求值器程序 glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &ctrlpoints[0][0][0]); glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, &texpts[0][0][0]); glEnable(GL_MAP2_TEXTURE_COORD_2); glEnable(GL_MAP2_VERTEX_3); glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);//均勻產(chǎn)生坐標 //紋理屬性設(shè)置 makeImage(); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, imageWidth, imageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glShadeModel (GL_FLAT); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho(-4.0, 4.0, -4.0*(GLfloat)h/(GLfloat)w, 4.0*(GLfloat)h/(GLfloat)w, -4.0, 4.0); else glOrtho(-4.0*(GLfloat)w/(GLfloat)h, 4.0*(GLfloat)w/(GLfloat)h, -4.0, 4.0, -4.0, 4.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(85.0, 1.0, 1.0, 1.0); } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
WM_CLOSE、WM_DESTROY、WM_QUIT及各種消息投遞函數(shù)詳解
這篇文章主要介紹了WM_CLOSE、WM_DESTROY、WM_QUIT及各種消息投遞函數(shù),有助于讀者更好的理解windows程序的消息機制,需要的朋友可以參考下2014-07-07windows 下C++生成Dump調(diào)試文件與分析
dump文件是C++程序發(fā)生異常時,保存當時程序運行狀態(tài)的文件,是調(diào)試異常程序重要的方法,所以程序崩潰時,除了日志文件,dump文件便成了我們查找錯誤的最后一根救命的稻草,這篇文章主要介紹了windows 下C++生成Dump調(diào)試文件與分析,需要的朋友可以參考下2023-04-04C語言中函數(shù)與指針的應(yīng)用總結(jié)
本篇文章是對C語言中函數(shù)與指針的應(yīng)用進行了詳細的分析介紹,需要的朋友參考下2013-05-05