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

  效果图:。。。。。。

  

 编写Dad.java

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

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

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


package com.scout.eeeeeee;

/**
 * Created by liuguodong on 2017/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 stub
        mRenderer = 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();
    }
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值