看到了
Android OpenGL开发四棱锥和立方体之后,我们是不是增加了使用OpenGL开发图形的兴趣啊,呵呵,希望大家保持热情啊,今天我们接着给已经画好的立方体进行文理处理,效果图如下:
可以看到,我们对正方体做了如下处理:
- 给正方体增加3轴旋转功能;
- 给正方体添加纹理;
- 注意点:真机上不显示纹理贴图的解决办法~~ Android OpenGL给立方体进行纹理映射时真机一片空白
具体如何实现,我们接着看~~~
Java代码
- //当窗口被创建时我们可以做些初始化工作
- @Override
- publicvoidonSurfaceCreated(GL10gl,EGLConfigconfig){
- //TODOAuto-generatedmethodstub
- //设置清除屏幕时所用的颜色,参数依次为红、绿、蓝、Alpha值
- gl.glClearColor(0,0,0,0);
- gl.glEnable(GL10.GL_CULL_FACE);
- //启用阴影平滑
- gl.glShadeModel(GL10.GL_SMOOTH);
- gl.glEnable(GL10.GL_DEPTH_TEST);//启用深度测试
- //以下是关于深度缓存的设置,非常重要
- gl.glClearDepthf(1.0f);//设置深度缓存
- gl.glDepthFunc(GL10.GL_LEQUAL);//所做深度测试的类型
- //告诉系统对透视进行修正
- gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
- //允许2D贴图
- gl.glEnable(GL10.GL_TEXTURE_2D);
- IntBufferintBuffer=IntBuffer.allocate(1);
- //创建纹理
- gl.glGenTextures(1,intBuffer);
- texture=intBuffer.get();
- //设置需要使用的纹理
- gl.glBindTexture(GL10.GL_TEXTURE_2D,texture);
- Bitmapbmp=BitmapFactory.decodeResource(getResources(),R.drawable.test);
- //生成纹理
- GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bmp,0);
- //线形滤波
- gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
- gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
- }
在onSurfaceChanged方法中,我们需要做一些处理,主要有如下两个方法:
Java代码
- //创建纹理
- gl.glGenTextures(1,intBuffer);
这个方法是主要用来创建一个文理,参数1表示数量1,参数intBuffer是文理代号;
Java代码
- gl.glBindTexture(GL10.GL_TEXTURE_2D,texture);
- Bitmapbmp=BitmapFactory.decodeResource(getResources(),R.drawable.test);
- //生成纹理
- GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bmp,0);
- //线形滤波
- gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
- gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
- }
- 接着绑定需要该纹理的target,在onSurfaceChanged方法之后,我们再在onDrawFrame方法中着色和旋转,完全代码如下:
- packageorg.ourunix.android.opengltest;
- importjava.nio.ByteBuffer;
- importjava.nio.ByteOrder;
- importjava.nio.IntBuffer;
- importjavax.microedition.khronos.egl.EGLConfig;
- importjavax.microedition.khronos.opengles.GL10;
- importandroid.app.Activity;
- importandroid.graphics.Bitmap;
- importandroid.graphics.BitmapFactory;
- importandroid.opengl.GLSurfaceView;
- importandroid.opengl.GLUtils;
- importandroid.opengl.GLSurfaceView.Renderer;
- importandroid.os.Bundle;
- publicclassOpenGLTestActivityextendsActivity{
- /**Calledwhentheactivityisfirstcreated.*/
- @Override
- publicvoidonCreate(BundlesavedInstanceState){
- super.onCreate(savedInstanceState);
- GLSurfaceViewglView=newGLSurfaceView(this);
- glView.setRenderer(newGLRender());
- setContentView(glView);
- }
- publicclassGLRenderimplementsRenderer{
- privateinttexture=-1;
- privateintone=0x10000;
- privateint[]quarter={-one,-one,one,
- one,-one,one,
- one,one,one,
- -one,one,one,
- -one,-one,-one,
- -one,one,-one,
- one,one,-one,
- one,-one,-one,
- -one,one,-one,
- -one,one,one,
- one,one,one,
- one,one,-one,
- -one,-one,-one,
- one,-one,-one,
- one,-one,one,
- -one,-one,one,
- one,-one,-one,
- one,one,-one,
- one,one,one,
- one,-one,one,
- -one,-one,-one,
- -one,-one,one,
- -one,one,one,
- -one,one,-one,};
- privateint[]texCoords={one,0,0,0,0,one,one,one,
- 0,0,0,one,one,one,one,0,
- one,one,one,0,0,0,0,one,
- 0,one,one,one,one,0,0,0,
- 0,0,0,one,one,one,one,0,
- one,0,0,0,0,one,one,one,};
- //准备正方体顶点
- privateIntBufferquarterBuffer=BufferUtil.iBuffer(quarter);
- //纹理映射数据
- privateIntBuffertexCoordsBuffer=BufferUtil.iBuffer(texCoords);
- ByteBufferindicesBuffer=ByteBuffer.wrap(newbyte[]{
- 0,1,3,2,
- 4,5,7,6,
- 8,9,11,10,
- 12,13,15,14,
- 16,17,19,18,
- 20,21,23,22,
- });
- privatefloatrotateX;//用于正方体x轴的旋转;
- privatefloatrotateY;//用于正方体y轴的旋转;
- privatefloatrotateZ;//用于正方体z轴的旋转;
- //咳,咳现在开始画图了
- @Override
- publicvoidonDrawFrame(GL10gl){
- //TODOAuto-generatedmethodstub
- //清楚屏幕和深度缓存
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
- //重置当前的观察模型矩阵
- gl.glLoadIdentity();
- //现将屏幕向里移动,用来画正方体
- gl.glTranslatef(0.0f,0.0f,-6.0f);
- //设置3个方向的旋转
- gl.glRotatef(rotateX,1.0f,0.0f,0.0f);
- gl.glRotatef(rotateY,0.0f,1.0f,0.0f);
- gl.glRotatef(rotateZ,0.0f,0.0f,1.0f);
- //通知opnegl将文理名字texture绑定到指定的纹理目标上GL10.GL_TEXTURE_2D
- gl.glBindTexture(GL10.GL_TEXTURE_2D,texture);
- gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
- //纹理的使用与开启颜色渲染一样,需要开启纹理功能
- gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
- //设置正方体各顶点
- gl.glVertexPointer(3,GL10.GL_FIXED,0,quarterBuffer);
- gl.glTexCoordPointer(2,GL10.GL_FIXED,0,texCoordsBuffer);
- //绘制
- gl.glDrawElements(GL10.GL_TRIANGLE_STRIP,24,GL10.GL_UNSIGNED_BYTE,indicesBuffer);
- gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
- gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
- rotateX+=0.5f;
- rotateY+=0.6f;
- rotateZ+=0.3f;
- }
- //当窗口改变时,调用,至少在创建窗口时调用一次,这边设置下场景大小
- @Override
- publicvoidonSurfaceChanged(GL10gl,intwidth,intheight){
- //TODOAuto-generatedmethodstub
- //设置OpenGL场景大小
- floatratio=(float)width/height;
- 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();
- }
- //当窗口被创建时我们可以做些初始化工作
- @Override
- publicvoidonSurfaceCreated(GL10gl,EGLConfigconfig){
- //TODOAuto-generatedmethodstub
- //设置清除屏幕时所用的颜色,参数依次为红、绿、蓝、Alpha值
- gl.glClearColor(0,0,0,0);
- gl.glEnable(GL10.GL_CULL_FACE);
- //启用阴影平滑
- gl.glShadeModel(GL10.GL_SMOOTH);
- gl.glEnable(GL10.GL_DEPTH_TEST);//启用深度测试
- //以下是关于深度缓存的设置,非常重要
- gl.glClearDepthf(1.0f);//设置深度缓存
- gl.glDepthFunc(GL10.GL_LEQUAL);//所做深度测试的类型
- //告诉系统对透视进行修正
- gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
- //允许2D贴图
- gl.glEnable(GL10.GL_TEXTURE_2D);
- IntBufferintBuffer=IntBuffer.allocate(1);
- //创建纹理
- gl.glGenTextures(1,intBuffer);
- texture=intBuffer.get();
- //设置需要使用的纹理
- gl.glBindTexture(GL10.GL_TEXTURE_2D,texture);
- Bitmapbmp=BitmapFactory.decodeResource(getResources(),R.drawable.test);
- //生成纹理
- GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,bmp,0);
- //线形滤波
- gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR);
- gl.glTexParameterx(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);
- }
- }
- publicstaticclassBufferUtil{
- publicstaticIntBufferintBuffer;
- publicstaticIntBufferiBuffer(int[]a){
- //先初始化buffer,数组的长度*4,因为一个float占4个字节
- ByteBuffermbb=ByteBuffer.allocateDirect(a.length*4);
- //数组排列用nativeOrder
- mbb.order(ByteOrder.nativeOrder());
- intBuffer=mbb.asIntBuffer();
- intBuffer.put(a);
- intBuffer.position(0);
- returnintBuffer;
- }
- }
- }