OpenGL画小球(无光照渲染)
来源:互联网 发布:帝国cms自带的采集 编辑:程序博客网 时间:2024/04/29 07:40
#define GLUT_DISABLE_ATEXIT_HACK
#include <gl/glut.h>#include <gl/glu.h>void display(){ glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glColor3f( 1.0f, 1.0f, 1.0f ); glutSolidSphere( 50.f, 15, 15 ); //glutSolidSphere中的第一个参数太大,要小于1才能看到,第一个参数为半径 glutSwapBuffers();}int main(int argc, char* argv[]){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutCreateWindow("小球"); glClearColor(0.0f, 1.0f, 1.0f, 1.0f); glutDisplayFunc(display); glutMainLoop(); return 0;}
上述的代码会画出实心球,整个实心小球是一个颜色,立体效果差,若想显示立体效果,需要用颜色,光照等渲染。
下面的代码画出球比较慢,是按照一个一个切面的圆显示出来的,最终为这些切面组成的网状图。这个球的立体感较强,但是画一个球的时间较长。
//球心坐标为(x,y,z),球的半径为radius,M,N分别表示球体的横纵向被分成多少份void drawSphere(GLfloat xx, GLfloat yy, GLfloat zz, GLfloat radius, GLfloat M, GLfloat N){ glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glColor3f( 1.0f, 1.0f, 1.0f ); float step_z = PI/M; float step_xy = 2*PI/N; float x[4],y[4],z[4]; float angle_z = 0.0; float angle_xy = 0.0; int i=0, j=0; glBegin(GL_POLIGON); for(i=0; i<M; i++) { angle_z = i * step_z; for(j=0; j<N; j++) { angle_xy = j * step_xy; x[0] = radius * sin(angle_z) * cos(angle_xy); y[0] = radius * sin(angle_z) * sin(angle_xy); z[0] = radius * cos(angle_z); x[1] = radius * sin(angle_z + step_z) * cos(angle_xy); y[1] = radius * sin(angle_z + step_z) * sin(angle_xy); z[1] = radius * cos(angle_z + step_z); x[2] = radius*sin(angle_z + step_z)*cos(angle_xy + step_xy); y[2] = radius*sin(angle_z + step_z)*sin(angle_xy + step_xy); z[2] = radius*cos(angle_z + step_z); x[3] = radius * sin(angle_z) * cos(angle_xy + step_xy); y[3] = radius * sin(angle_z) * sin(angle_xy + step_xy); z[3] = radius * cos(angle_z); for(int k=0; k<4; k++) { glVertex3f(xx+x[k], yy+y[k],zz+z[k]); } } } glEnd();}
注意glvertex3f函数,各个坐标均在0~1之间,如果参数不满足上述要求,则不能画出球形。屏幕为背景色。
glbegin的模式参数决定图像的立体感,如果为GL_QUADS,立体感较差。如果未GL_POLYGON,立体感稍好一些。
这里需要说明一点,第一份代码中使用了双缓冲技术。
通常, 我们所看到的窗体、文字、图像,从根本上来说都是“画”出来的。比如,制作一个简单的五子棋, 我们可能先要绘制棋盘,然后绘制棋子,我们可能还要绘制一些提示信息。虽然这些绘制操作有一定的先后顺序,通常情况下,操作系统的这些绘制速度非常的快,使人眼误认为这些绘制操作是同时完成的。
但当我们进行复杂的绘图操作时,画面便可能有明显的闪烁。解决这个问题的关键在于使绘制的东西同时出现在屏幕上。所谓双缓冲技术, 是指使用两个缓冲区: 前台缓冲和后台缓冲。前台缓冲即我们看到的屏幕,后台缓冲则在内存当中,对我们来说是不可见的。每次的所有绘图操作都在后台缓冲中进行, 当绘制完成时, 把绘制的最终结果复制到屏幕上, 这样, 我们看到所有GDI元素同时出现在屏幕上,从而解决了频繁刷新导致的画面闪烁问题。
glutSwapBuffers函数是OpenGL中GLUT工具包中用于实现双缓冲技术的一个重要函数。该函数的功能是交换两个缓冲区指针。 使用glutSwapBuffers函数需要在glutInitDisplayMode函数中时, 开启GLUT_DOUBLE,即glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE)。这里将我们惯用的GLUT_SINGLE替换为GLUT_DOUBLE,意为要使用双缓冲而非单缓冲。
第二份代码中使用了单缓冲技术。
在glutInitDisplayMode函数中时, 开启GLUT_SINGLE。glFlush函数是强制刷新,强制马上输出命令执行的结果,而不是存储在缓冲区中,继续等待其他OpenGL命令。因为OPENGL是使用一条渲染管线线性处理命令的,一般情况下,我们提交给OPENGL的指令并不是马上送到驱动程序里执行的,而是放到一个缓冲区里面,等这个缓冲区满了再一次过发到驱动程序里执行;很多时候只有几条指令是填充不满那个缓冲区的,这就是说这些指令根本没有被发送到驱动里,所以我们要调用glFlush来强制把这些指令送到驱动里进行处理。
因此使用该技术,可以看到每次画图的过程,而不是直接显示最终结果。
- OpenGL画小球(无光照渲染)
- 【Shader】Unity Unlit Shader(无光照着色器)
- 第四弹 3D物体无光照绘制
- opengl 渲染管线(转)
- OpenGL绘制自由落体小球
- 3D光照渲染小球
- OpenGL: OpenGL渲染流程
- cocos-2dx OPENGL渲染(1)
- (一)OpenGL渲染的基本流程
- OpenGL渲染管线---概述(一)
- D3D11四面体简单方向光光照渲染
- OpenGL ES总结(四)OpenGL 渲染视频画面
- OpenGL ES总结(四)OpenGL 渲染视频画面
- C#中使用OpenGL:(七)创建OpenGL渲染环境
- OpenGl 学习之小球运动
- 如何将OpenGL渲染的图片保存到本地(正常渲染和离屏渲染)
- 【OpenGL】OpenGL渲染流程详解
- 使用OpenGL对光照的设置
- MyEclipse 配置代码注释
- 我的APUE学习笔记(一)
- 关于 Fatal NI connect error 12170
- hdu 4455 dp
- JAVA实现气泡提示框
- OpenGL画小球(无光照渲染)
- 显示遮罩层插件blockUI
- jquery、js调用iframe父窗口与子窗口元素的方法
- ORACLE 12C PDB 维护基础介绍
- 视频文件头解析--mpeg-个人对mpg文件结构的理解
- tp调试---a13
- 百度笔试题:求非完全二叉树第m层第k个节点
- 《cocos2dx手机游戏开发》 源码基于cocos2d-x v2.2 下载
- cocos2d-x锚点