zoukankan      html  css  js  c++  java
  • opengl se画图

     OpenGL 是一个非常底层的画图接口,它所使用的缓冲区存储结构是和我们的 java 程序中不相同的。
    Java 是大端字节序(BigEdian),而 OpenGL 所需要的数据是小端字节序(LittleEdian)。 所以,我们在将 Java 的缓冲区转化为 OpenGL 可用的缓冲区时需要作一些工作。
    建立buff的方法如下:
    class BufferUtil {
    public static FloatBuffer mBuffer;
    public static IntBuffer mBuffer2;
    public static FloatBuffer floatToBuffer(float[] a) {
    //先初始化buffer,数组的长度*4,因为一个float占4个字节
    ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
    //数组排序用nativeOrder
    mbb.order(ByteOrder.nativeOrder());
    mBuffer = mbb.asFloatBuffer();
    mBuffer.put(a);
    mBuffer.position(0);
    return mBuffer;
    }
    public static IntBuffer intToBuffer(int[] a) {
    //先初始化buffer,数组的长度*4,因为一个float占4个字节
    ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
    //数组排序用nativeOrder
    mbb.order(ByteOrder.nativeOrder());
    mBuffer2 = mbb.asIntBuffer();
    mBuffer2.put(a);
    mBuffer2.position(0);
    return mBuffer2;
    }
    }
    该类的2个方法可以将点的坐标转化为opengl的存储结构。
     
    openglSurfaceView提供了图形渲染接口Render,实现该接口里的3个方法就可以显示我们要画的显示的图形纹理。线面给出最简单的一个绘图demo。
    Activity和GLRender 2个java文件:
    public class MainActivity extends AppCompatActivity {
     
    private GLSurfaceView glSurfaceView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    init();
    }
     
    private void init() {
    glSurfaceView=new GLSurfaceView(this);
    GLSurfaceView.Renderer renderer=new GLRender();
    glSurfaceView.setRenderer(renderer);
    setContentView(glSurfaceView);
     
    }
     
     
     
    package com.example.zp.myapplication;
     
    import android.opengl.GLSurfaceView;
     
    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;
     
     
    /*
    * OpenGL 是一个非常底层的画图接口,它所使用的缓冲区存储结构是和我们的 java 程序中不相同的。
    * Java 是大端字节序(BigEdian),而 OpenGL 所需要的数据是小端字节序(LittleEdian)。
    * 所以,我们在将 Java 的缓冲区转化为 OpenGL 可用的缓冲区时需要作一些工作。建立buff的方法如下
    * */
    class BufferUtil {
    public static FloatBuffer mBuffer;
    public static IntBuffer mBuffer2;
    public static FloatBuffer floatToBuffer(float[] a) {
    //先初始化buffer,数组的长度*4,因为一个float占4个字节
    ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
    //数组排序用nativeOrder
    mbb.order(ByteOrder.nativeOrder());
    mBuffer = mbb.asFloatBuffer();
    mBuffer.put(a);
    mBuffer.position(0);
    return mBuffer;
    }
    public static IntBuffer intToBuffer(int[] a) {
    //先初始化buffer,数组的长度*4,因为一个float占4个字节
    ByteBuffer mbb = ByteBuffer.allocateDirect(a.length * 4);
    //数组排序用nativeOrder
    mbb.order(ByteOrder.nativeOrder());
    mBuffer2 = mbb.asIntBuffer();
    mBuffer2.put(a);
    mBuffer2.position(0);
    return mBuffer2;
    }
    }
     
    /**
    * Created by lenovo on 2016/7/22.
    */
    public class GLRender implements GLSurfaceView.Renderer {
    float rotateSpeed =5* (float) Math.PI/18;
    float rotateTri = 0;
    int one=0x10000;
    float a=0.2f;
     


     
    public IntBuffer getIntTriggerBuffer(int [] a)
    {
    return BufferUtil.intToBuffer(a);
    }
     
    public FloatBuffer getFloatTriggerBuffer(float[] mTriangleArray)
    {
    return BufferUtil.floatToBuffer(mTriangleArray);
    }
     
     
    @Override
    public void onDrawFrame(GL10 gl)
    {
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
    gl.glLoadIdentity();//这个是重置模型矩阵,即作图原点回到(0,0,0)
    gl.glTranslatef(0f,0f,-3f);移到作图原点到(0,0,)
    gl.glRotatef(rotateTri, 1.0f, 0.0f, 0.0f);
    int[] quater=new int[]{
    0,one,0,
    -one,-one,one,
    one,-one,one,
     
    0,one,0,
    one,-one,one,
    one,-one,-one,
     
    0,one,0,
    one,-one,-one,
    -one,-one,-one,
     
    0,one,0,
    -one,-one,-one,
    -one,-one,one,
    };
    //设置点可用 
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    // 这里的GL10.GL_FIXED是整形数据,即one的大小是投影在第一层时候观察的大小,显示为整个openglsurfaceview的控件中宽的大小

    // 当为folat类型数据时候,1代表的屏幕宽度
    gl.glVertexPointer(3,GL10.GL_FIXED,0,getIntTriggerBuffer(quater));
    for(int i = 0; i < 4 ; i ++)
    {
    if(i==0) gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
    if(i==1) gl.glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
    if(i==2) gl.glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
    if(i==3) gl.glColor4f(1.0f, 0.0f, 1.0f, 1.0f);
    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,i*3,3);
    }
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    rotateTri = rotateSpeed+rotateTri;
    }
     
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
     
    //告知系统对透视进行修正
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
    //设置背景为黑色
    gl.glClearColor(0, 0, 0, 0);
    //启用阴影平滑
    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) {
    float ratio = (float) width / height;
    //设置OpenGL场景的大小
    gl.glViewport(0, 0, width, height);
    //设置投影矩阵
    gl.glMatrixMode(GL10.GL_PROJECTION);
    //重置投影矩阵
    gl.glLoadIdentity();
    // 设置视口的大小
    gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
    // 选择模型观察矩阵,这个模型只能看到第二层,既当你绘图投影在第一层时候什么都看不到,暂时没有深入研究
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    // 重置模型观察矩阵
    gl.glLoadIdentity();
     
     
    }
    }
     
     
    实现效果是个在旋转的四棱锥
     
     
  • 相关阅读:
    微软程序员最好的时代来了
    领域驱动设计系列 (六):CQRS
    当我谈 "加班有罪" 我在谈什么?
    parquet 简介(转)
    Spark动态资源分配-Dynamic Resource Allocation
    Spark配置参数详解
    PhpStorm使用sftp实现代码自动上传服务器
    docker 命令大全
    mysql 5.6配置
    docker volume
  • 原文地址:https://www.cnblogs.com/bokeofzp/p/5967637.html
Copyright © 2011-2022 走看看