1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > android 使用OPENGL ES实现三角形纹理贴图效果-纹理映射基础

android 使用OPENGL ES实现三角形纹理贴图效果-纹理映射基础

时间:2020-03-25 12:58:45

相关推荐

android 使用OPENGL ES实现三角形纹理贴图效果-纹理映射基础

效果图:。。。。。。

编写Dad.java

*在Dad构造器中创建和设置场景渲染器为主动渲染,并设置重写触屏时间回调方法以记录触控笔坐标,改变三角形坐标系的位置,使三角形能够在场景中转动

*为声明场景渲染类,在该类中首先设置场景属性,移动坐标系可以绘制三角形

*定义生成纹理ID的方法initTexture,该方法通过接受图片ID和gl引用,将图片转换成Bitmap

package com.scout.eeeeeee;/** * Created by liuguodong on /10/28. */import java.io.IOException;import java.io.InputStream;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.opengl.GLSurfaceView;import android.opengl.GLUtils;import android.view.MotionEvent;public class dad extends GLSurfaceView{ private SceneRenderer mRenderer;//场景渲染器 private float mPreviousY;//上次的触控位置Y坐标 private float mPreviousX;//上次的触控位置X坐标 private float TOUCH_SCALE_FACTOR=180.0f/320;;//角度缩放比例 public int textureId;//纹理的名称ID public dad(Context context) { super(context); //TODO Auto-generated constructor stubmRenderer=new SceneRenderer(); //创建场景渲染器 setRenderer(mRenderer); //设置渲染器 setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//设置渲染模式为主动渲染 } @Override public boolean onTouchEvent(MotionEvent e) { float y=e.getY(); float x=e.getX(); switch (e.getAction()) { case MotionEvent.ACTION_MOVE:float dy=y-mPreviousY;//计算触控笔Y位移float dx=x-mPreviousX;//计算触控笔Y位移mRenderer.texTri.jiaoY+=dy*TOUCH_SCALE_FACTOR;//设置沿x轴旋转角度mRenderer.texTri.mAngleZ+=dx*TOUCH_SCALE_FACTOR;//设置沿z轴旋转角度requestRender();//重绘画面 } mPreviousY=y;//记录触控笔位置 mPreviousX=x;//记录触控笔位置 return true; } private class SceneRenderer implements GLSurfaceView.Renderer { yisuo texTri; int textureId; @Override public void onDrawFrame(GL10 gl) { //TODO Auto-generated method stub//清除颜色缓存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT); //设置当前矩阵为模式矩阵 gl.glMatrixMode(GL10.GL_MODELVIEW); //设置当前矩阵为单位矩阵 gl.glLoadIdentity(); gl.glTranslatef(0, 0f,-2.5f); texTri.drawSelf(gl); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { //TODO Auto-generated method stub//设置视窗大小及位置 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, 20); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { //TODO Auto-generated method stub//关闭抗抖动 gl.glDisable(GL10.GL_DITHER); //设置特定Hint项目的模式,这里为设置为使用快速模式 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST); //设置屏幕背景色黑色RGBA gl.glClearColor(0,255,255,0); //打开背面剪裁 //gl.glEnable(GL10.GL_CULL_FACE); //设置着色模型为平滑着色 gl.glShadeModel(GL10.GL_SMOOTH);//GL10.GL_SMOOTH GL10.GL_FLAT //启用深度测试 gl.glEnable(GL10.GL_DEPTH_TEST); //初始化纹理 textureId=initTexture(gl,R.drawable.su); texTri=new yisuo(textureId); } } public int initTexture(GL10 gl,int textureId)//textureId { int[] textures=new int[1]; gl.glGenTextures(1, textures, 0); int currTextureId=textures[0]; gl.glBindTexture(GL10.GL_TEXTURE_2D, currTextureId); 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); InputStream is=this.getResources().openRawResource(textureId); Bitmap bitmapTmp; try { bitmapTmp=BitmapFactory.decodeStream(is); } finally { try {is.close(); } catch(IOException e) {e.printStackTrace(); } } GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmapTmp, 0); bitmapTmp.recycle(); return currTextureId; }}

编写yisuo.java,定义三角形类Texture

*创建顶点数组,并将顶点数组放入顶点缓冲区内,为绘制三角形做好准备

*创建纹理坐标数组,并将纹理数组放入纹理坐标缓冲区内,为绘三角形做好准备

*绘制三角形

package com.scout.eeeeeee;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import java.nio.IntBuffer;import javax.microedition.khronos.opengles.GL10;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import java.nio.IntBuffer;import javax.microedition.khronos.opengles.GL10;public class yisuo { private IntBuffer mVertexBuffer;//顶点坐标数据缓冲 private FloatBuffer mTextureBuffer;//顶点纹理数据缓冲 public float jiaoY;//沿y轴旋转角度 public float mAngleZ;//沿z轴旋转角度 int vCount=0;//顶点数量 int textureId; public yisuo(int textureId) { this.textureId=textureId; //顶点坐标数据的初始化 final int UNIT_SIZE=30000; vCount=3;//顶点的数量 int vertices[]=new int[]//顶点坐标数据数组{ 2*UNIT_SIZE,0,0,-2*UNIT_SIZE,0,0, 0,4*UNIT_SIZE,0}; //创建顶点坐标数据缓冲 //vertices.length*4是因为一个整数四个字节 ByteBuffer vbb=ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder());//设置字节顺序 mVertexBuffer=vbb.asIntBuffer();//转换为int型缓冲 mVertexBuffer.put(vertices);//向缓冲区中放入顶点坐标数据 mVertexBuffer.position(0);//设置缓冲区起始位置 //初始化顶点纹理数据的 float textureCoors[]=new float[]//顶点纹理S、T坐标值数组{ 0,1, 1,1, 0.5f,0}; //创建顶点纹理数据缓冲 ByteBuffer cbb=ByteBuffer.allocateDirect(textureCoors.length*4); cbb.order(ByteOrder.nativeOrder());//设置字节顺序 mTextureBuffer=cbb.asFloatBuffer();//转换为int型缓冲 mTextureBuffer.put(textureCoors);//向缓冲区中放入顶点着色数据 mTextureBuffer.position(0);//设置缓冲区起始位置 } public void drawSelf(GL10 gl) { gl.glRotatef(mAngleZ, 0, 0, 1);//沿Z轴旋转 gl.glRotatef(jiaoY, 0, 1, 0);//沿Y轴旋转 //顶点坐标,允许使用顶点数组 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); //为画笔指定顶点坐标数据 gl.glVertexPointer( 3,//每个顶点的坐标数量为3 xyz GL10.GL_FIXED, //顶点坐标值的类型为 GL_FIXED 0, //连续顶点坐标数据之间的间隔 mVertexBuffer //顶点坐标数据); //开启纹理 gl.glEnable(GL10.GL_TEXTURE_2D); //允许使用纹理数组 gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); //为画笔指定纹理uv坐标数据 gl.glTexCoordPointer( 2, //每个顶点两个纹理坐标数据 S、T GL10.GL_FLOAT, //数据类型 0, //连续纹理坐标数据之间的间隔 mTextureBuffer //纹理坐标数据); //为画笔绑定指定名称ID纹理 gl.glBindTexture(GL10.GL_TEXTURE_2D,textureId); //绘制图形 gl.glDrawArrays( GL10.GL_TRIANGLES, 0, vCount); gl.glDisable(GL10.GL_TEXTURE_2D);//关闭纹理 }}

wenCH.java

package com.scout.eeeeeee;import android.app.Activity;import android.os.Bundle;import android.app.Activity;import android.os.Bundle;public class wenCH extends Activity { /** Called when the activity is first created. */ dad mGLSurfaceView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mGLSurfaceView=new dad(this); setContentView(mGLSurfaceView); mGLSurfaceView.requestFocus();//获取焦点 mGLSurfaceView.setFocusableInTouchMode(true);//设置为可触控 } @Override protected void onResume() { super.onResume(); mGLSurfaceView.onResume(); } @Override protected void onPause() { super.onPause(); mGLSurfaceView.onPause(); }}

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