【循序渐进学图形学之】OpenGL使用多边形近似模拟法构建表面
2011-10-21 20:24
387 查看
环境:VS2008
首先创建一个二十面体:
代码:
使用二十面体来模拟着色球体。需修改代码:
我们可以对三角形进行细分。下面对上述成语执行一次细分,创建一个80个面的模拟球体。
代码:
继续对程序进修改,用递归的方法对三角形进行划分,以获得适当的深度。如果深度为0,则停止划分。
只需修改subdivide函数:
可以看出获得了比较好的效果。
首先创建一个二十面体:
代码:
#include <GL/glut.h> #define X .525731112119133606 #define Z .850650808352039932 static GLfloat vdata[12][3] = {//各顶点坐标 {-X,0.0,Z},{X,0.0,Z},{-X,0.0,-Z},{X,0.0,-Z}, {0.0,Z,X},{0.0,Z,-X},{0.0,-Z,X},{0.0,-Z,-X}, {Z,X,0.0},{-Z,X,0.0},{Z,-X,0.0},{-Z,-X,0.0}, }; static GLuint tindices[20][3] = {//构成各面(三角形)的顶点索引 {1,4,0},{4,9,0},{4,5,9},{8,5,4},{1,8,4}, {1,10,8},{10,3,8},{8,3,5},{3,2,5},{3,7,2}, {3,10,7},{10,6,7},{6,11,7},{6,0,11},{6,1,0}, {10,1,6},{11,0,9},{2,11,9},{5,2,9},{11,2,7}, }; void display() { glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); for(int i = 0;i < 20;++i) { glColor3f(1.0,1.0,i * 1.0 / 20);//颜色设置 glVertex3fv(&vdata[tindices[i][0]][0]); glVertex3fv(&vdata[tindices[i][1]][0]); glVertex3fv(&vdata[tindices[i][2]][0]); } glEnd(); glFlush(); } void init() { glClearColor(0.0,0.0,0.0,0.0); } int main(int argc,char** argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(250,250); glutInitWindowPosition(100,100); glutCreateWindow("Polygon"); init(); glutDisplayFunc(display); glutMainLoop(); return 0; }运行结果:
使用二十面体来模拟着色球体。需修改代码:
glBegin(GL_TRIANGLES); for(int i = 0;i < 20;++i) { glColor3f(1.0,1.0,i * 1.0 / 20); glNormal3fv(&vdata[tindices[i][0]][0]); glVertex3fv(&vdata[tindices[i][0]][0]); glNormal3fv(&vdata[tindices[i][1]][0]); glVertex3fv(&vdata[tindices[i][1]][0]); glNormal3fv(&vdata[tindices[i][2]][0]); glVertex3fv(&vdata[tindices[i][2]][0]); } glEnd();但是效果并不好。
我们可以对三角形进行细分。下面对上述成语执行一次细分,创建一个80个面的模拟球体。
代码:
#include <GL/glut.h> #include <iostream> #include <cmath> using namespace std; #define X .525731112119133606 #define Z .850650808352039932 static GLfloat vdata[12][3] = { {-X,0.0,Z},{X,0.0,Z},{-X,0.0,-Z},{X,0.0,-Z}, {0.0,Z,X},{0.0,Z,-X},{0.0,-Z,X},{0.0,-Z,-X}, {Z,X,0.0},{-Z,X,0.0},{Z,-X,0.0},{-Z,-X,0.0}, }; static GLuint tindices[20][3] = { {1,4,0},{4,9,0},{4,5,9},{8,5,4},{1,8,4}, {1,10,8},{10,3,8},{8,3,5},{3,2,5},{3,7,2}, {3,10,7},{10,6,7},{6,11,7},{6,0,11},{6,1,0}, {10,1,6},{11,0,9},{2,11,9},{5,2,9},{11,2,7}, }; static GLuint count = 0;//全局静态变量 void normalize(float v[3]) { GLfloat d = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); if(d == 0) { cout<<"zero length vector!"; return; } v[0] /= d; v[1] /= d; v[2] /= d; } void drawtriangle(float *v1,float *v2,float *v3)//绘制三角形的操作 { count += 1; glBegin(GL_TRIANGLES); //颜色设置 :给不同小三角形设置不同颜色,便于查看 if(count % 3 == 0) glColor3f(0.0,1.0,1.0); else if(count % 3 == 1) glColor3f(1.0,0.0,1.0); else glColor3f(1.0,1.0,0.0); glNormal3fv(v1); glVertex3fv(v1); glNormal3fv(v2); glVertex3fv(v2); glNormal3fv(v3); glVertex3fv(v3); glEnd(); } void subdivide(float *v1,float *v2,float *v3) { GLfloat v12[3],v23[3],v31[3]; for(int i = 0;i < 3;++i) { v12[i] = (v1[i] + v2[i]) / 2.0; v23[i] = (v2[i] + v3[i]) / 2.0; v31[i] = (v3[i] + v1[i]) / 2.0; } normalize(v12); normalize(v23); normalize(v31); drawtriangle(v1,v12,v31); drawtriangle(v2,v23,v12); drawtriangle(v3,v31,v23); drawtriangle(v12,v23,v31); } void display() { glClear(GL_COLOR_BUFFER_BIT); for(int i = 0;i < 20;++i) { subdivide(&vdata[tindices[i][0]][0],&vdata[tindices[i][1]][0], &vdata[tindices[i][2]][0]); } glFlush(); } void init() { glClearColor(0.0,0.0,0.0,0.0); } int main(int argc,char** argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(250,250); glutInitWindowPosition(100,100); glutCreateWindow("Polygon"); init(); glutDisplayFunc(display); glutMainLoop(); return 0; }运行结果:
继续对程序进修改,用递归的方法对三角形进行划分,以获得适当的深度。如果深度为0,则停止划分。
只需修改subdivide函数:
//采用递归细分方法:depth为深度值,控制划分的次数 void subdivide(float *v1,float *v2,float *v3,long depth) { GLfloat v12[3],v23[3],v31[3]; if(depth == 0) { drawtriangle(v1,v2,v3); return; } for(int i = 0;i < 3;++i) { v12[i] = (v1[i] + v2[i]) / 2.0; v23[i] = (v2[i] + v3[i]) / 2.0; v31[i] = (v3[i] + v1[i]) / 2.0; } normalize(v12); normalize(v23); normalize(v31); subdivide(v1,v12,v31,depth - 1); subdivide(v2,v23,v12,depth - 1); subdivide(v3,v31,v23,depth - 1); subdivide(v12,v23,v31,depth - 1); }运行结果:
可以看出获得了比较好的效果。
相关文章推荐
- 用多边形近似球体表面(icosphere)的Mesh数据的生成并使用openGL绘制
- IOS 中openGL使用教程2(openGL ES 入门篇 | 绘制一个多边形)
- 使用angularjs1.x构建前台开发框架(四)——模拟后台响应(打桩模块)
- VC++下,使用OpenGL实现星系运行的模拟
- [OpenGL]图形的绘制——多边形面
- OpenGL: 多边形分格化 和 gluTessCallback() 函数在c++中的使用方法
- 如何让c语言使用结构体近似模拟c++中的类
- 使用Coin3D VS2010 Qt 5.3.1构建三维图形开发环境
- 如何快速上手使用OpenGL进行图形绘制
- OpenGL: 多边形分格化 和 gluTessCallback() 函数在c++中的使用方法
- OpenGL基础图形编程 - OpenGL辅助库的基本使用
- 幻世(OurDream)2D图形引擎使用教程1——认识幻世,构建幻世开发环境
- OpenGL基础图形编程 - OpenGL辅助库的基本使用
- 在qt中使用opengl绘制图形动画
- openGL学习笔记四 : 关于颜色, 大小, 虚线, 多边形反转, 镂空, 使用位图
- 【循序渐进学图形学之】OpenGL视图和模型变换中各变换发生顺序的思考
- 使用D3.js构建实时图形的示例代码
- 使用原生JavaScript的Canvas实现拖拽式图形绘制,支持画笔、线条、箭头、三角形、矩形、平行四边形、梯形以及多边形和圆形,不依赖任何库和插件,有演示demo
- OpenGL,多边形上贴BMP (C/C++版)+在QT中的使用
- Ubuntu12.04下使用OPENGL做波场模拟显示