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的:
最后展示一下运行结果:
OpenGL ES实现三棱锥纹理贴图相关推荐
- OpenGL ES教程VI之纹理贴图(原文对照)
注:又是一篇,是否有人能解释得清楚,2是重复两次,那么是否N就是重复N次呢?接近1.0的坐标值整数部分加上几就是重复几次吗?这个好像之前验证过不一定的. 转自:http://melord.iteye. ...
- Android Studio OpenGL ES绘制三棱锥/四面体的多纹理贴图 每个面使用一张图片渲染
本文参考了王刚的<疯狂Android讲义(第3版)>P554-P559 要求:利用OpenGL ES绘制一个三棱锥,并对每个面进行纹理贴图,每个面使用不同的图片进行渲染. 环境:Andro ...
- Android 开发使用OpenGL ES绘制三棱锥并进行纹理贴图
效果图: 直接上代码 MainActivity.java的代码 package com.zzu.shiyan3;import androidx.appcompat.app.AppCompatActiv ...
- OPENGL ES 2.0 知识串讲 (10) ——OPENGL ES 详解IV(纹理优化)
上节回顾 上一节学习了如何从一张原始图片中,获取生成纹理所需要的信息,然后根据这些信息,通过OpenGL ES API在GPU内存中生成了一张纹理,并且还介绍了纹理属性,知道了如何通过纹理坐标将纹理映 ...
- OpenGL ES 3. 天空盒 立方体贴图
大家好,接下来将为大家介绍OpenGL ES 3. 天空盒 立方体贴图. OpenGL ES 立方体贴图本质上还是纹理映射,是一种 3D 纹理映射.立方体贴图所使的纹理称为立方图纹理,它是由 6 个单 ...
- OpenGL ES 之 LUT(滤镜基准图)
前言 Look Up Table(简称LUT,查找表).输入一个值,然后通过查找表来得到一个输出值. 在调色领域中,称为颜色查找表,查找表的分量为R.G.B,是一种降低GPU运算量的技术,通过将颜色值 ...
- OpenGL着色器程序解析--纹理贴图
背景 纹理贴图意思是将任意类型的图片贴在3d模型的一个或者多个面上.图片可以是任意的但通常是一种通用的样式,比如:砖块.植物.荒芜的土地等等,可以提高场景的真实性.比较下面两幅图片: 为了实现纹理贴 ...
- 笔谈OpenGL ES(三)
昨天下午以及今天一天,公司安排了新员工培训课程,占用了自己的一些时间,但是也了解到一些新的有利于自身的东西.进公司就要进有完善公司体系和制度的公司,小公司真的是没搞头的,我体验过,反正小公司以后是不会 ...
- Android OpenGL ES (八)纹理绘制
基本原理 与渐变色接近,但有些区别: 渐变色:光栅化过程中,计算出颜色值,然后在片段着色器的时候可以直接赋值 纹理:光栅化过程中,计算出当前片段在纹理上的坐标位置,然后在片段着色器的中,根据这个纹理上 ...
最新文章
- Android DDMS应用
- datatables php数据,html5 - datatables 加载不出来数据。
- IIS托管管道模式的集成和经典
- 求助:如何获取ueditor的上传路径
- C++设计模式之Adapter
- 为什么要挖Chia币
- delphi列举用户
- 关于视频监控线缆的常识
- 计算机网络电缆是什么,插入Cat的计算机网络电缆和插入路由器的计算机的网络电缆有什么区别?...
- 多媒体会议系统中的延迟
- Struts框架命名空间问题答疑
- 计算机网络线路故障及排查方法,计算机网络常见故障排查
- 软件项目管理:使用PERT评价不确定性的方法
- 区块链在版权保护方面的探索与实践
- stm32 带通滤波器_PCB设计中建立带通滤波器波特图
- 车辆出险理赔记录接口文档
- 阿里、华为和微软等多家国内外厂商组团搞OpenJDK,Oracle为啥不参加?
- TWaver三维可视化管理软件、3D和2D开发工具软件的试用(申请试用的回复邮件)
- Android App启动流程详解
- Tomcat之——宕机自动重启和每日定时启动tomcat
热门文章
- 计算机无法投影,如果无法连接计算机和投影仪怎么办
- 【学习笔记】多线程进阶JUC
- Shell语言基本语法总结(4)正则表达式与文本处理之grep
- mysql leng() 与 char_length() 的区别,注意一下。
- 关于idea+mybatis+springcloud+swagger2+Apollo 踩得小坑
- blos设置具体解释
- 短信验证(手机号注册,绑定手机号获取验证码)
- MMORPG游戏中AOI视野算法解析
- 洋码头API接口:item_search - 根据关键词取商品列表
- 什么样的人适合做外贸?