zoukankan      html  css  js  c++  java
  • [Android]OpenGL ES实现三角形/四边形2D/3D绘制

    代码:

    1. MainActivity.java

    package home.lee.openglesdemo1;

    import java.nio.Buffer;
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.IntBuffer;

    import javax.microedition.khronos.egl.EGLConfig;
    import javax.microedition.khronos.opengles.GL10;

    import android.app.Activity;
    import android.opengl.GLSurfaceView;
    import android.opengl.GLSurfaceView.Renderer;
    import android.os.Bundle;
    import android.util.Log;

    public class MainActivity extends Activity {

    public static final String TAG = "Ray OpenGL ES";
    public float roateTri;
    public float roateQuad;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //setContentView(R.layout.activity_main);

    GLSurfaceView mGLSurfaceView = new GLSurfaceView(this);
    mGLSurfaceView.setRenderer(new OpenGLRender());
    setContentView(mGLSurfaceView);
    }

    public class OpenGLRender implements Renderer{
    int one = 0x10000;//系统将取坐标值的高16位
    // public IntBuffer triangleBuffer = IntBuffer.wrap(new int[]{
    // 0,one,0,
    // -one,-one,0,
    // one,-one,0});
    int [] triangleArray ={
    0,one,0,
    -one,-one,0,
    one,-one,0};

    int [] colorArray = {
    one,0,0,one,
    0,one,0,one,
    0,0,one,one};

    int [] quaterArray = {
    one,one,0,
    -one,one,0,
    one,-one,0,
    -one,-one,0};

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    // 初始化工作、设置顶点坐标的值等
    // 告诉系统对透视进行修正,会使透视图看起来好看点
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
    // 启用阴影平滑
    //gl.glShadeModel(GL10.GL_SMOOTH);
    // 黑色背景
    gl.glClearColor(0, 0, 0, 0);//红,绿,蓝,apaha
    // 启动阴影平滑
    gl.glShadeModel(GL10.GL_SMOOTH);
    // 设置深度缓存
    gl.glClearDepthf(1.0f);
    // 启用深度测试
    gl.glEnable(GL10.GL_DEPTH_TEST);
    // 所作深度测试的类型
    gl.glDepthFunc(GL10.GL_LEQUAL);

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {// 3D图形的画布,画布的宽度,画布的高度
    // 当窗口大小发生改变时系统将调用 onSurfaceChanged方法,可以在该方法中设置 OpenGL场景大小
    // 设置视口大小、投影类型、矩阵模式、切换投影类型等

    Log.i(TAG, "onSurfaceChanged "+width+" height:"+height);

    // 试图的长宽比例必须和投影坐标x,y轴的刻度比例相同,否则绘制的刻度比例将变形
    float ratio = (float) width / height;
    ////// 视口的宽高度和画布的宽高度相同-设置OpenGL场景的大小
    gl.glViewport(0, 0, width, height);
    // 改为投影矩阵模式
    gl.glMatrixMode(GL10.GL_PROJECTION);//投影矩阵负责为场景增加透视度
    // 设为单位矩阵-重置投影矩阵
    gl.glLoadIdentity();//此方法相当于我们手机的重置功能,它将所选择的矩阵状态恢复成原始状态
    //x,y轴的刻度之比为ratio,投影坐标没有实际的单位,只是将视口的大小映射成相应的坐标刻度
    // 最后两个参数是near和far的值,实际Z轴是指向地面方向,因此在这里Z轴的可视刻度范围是:小于-1,不小于-10
    gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);//后两个参数-场景中所能绘制深度的起点和终点
    // 设为模型视图(观察)矩阵-以便可以使用相应的方法设置模型(被观察的物体)和试图(观察点的位置,默认在坐标原点)
    gl.glMatrixMode(GL10.GL_MODELVIEW);//指明任何新的变换将会影响
    // 重置模型观察矩阵
    gl.glLoadIdentity();
    }

    @Override
    public void onDrawFrame(GL10 gl) {
    // 开关的操作、绘制3D图形、设置顶点坐标等
    Log.i(TAG, "onDrawFrame");
    ////////////////////必须清除屏幕、否则上次绘制的图形不会自动消失///////////////
    roateTri += 0.5f;
    roateQuad -= 0.5f;
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    gl.glLoadIdentity();

    // 设置背景颜色
    gl.glClearColor(0.5f, 0.5f, 0.5f, 0.2f);
    // 设置深度缓存-默认
    //gl.glClearDepthf(1.0f);

    ////////////////////////////////三角形绘制-移动、旋转、着色,开启关闭开关///////////////////////////////////////
    // 将当前位置向Z轴负方向移6个单位
    // 移动当前中心点,左移1.5单位,并移入屏幕10.0,y不变
    // 注意:屏幕内移动的单位数必须小于前面我们通过
    // glFrustumf方法所设置的最远距离,否则显示不出来。
    // 腰围OpenGL设置一个顶点数组,故需要告诉OpenGL要设置
    // 顶点这个功能。
    gl.glTranslatef(-1.5f, 0.0f, -4.0f);

    // 设置某无题沿着指定的轴旋转
    // 参数1:旋转的角度
    // 后三个参数共同决定旋转的方向
    // 注意:要在画图前,使用旋转
    gl.glRotatef(roateTri, 0.0f, 1.0f, 0.0f);

    // 开启顶点方式绘制-允许使用顶点方式绘制图形-使用顶点坐标绘制图形时必须使用glEnableClientState方法打开允许使用顶点坐标状态
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    // 装载用于绘制图形的顶点坐标
    // 设置三角形
    // 参数1:描述顶点的尺寸,本例中使用X,Y,Z坐标系,所以是3
    // 参数2:描述顶点的类型,本例中数据是固定的,所以使用了GL_FIXED表示固定顶点
    // 参数3:描述步长
    // 参数4:顶点缓存,即我们创建的顶点数组
    gl.glVertexPointer(3, GL10.GL_FIXED, 0, bufferUtil(triangleArray));

    // 开启颜色渲染功能
    gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
    // 设置颜色,平滑着色
    gl.glColorPointer(4, GL10.GL_FIXED, 0, bufferUtil(colorArray));

    //开启OpenGL ES光源,没有颜色
    gl.glEnable(GL10.GL_LIGHTING);
    //gl.glDisable(GL10.GL_LIGHTING);

    // 开始绘制
    // 参数1:绘制模式,GL_TRIANGLES:表示绘制三角形
    // 参数2:开始位置 - id
    // 参数3:要绘制的顶点计数
    gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);

    // 将当前矩阵设为单位矩阵-如果在第二次移位时想从坐标系原点开始,就需要将当前矩阵恢复到单位矩阵
    // 重置当前的模型观察矩阵
    gl.glLoadIdentity();

    // 禁止使用顶点方式绘制图形
    //gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    // 关闭颜色渲染
    gl.glDisableClientState(GL10.GL_COLOR_ARRAY);

    /////////////////////////////////////矩形绘制-同上//////////////////////////////////
    // 右移1.5单位,并移入屏幕6.0
    gl.glTranslatef(1.5f, 0.0f, -6.0f);
    // 与三角形的旋转方式相反
    gl.glRotatef(roateQuad, 0.0f, 0.0f, 1.0f);//顺时针方向旋转
    // 开启颜色渲染功能
    gl.glEnableClientState(GL10.GL_COLOR_BUFFER_BIT);
    // 设置颜色,单调着色 (r,g,b,a)
    gl.glColor4f(0.5f, 0.2f, 0.8f, 0.7f);
    // 设置和绘制正方形
    gl.glVertexPointer(3, GL10.GL_FIXED, 0, bufferUtil(quaterArray));
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
    // 关闭颜色渲染
    gl.glDisableClientState(GL10.GL_COLOR_BUFFER_BIT);
    // 关闭顶点方式
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glFinish();

    }

    /*
    * OpenGL 是一个非常底层的画图接口,它所使用的缓冲区存储结构是和我们的 java 程序中不相同的。
    * Java 是大端字节序(BigEdian),而 OpenGL 所需要的数据是小端字节序(LittleEdian)。
    * 所以,我们在将 Java 的缓冲区转化为 OpenGL 可用的缓冲区时需要作一些工作。建立buff的方法如下
    * */
    public Buffer bufferUtil(int []arr){ // float型也可用该方法指定
    IntBuffer mBuffer ;

    // 先初始化buffer,数组的长度*4,因为一个int占4个字节
    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(arr.length * 4);
    // 数组排列用nativeOrder
    byteBuffer.order(ByteOrder.nativeOrder());

    mBuffer = byteBuffer.asIntBuffer();
    mBuffer.put(arr);
    mBuffer.position(0);

    return mBuffer;
    }
    }
    }

     

    2. 结果

    下载代码资源:代码

  • 相关阅读:
    设计模式之访问者模式
    SecureCRT Win免安装版本,简单好用
    Java BAT大型公司面试必考技能视频-1.HashMap源码分析与实现
    最好用的百度云盘破解下载加速器
    博客系统学习关于应用架构的分层与设计
    博客系统实战——SprintBoot 集成Thymeleaf 实现用户增删查改(含源码)
    【设计模式】简单工厂模式
    快速开发平台全新升级,把时间留给自己,工作丢给力软平台
    快速开发平台全新升级,把时间留给自己,工作丢给力软平台
    The rapid development platform upgrade, leave the time to yourself, the work is lost to the soft platform
  • 原文地址:https://www.cnblogs.com/webapplee/p/3771830.html
Copyright © 2011-2022 走看看