一、OpenGL概述 Open GL 是3D图像处理技术的标准技术,其通过将三维直观图形绘制在三维坐标系上的表面顶点上,通过模拟现实事件的光照,材质等操作,然后结合物体本身的运动属于,结合物体本身的颜色属性(Texture),而进行绘制的接口操作,最后,上面的运算函数将运算结果现实在二维的屏幕控件上。简单介绍下其中的处理技术: 1、多边形顶点绘制,几乎很多入门级的书中,第一章就是将如何绘制多边形,如如何绘制球形物体的顶点,使用很多三角型坐标,其实Open GL在表示3维图形的时候,并不是人眼的模拟结果,而是将物体在三维控件上显示,然后顶点绘制的意义就是绘制三维控件的小平面,由这些小的平面组织成大型的三维控件的表面,所以如果要想逼真效果好,就是这些小型的表面控件一定要小,正如多边形的边越多,就越像圆一样。绘制各种图形有各种各样的算法。 2、3D图形的矩阵运算,3D图形在绘制的时候,很可能根据实际的情况,有镜头从远而近(如CS),有不断旋转的物体(如水车),正如我们在glsurfaceview中的thread一样,OnDrawFrame在不断的重画,所以我们在调用open gl的矩阵运算,缩放,移动,旋转的时候,可以在OnDrawFrame里边调用这些运算,从而在屏幕上显示动态的效果。 3、光照和材质,Open gl在显示立体表面的时候,如没有光照效果,很可能显示的是一个圆而不是一个球,所以有了光照的操作,光照的原理与显示一样,有类似手电筒在黑夜里的光照效果,有类似太阳光的光照效果,有的是照在光滑的表面,有的是非常粗糙的材质,Open gl光照是根据每个顶点的法向量(比如球的表面顶点的法向量,是指向球心的半径),那么在计算机中,glLight就是通过法向量运算完毕后,显示的各顶点的颜色的不同灰度值。OpenGL光有自发光(Emitted Light)、环境光(Ambient Light)、漫反射光(Diffuse Light)和高光(Specular Light)。材质是用光反射率来表示。场景(Scene)中物体最终反映到人眼的颜色是光的红绿蓝分量与材质红绿蓝分量的反射率相乘后形成的颜色。 4、颜色混合和纹理,Open gl最后需要与显示想结合,所以绘制的顶点数据,将用现实世界的三维空间的真实表面去“覆盖”顶点坐标,以达到真实的效果,而3D世界中,很多小的纹理可以合成成大的纹理,有关纹理的运算open gl也提供了不同的算法。 5、位图显示和图象增强图象功能除了基本的拷贝和像素读写外,还提供融合(Blending)、抗锯齿(反走样)(Antialiasing)和雾(fog)的特殊图象效果处理。以上三条可使被仿真物更具真实感,增强图形显示的效果。 6、双缓存动画(Double Buffering)双缓存即前台缓存和后台缓存,简言之,后台缓存计算场景、生成画面,前台缓存显示后台缓存已画好的画面。 二、OpenGL接口函数: 我们还是鸟瞰下open gl的JNI接口函数吧: glAccum \\操作累加缓冲区 glAddSwapHintRectWIN \\定义一组被SwapBuffers拷贝的三角形 glAlphaFunc \\允许设置alpha检测功能 glAreTexturesResident \\决定特定的纹理对象是否常驻在纹理内存中 glArrayElement \\定义一个被用于顶点渲染的数组成分 glBegin,glEnd \\定义一个或一组原始的顶点 glBindTexture \\允许建立一个绑定到目标纹理的有名称的纹理 glBitmap \\绘制一个位图 glBlendFunc \\特殊的像素算法 glCallList \\执行一个显示列表 glCallLists \\执行一列显示列表,mgllDisplay接口操作 glClear \\用当前值清除缓冲区 lClearAccum \\为累加缓冲区指定用于清除的值 glClearColor \\为色彩缓冲区指定用于清除的值 glClearDepth \\为深度缓冲区指定用于清除的值 glClearStencil \\为模板缓冲区指定用于清除的值 glClipPlane \\定义被裁剪的一个平面几何体 glColor \\设置当前色彩 glColorMask \\允许或不允许写色彩组件帧缓冲区 glColorMaterial \\使一个材质色彩指向当前的色彩 glColorPointer \\定义一列色彩 glColorTableEXT \\定义目的一个调色板纹理的调色板的格式和尺寸 glColorSubTableEXT \\定义目的纹理的调色板的一部分被替换 glCopyPixels \\拷贝帧缓冲区里的像素 glCopyTexImage1D \\将像素从帧缓冲区拷贝到一个单空间纹理图象中 glCopyTexImage2D \\将像素从帧缓冲区拷贝到一个双空间纹理图象 glCopyTexSubImage1D \\从帧缓冲区拷贝一个单空间纹理的子图象 glCopyTexSubImage2D \\从帧缓冲区拷贝一个双空间纹理的子图象 glCullFace \\定义前面或后面是否能被精选 glDeleteLists \\删除相邻一组显示列表 glDeleteTextures \\删除命名的纹理 glDepthFunc \\定义用于深度缓冲区对照的数据 glDepthMask \\允许或不允许写入深度缓冲区 glDepthRange \\定义z值从标准的设备坐标映射到窗口坐标 glDrawArrays \\定义渲染多个图元 glDrawBuffer \\定义选择哪个色彩缓冲区被绘制 glDrawElements \\渲染数组数据中的图元 glDrawPixels \\将一组像素写入帧缓冲区 glEdgeFlag \\定义一个边缘标志数组 glEdgeFlagPointer \\定义一个边缘标志数组 glEnable, glDisable \\打开或关闭 glEnableClientState,glDisableClientState \\分别打开或关闭数组 glEvalCoord \\求解一维和二维贴图 glEvalMesh1,glEvalMesh2 \\求解一维和二维点或线的网格 glEvalPoint1,glEvalPoint2 \\生成及求解一个网格中的单点 glFeedbackBuffer \\控制反馈模式 glFinish \\等待直到OpenGL执行结束 glFlush \\在有限的时间里强制OpenGL的执行 glFogf,glFogi,glFogfv,glFogiv \\定义雾参数 glFrontFace \\定义多边形的前面和背面 glFrustum \\当前矩阵乘上透视矩阵 glGenLists \\生成一组空的连续的显示列表 glGenTextures \\生成纹理名称 glGetBooleanv,glGetDoublev,glGetFloatv,glGetIntegerv \\返回值或所选参数值 glGetClipPlane \\返回特定裁减面的系数 glGetColorTableEXT \\从当前目标纹理调色板得到颜色表数据 glGetColorTableParameterfvEXT,glGetColorTableParameterivEXT \\从颜色表中得到调色板参数 glGetError \\返回错误消息 glGetLightfv,glGetLightiv \\返回光源参数值 glGetMapdv,glGetMapfv,glGetMapiv \\返回求值程序参数 glGetMaterialfv,glGetMaterialiv \\返回材质参数 glGetPixelMapfv,glGetpixelMapuiv,glGetpixelMapusv \\返回特定的像素图 glGetPointerv \\返回顶点数据数组的地址 glGetPolygonStipple \\返回多边形的点图案 glGetString \\返回描述当前OpenGl连接的字符串 glGetTexEnvfv \\返回纹理环境参数 glGetTexGendv,glGetTexGenfv,glGetTexGeniv \\返回纹理坐标生成参数 glGetTexImage \\返回一个纹理图象 glGetTexLevelParameterfv,glGetTexLevelParameteriv \\返回特定的纹理参数的细节级别 glGetTexParameterfv,glGetTexParameteriv \\返回纹理参数值 glHint \\定义实现特殊的线索 glIndex \\建立当前的色彩索引 glIndexMask \\控制写色彩索引缓冲区里的单独位 GlIndexPointer \\定义一个颜色索引数组 glInitName \\初始化名字堆栈 glInterleavedArrays \\同时定义和允许几个在一个大的数组集合里的交替数组 glIsEnabled \\定义性能是否被允许 glIsList \\检测显示列表的存在 glIsTexture \\确定一个名字对应一个纹理 glLightf,glLighti,glLightfv,glLightiv \\设置光源参数 glLightModelf,glLightModeli,glLightModelfv,glLightModeliv \\设置光线模型参数 glLineStipple \\设定线点绘图案 glLineWidth \\设定光栅线段的宽 glListBase \\为glcallList设定显示列表的基础 glLoadIdentity \\用恒等矩阵替换当前矩阵 glLoadMatrixd,glLoadMatrif \\用一个任意矩阵替换当前矩阵 glLoadName \\将一个名字调入名字堆栈 glLogicOp \\为色彩索引渲染定义一个逻辑像素操作 glMap1d,glMap1f \\定义一个一维求值程序 glMap2d,glMap2f \\定义一个二维求值程序 glMapGrid1d,glMapGrid1f,glMapgrid2d,glMapGrid2f \\定义一个一维或二维网格 glMaterialf,glMateriali,glMateriafv,glMaterialiv \\为光照模型定义材质参数 glMatrixMode \\定义哪一个矩阵是当前矩阵 glMultMatrixd,glMultMatrixf \\用当前矩阵与任意矩阵相乘 glNewList,glEndList \\创建或替换一个显示列表 glNormal \\设定当前顶点法向 glNormalPointer \\设定一个法向数组 glOrtho \\用垂直矩阵与当前矩阵相乘 glPassThrough \\在反馈缓冲区做记号 glPixelMapfv,glPixelMapuiv,glPixelMapusv \\设定像素交换图 glPixelStoref,glpixelStorei \\设定像素存储模式 glPixelTransferf,glPixelTransferi \\设定像素存储模式 glPixelZoom \\设定像素缩放因数 glPointSize \\设定光栅点的直径 glPolygonMode \\选择一个多边形的光栅模式 glPolygonOffset \\设定OpenGL用于计算深度值的比例和单元 glPolygonStipple \\设定多边形填充图案 glPrioritizeTextures \\设定纹理固定的优先级 glPushAttrib,glPopAttrib \\属性堆栈的压入和弹出操作 glPushClientAttrib,glPopClientAttrib \\在客户属性堆栈存储和恢复客户状态值 glPushmatrix,glPopMatrix \\矩阵堆栈的压入和弹出操作 glPushName,glPopName \\名字堆栈的压入和弹出操作 glRasterPos \\定义像素操作的光栅位置 glreadBuffer \\为像素选择一个源色彩缓冲区 glReadPixels \\从帧缓冲区读取一组数据 glRectd,glRectf,glRecti,glRects,glRectdv,glRectfv,glRectiv,glRectsv \\绘制一个三角形 glRenderMode \\定义光栅模式 glRotated,glRotatef \\将旋转矩阵与当前矩阵相乘 glScaled,glScalef \\将一般的比例矩阵与当前矩阵相乘 glScissor \\定义裁减框 glSelectBuffer \\为选择模式值建立一个缓冲区 glShadeModel \\选择平直或平滑着色 glStencilFunc \\为模板测试设置功能和参照值 glStencilMask \\控制在模板面写单独的位 glStencilOp \\设置激活模式测试 glTexCoord \\设置当前纹理坐标 glTexCoordPointer \\定义一个纹理坐标数组 glTexEnvf,glTexEnvi,glTexEnvfv,glTexEnviv \\设定纹理坐标环境参数 glTexGend,glTexgenf,glTexGendv,glTexGenfv,glTexGeniv \\控制纹理坐标的生成 glTexImage1D \\定义一个一维的纹理图象 glTexImage2D \\定义一个二维的纹理图 glTexParameterf,glTexParameteri,glTexParameterfv,glTexParameteriv \\设置纹理参数 glTexSubImage1D \\定义一个存在的一维纹理图像的一部分,但不能定义新的纹理 glTexSubImage2D \\定义一个存在的二维纹理图像的一部分,但不能定义新的纹理 glTranslated,glTranslatef \\将变换矩阵与当前矩阵相乘 glVertex \\定义一个顶点 glVertexPointer \\设定一个顶点数据数组 glViewport \\设置视窗 三、OpenGL实例:(实例化render就可以) public class GLRender implements Renderer{ float rotateTri,rotateQuad; int one=0x10000; //三角形的一个顶点 private IntBuffer triggerBuffer=IntBuffer.wrap(new int[]{ 0,one,0, //上顶点 -one,-one,0, //左顶点 one,-one,0 //右下点 }); //正方形的四个顶点 private IntBuffer quateBuffer=IntBuffer.wrap(new int[]{ one,one,0, -one,-one,0, one,-one,0, -one,-one,0 }); private IntBuffer colorBuffer=IntBuffer.wrap(new int[]{ one,0,0,one, 0,one,0,one, 0,0,one,one }); //用户的绘制操作在该函数中完成,注意,由于OpenGL本身是一个活动线程,所以它可以自动的绘制因旋转或者缩放平移等引起“动画”效果 @Override public void onDrawFrame(GL10 gl) { // TODO Auto-generated method stub // 清除屏幕和深度缓存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // 重置当前的模型观察矩阵 gl.glLoadIdentity(); // 左移 1.5 单位,并移入屏幕 6.0 gl.glTranslatef(-1.5f, 0.0f, -6.0f); //设置旋转 gl.glRotatef(rotateTri, 0.0f, 1.0f, 0.0f); //设置定点数组 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //设置颜色数组 gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glColorPointer(4, GL10.GL_FIXED, 0, colorBuffer); // 设置三角形顶点 gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer); //绘制三角形 gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); gl.glDisableClientState(GL10.GL_COLOR_ARRAY); //绘制三角形结束 gl.glFinish(); /***********************/ /* 渲染正方形 */ // 重置当前的模型观察矩阵 gl.glLoadIdentity(); // 左移 1.5 单位,并移入屏幕 6.0 gl.glTranslatef(1.5f, 0.0f, -6.0f); // 设置当前色为蓝色 gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); //设置旋转 gl.glRotatef(rotateQuad, 1.0f, 0.0f, 0.0f); //设置和绘制正方形 gl.glVertexPointer(3, GL10.GL_FIXED, 0, quateBuffer); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); //绘制正方形结束 gl.glFinish(); //取消顶点数组 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); //改变旋转的角度 rotateTri += 0.5f; rotateQuad -= 0.5f; } //在changed函数当中,修改由系统作出的改变值 @Override public void onSurfaceChanged(GL10 gl, int width, int height) { // TODO Auto-generated method stub float ratio = (float) width / height; //设置OpenGL场景的大小 gl.glViewport(0, 0, width, height); //设置投影矩阵 gl.glMatrixMode(GL10.GL_PROJECTION); //重置投影矩阵 gl.glLoadIdentity(); // 设置视口的大小 gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); // 选择模型观察矩阵 gl.glMatrixMode(GL10.GL_MODELVIEW); // 重置模型观察矩阵 gl.glLoadIdentity(); } //openGL的初始化操作 @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // TODO Auto-generated method stub // 启用阴影平滑 gl.glShadeModel(GL10.GL_SMOOTH); // 黑色背景 gl.glClearColor(0, 0, 0, 0); // 设置深度缓存 gl.glClearDepthf(1.0f); // 启用深度测试 gl.glEnable(GL10.GL_DEPTH_TEST); // 所作深度测试的类型 gl.glDepthFunc(GL10.GL_LEQUAL); // 告诉系统对透视进行修正 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); } } |