Android的OpenGL学习笔记(2)
16lz
2021-01-23
Android的OpenGL学习笔记(2)
上篇主要目的是介绍OpenGL的基本框架,这里就用基本的框架绘画出一个三角形,绘制三角形在OpenGL中比较重要,因为在OpenGL(Android)中的图形都是用三角形拼凑起来的!
画三角形有两种,主要是调用的方法不同而已:
第一种,调用glDrawElements()方法绘画:
看代码,主要看继承GLSurfaceView的代码部分,其他的和上篇基本一样:
VortexRenderer.java
Code:- packagecom.droidnova.android.games.vortex;
- importjava.nio.ByteBuffer;
- importjava.nio.ByteOrder;
- importjava.nio.FloatBuffer;
- importjava.nio.ShortBuffer;
- importjavax.microedition.khronos.egl.EGLConfig;
- importjavax.microedition.khronos.opengles.GL10;
- importandroid.opengl.GLSurfaceView;
- publicclassVortexRendererimplementsGLSurfaceView.Renderer{
- //privatestaticfinalStringLOG_TAG=VortexRenderer.class.getSimpleName();
- privatefloat_red=0f;
- privatefloat_green=0f;
- privatefloat_blue=0f;
- //arawbuffertoholdindicesallowingareuseofpoints.
- privateShortBuffer_indexBuffer;
- //arawbuffertoholdthevertices
- privateFloatBuffer_vertexBuffer;
- privateshort[]_indicesArray={0,1,2};//关于索引的理解:即三角形三个顶点的索引,这里暂时画了一个平面二维的三角形,
- //看不出它的作用,当画三维的时候,就会清楚了,这里大概提一下,索引组合可以构成一个面!相当于三个点可以构成一个面,这里用索引代替了三个点而已!
- privateint_nrOfVertices=3;
- privatefloat_angle;
- @Override
- publicvoidonSurfaceCreated(GL10gl,EGLConfigconfig){
- //preparation
- gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
- initTriangle();
- }
- @Override
- publicvoidonSurfaceChanged(GL10gl,intw,inth){
- gl.glViewport(0,0,w,h);
- }
- @Override
- publicvoidonDrawFrame(GL10gl){
- //definethecolorwewanttobedisplayedasthe"clippingwall"
- gl.glClearColor(_red,_green,_blue,1.0f);
- gl.glLoadIdentity();//还原场景,还原矩阵。假如你旋转一个三角形之后,调用这个方法,
- //可以让该三角形还原到初始位置,这里的主要作用是为了防止三角形不停的旋转。
- //clearthecolorbuffertoshowtheClearColorwecalledabove...
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
- //setrotation
- gl.glRotatef(_angle,0f,1f,0f);//旋转时需要进行3D图像到2D的转换,需要进行浮点运算,
- //会有偏差,所以随着时间的延长,三角形的顶点有偏移现象,暂时就这么理解着!
- gl.glColor4f(0.5f,0f,0f,0.5f);//对三角形进行着色!
- gl.glVertexPointer(3,GL10.GL_FLOAT,0,_vertexBuffer);//第三个参数表示在数组元素中,两个有意义的数据单元之间相隔的字节数。
- //当值为0时,表示该数组数据是紧密排列的,没有间隔
- gl.glDrawElements(GL10.GL_TRIANGLES,_nrOfVertices,GL10.GL_UNSIGNED_SHORT,_indexBuffer);
- }
- privatevoidinitTriangle(){
- //floathas4bytes
- ByteBuffervbb=ByteBuffer.allocateDirect(_nrOfVertices*3*4);
- vbb.order(ByteOrder.nativeOrder());
- _vertexBuffer=vbb.asFloatBuffer();//将字节Buffer转换为FloatBuffer,暂时这么理解的!
- //shorthas2bytes
- ByteBufferibb=ByteBuffer.allocateDirect(_nrOfVertices*2);//申请空间
- ibb.order(ByteOrder.nativeOrder());//必须设置为原生字节序!
- _indexBuffer=ibb.asShortBuffer();
- float[]coords={
- -0.5f,-0.5f,0f,//(x1,y1,z1)
- 0.5f,-0.5f,0f,//(x2,y2,z2)
- 0f,0.5f,0f//(x3,y3,z3)
- };
- _vertexBuffer.put(coords);
- _indexBuffer.put(_indicesArray);
- _vertexBuffer.position(0);
- _indexBuffer.position(0);
- }
- publicvoidsetColor(floatr,floatg,floatb){
- _red=r;
- _green=g;
- _blue=b;
- }
- publicvoidsetAngle(floatangle){
- _angle=angle;
- }
- }
VortexView.java
Code:- packagecom.droidnova.android.games.vortex;
- importandroid.content.Context;
- importandroid.opengl.GLSurfaceView;
- importandroid.view.MotionEvent;
- publicclassVortexViewextendsGLSurfaceView{
- //privatestaticfinalStringLOG_TAG=VortexView.class.getSimpleName();
- privateVortexRenderer_renderer;
- publicVortexView(Contextcontext){
- super(context);
- _renderer=newVortexRenderer();
- setRenderer(_renderer);
- }
- publicbooleanonTouchEvent(finalMotionEventevent){
- queueEvent(newRunnable(){
- publicvoidrun(){
- _renderer.setColor(event.getX()/getWidth(),event.getY()
- /getHeight(),1.0f);
- _renderer.setAngle(event.getX());
- }
- });
- returntrue;
- }
- }
第二种,调用glDrawArrays()绘画三角形:
GLRender.java代码:
Code:- packagecom.android.myOpenGL;
- importjava.nio.ByteBuffer;
- importjava.nio.ByteOrder;
- importjava.nio.FloatBuffer;
- importjavax.microedition.khronos.egl.EGLConfig;
- importjavax.microedition.khronos.opengles.GL10;
- importandroid.opengl.GLSurfaceView.Renderer;
- publicclassGLRenderimplementsRenderer{
- privatefloat_red=0.9f;
- privatefloat_green=0.2f;
- privatefloat_blue=0.2f;
- privatefloat_angle;
- privateFloatBuffer_vertexBuffer;
- privateint_nrOfVertices=3;
- @Override
- publicvoidonDrawFrame(GL10gl){
- //TODOAuto-generatedmethodstub
- gl.glClearColor(_red,_green,_blue,1.0f);
- gl.glLoadIdentity();//如果注释掉这句,效果将如同地球绕太阳旋转一样,自身旋转,也绕太阳公转,注意三角形分正反面
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
- gl.glTranslatef(0.5f,0f,0f);
- gl.glRotatef(_angle,0f,1f,0f);//绕Y轴旋转,Y轴正方向单位1处,X,Y,Z三个参数共同决定讯转轴的方向。
- _angle++;//为了测试旋转平移的先后顺序会对结果造成何种影响添加上的,这样也可以让三角形不停的旋转,一般我喜欢这么做!
- /*
- *先旋转还是先平移,顺序不同,效果也会不同的,具体怎么样的效果,自己运行一下程序,并改变次序,就会得到结果!
- */
- gl.glColor4f(0.5f,0f,0f,0.5f);
- gl.glVertexPointer(3,GL10.GL_FLOAT,0,_vertexBuffer);
- gl.glDrawArrays(GL10.GL_TRIANGLES,0,3);
- //gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//取消顶点设置,如果在这里添加这句,三角形会一闪而过。为了显示三角形,我们注释掉这句话。
- }
- @Override
- publicvoidonSurfaceChanged(GL10gl,intwidth,intheight){
- //TODOAuto-generatedmethodstub
- gl.glViewport(0,0,width,height);
- }
- @Override
- publicvoidonSurfaceCreated(GL10gl,EGLConfigarg1){
- //TODOAuto-generatedmethodstub
- gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
- initTriangle();
- }
- privatevoidinitTriangle(){
- //floathas4bytes
- ByteBuffervbb=ByteBuffer.allocateDirect(_nrOfVertices*3*4);
- vbb.order(ByteOrder.nativeOrder());
- _vertexBuffer=vbb.asFloatBuffer();
- float[]coords={
- -0.5f,-0.5f,0f,//(x1,y1,z1)
- 0.5f,-0.5f,0f,//(x2,y2,z2)
- 0f,0.5f,0f//(x3,y3,z3)
- };
- _vertexBuffer.put(coords);
- _vertexBuffer.position(0);
- }
- publicvoidsetColor(floatr,floatg,floatb){
- _red=r;
- _green=g;
- _blue=b;
- }
- publicvoidsetAngle(floatangle){
- _angle=angle;
- }
- }
最终效果图都是一样的,如图:
必要的解释都在代码注释中,如有问题,请留言提出,如有错误,也同样请留言指出,小弟感激不尽……
更多相关文章
- 【eoeAndroid社区索引】Android二维码知识汇总
- [置顶] 【Android Notes】置顶索引
- Joggler索引页
- Android drawable 三角形
- 关于android实现fastindexbar(快速索引)详解
- Android 之 Fast Scroll 、字母索引栏
- Android下使用OpenGL绘制三角形
- Android ListView城市列表,按a-z分组字母索引排序
- LXR 索引Android 源码