1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > OpenGL ES实现三棱锥纹理贴图

OpenGL ES实现三棱锥纹理贴图

时间:2022-04-12 22:14:10

相关推荐

OpenGL ES实现三棱锥纹理贴图

这是老师布置的课后作业,闲来无事分享出来,也加深一遍自己的印象~

自己定义一个MyRenderer.java类:

package com.example.shiyan3_2;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.opengl.GLSurfaceView.Renderer;import android.opengl.GLUtils;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import java.nio.IntBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;public class MyRenderer implements Renderer{// 定义三棱椎的4个顶点float[] taperVertices = new float[] {0.0f, 0.5f, 0.0f,-0.5f, -0.5f, -0.2f,0.5f, -0.5f, -0.2f,0.0f, -0.2f, 0.2f};// 定义三棱椎的4个三角面(没有使用)private byte[] taperFacets = new byte[]{0, 1, 2, // 0、1、2三个顶点组成一个面0, 1, 3, // 0、1、3三个顶点组成一个面1, 2, 3, // 1、2、3三个顶点组成一个面0, 2, 3 // 0、2、3三个顶点组成一个面};//定义纹理贴图的坐标数据private float[] taperTextures = {1.0000f,1.0000f,1.0000f,0.0000f,0.0000f,0.0000f,0.0000f,1.0000f};// 分别定义三棱椎的4个三角面ByteBuffer i1=ByteBuffer.wrap(new byte[]{0,1,2,});ByteBuffer i2=ByteBuffer.wrap(new byte[]{0,1,3,});ByteBuffer i3=ByteBuffer.wrap(new byte[]{1,2,3});ByteBuffer i4=ByteBuffer.wrap(new byte[]{0,2,3,});Context context;// 定义Open GL ES绘制所需要的Buffer对象FloatBuffer taperVerticesBuffer;//IntBuffer taperColorsBuffer;ByteBuffer taperFacetsBuffer;FloatBuffer taperTexturesBuffer;// 控制旋转的角度private float rotate;//定义本程序所使用的纹理private int texture;public MyRenderer(Context main){this.context = main;// 将三棱椎的顶点位置数据数组包装成FloatBuffertaperVerticesBuffer = floatBufferUtil(taperVertices);// 将三棱椎的4个面的数组包装成ByteBuffertaperFacetsBuffer = ByteBuffer.wrap(taperFacets);//将立方体的纹理贴图的坐标数据包装成FLoatBuffertaperTexturesBuffer = floatBufferUtil(taperTextures);}@Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config){// 关闭抗抖动gl.glDisable(GL10.GL_DITHER);// 设置系统对透视进行修正gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);gl.glClearColor(0, 0, 0, 0);// 设置阴影平滑模式gl.glShadeModel(GL10.GL_SMOOTH);// 启用深度测试gl.glEnable(GL10.GL_DEPTH_TEST);// 设置深度测试的类型gl.glDepthFunc(GL10.GL_LEQUAL);//启用2D纹理贴图gl.glEnable(GL10.GL_TEXTURE_2D);//装载纹理loadTexture(gl);}@Overridepublic void onSurfaceChanged(GL10 gl, int width, int height){// 设置3D视窗的大小及位置gl.glViewport(0, 0, width, height);// 将当前矩阵模式设为投影矩阵gl.glMatrixMode(GL10.GL_PROJECTION);// 初始化单位矩阵gl.glLoadIdentity();// 计算透视视窗的宽度、高度比float ratio = (float) width / height;// 调用此方法设置透视视窗的空间大小。gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);}// 绘制图形的方法int[] tex_id = new int[4];@Overridepublic void onDrawFrame(GL10 gl){// 清除屏幕缓存和深度缓存gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 启用顶点坐标数据gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//启用贴图坐标数组数据gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // ①// 设置当前矩阵模式为模型视图。gl.glMatrixMode(GL10.GL_MODELVIEW);// --------------------绘制图形---------------------// 重置当前的模型视图矩阵gl.glLoadIdentity();gl.glTranslatef(0.0f, 0.0f, -1.5f);// 沿着Y轴旋转gl.glRotatef(rotate, 0f, 0.2f, 0f);// 设置顶点的位置数据gl.glVertexPointer(3, GL10.GL_FLOAT, 0, taperVerticesBuffer);//设置贴图的坐标数据gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, taperTexturesBuffer); // ②//执行纹理贴图gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[0]); // ③// 按taperFacetsBuffer指定的面绘制三角形gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, i1.remaining(),GL10.GL_UNSIGNED_BYTE, i1);gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[1]); // ③// 按taperFacetsBuffer指定的面绘制三角形gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, i2.remaining(),GL10.GL_UNSIGNED_BYTE, i2);gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[2]); // ③// 按taperFacetsBuffer指定的面绘制三角形gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, i3.remaining(),GL10.GL_UNSIGNED_BYTE, i3);gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[3]); // ③// 按taperFacetsBuffer指定的面绘制三角形gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, i4.remaining(),GL10.GL_UNSIGNED_BYTE, i4);// 绘制结束gl.glFinish();//禁用顶点、纹理坐标数组gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);// 旋转角度增加1rotate+=1;}private void loadTexture(GL10 gl){// 加载位图Bitmap[] bm = new Bitmap[4];bm[0]=BitmapFactory.decodeResource(context.getResources(),R.drawable.img1);bm[1]=BitmapFactory.decodeResource(context.getResources(),R.drawable.img2);bm[2]=BitmapFactory.decodeResource(context.getResources(),R.drawable.img3);bm[3]=BitmapFactory.decodeResource(context.getResources(),R.drawable.img4);try{int[] textures = new int[1];// 指定生成N个纹理(第一个参数指定生成一个纹理)// textures数组将负责存储所有纹理的代号IntBuffer textureBuffer = IntBuffer.allocate(4);gl.glGenTextures(4,textureBuffer);tex_id = textureBuffer.array();for(int i=0;i<4;i++){// 获取textures纹理数组中的第一个纹理//texture = textures[i];// 通知OpenGL将texture纹理绑定到GL10.GL_TEXTURE_2D目标中gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[i]);//gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);// 设置纹理被缩小(距离视点很远时被缩小)时的滤波方式gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);// 设置纹理被放大(距离视点很近时被方法)时的滤波方式gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);// 设置在横向、纵向上都是平铺纹理gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,GL10.GL_REPEAT);gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);// 加载位图生成纹理GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bm[i], 0);if (bm[i] != null)bm[i].recycle();}}finally {//生成纹理之后,回收位图}}// 定义一个工具方法,将float[]数组转换为OpenGL ES所需的FloatBufferprivate FloatBuffer floatBufferUtil(float[] arr){FloatBuffer mBuffer;// 初始化ByteBuffer,长度为arr数组的长度*4,因为一个int占4个字节ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);// 数组排列用nativeOrderqbb.order(ByteOrder.nativeOrder());mBuffer = qbb.asFloatBuffer();mBuffer.put(arr);mBuffer.position(0);return mBuffer;}}

接下来是MainActivity.java:

package com.example.shiyan3_2;import android.app.Activity;import android.opengl.GLSurfaceView;import android.os.Bundle;public class MainActivity extends Activity{@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);// 创建一个GLSurfaceView,用于显示OpenGL绘制的图形GLSurfaceView glView = new GLSurfaceView(this);// 创建GLSurfaceView的内容绘制器MyRenderer myRender = new MyRenderer(this);// 为GLSurfaceView设置绘制器glView.setRenderer(myRender);setContentView(glView);}}

记得加入纹理贴图,这里图片的格式是256x256的:

最后展示一下运行结果:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。