OpenGl入门

栏目: 后端 · 发布时间: 5年前

内容简介:OpenGl入门什么是OpenGLOpen Graphics Library,图形领域的工业标准,是一套跨平台的、专业的、图形变成软件接口。它用于二维、三维图像,是一个功能强大的调用方便的底层图形库。

OpenGl入门

什么是OpenGL

Open Graphics Library,图形领域的工业标准,是一套跨平台的、专业的、图形变成软件接口。它用于二维、三维图像,是一个功能强大的调用方便的底层图形库。

OpenGL与硬件无关,可以在不同的平台比如Windows、 Linux 、Mac、Andorid、IOS之间进行移植,因此也得到了广泛的应用。

Android 中使用OpenGl ES

GLSurfaceView,它继承自SurfaceView,它内嵌的sufface专门负责OpenGl渲染,管理Surface与EGL,允许自定义渲染器,让渲染器在独立的线程中运作,和UI线程分离,并且支持按需渲染(on-demand)和连续渲染(continuous)。

OpenGL是一个跨平台操作GUP的API,但是OpenGL需要本地视窗系统进行交互,这几需要一个中间层,EGL就是连接OpenGL ES和本地窗口的接口,引入EGL就是为了屏蔽不同平台上的区别。

CPU和GPU的区别

  • CPU是机器的大脑,中央处理器,用来发号施令
  • GPU的结构主要包括运算器(ALU),控制单元(CU),寄存器(Register),高速缓存器(Cache)和他们之间通讯的数据,控制及状态的总线

计算单元主要执行算数运算,位移和转换

存储单元主要用来保存运算中产生的数据以及指令等

控制单元则对指令译码,发出要完成每条指令要执行的各个操作的控制信号。

CPU中控制器和缓存器比较多,GPU中计算单元比较多。GPU无法单独工作,必须由CPU进行控制调用才能工作,CPU可以单独作用。

Android中渲染步骤

UI对象–>CPU处理为纹理–>通过OpenGLES接口调用GPU

–>GPU对图像进行栅格化–>硬件时钟–>垂直同步–>投射到屏幕

一维 点 顶点

二维 线 2个顶点

三维 面 3个顶点

在OpenGl的世界中中是又很多的3个顶点组成。

  1. 一个3D图片根据像素可以形成无数个顶点,顶点的连线叫做纹理(顶点着色器)
  2. 根据纹理形成一个一个像素(就像PS中对文字进行像素处理)(光栅化)
  3. 对像素进行着色(片元着色器)
  4. 上色之后交给GPU渲染(OpenGl渲染)

在使用OpenGl的时候,第二个和第四个是由系统完成的,我们需要手动写第一个和第三个,告诉系统有多少顶点和怎么着色

练习:

使用OpenGl绘制一个三角形

新建一个项目,Andorid系统中已经有OpenGl,不用导入第三方库,不过需要在AndroidManifest.xml中声明需要使用OpenGl

<uses-feature android:glEsVersion="0x00020000" android:required="true" />

OpenGl 使用套路

  • 创建顶点数组
  • 使用gl语言写顶点着色器和片元着色器
  • java 声明是顶点数组,颜色数组,传给gl语言中的变量
  • GPU开始渲染

自定义一个View继承自GLSurfaceView

public class GLView extends GLSurfaceView {

    public GLView(Context context) {
        super(context);
    }

    public GLView(Context context, AttributeSet attrs) {
        super(context, attrs);
        setEGLContextClientVersion(2);
        setRenderer(new GLRander(this));
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }
}

定义一个渲染器,定义一个三角形的类Triangle,绘制的方法交给它自己来做,因为还可能绘制别的图形。

public class GLRander implements GLSurfaceView.Renderer {
    protected View mView;
    Triangle mTriangle;
    public GLRander(View view) {
        mView = view;
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0, 0, 0, 0);
        mTriangle = new Triangle();
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        mTriangle.onSurfaceChanged(gl, width, height);
    }

    /**
     * 该方法不断被调用
     */
    @Override
    public void onDrawFrame(GL10 gl) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT);
        mTriangle.onDrawFrame(gl);
    }
}

开始绘制。

顶点着色器用来确定需要绘制的图形的顶点,片元着色器用来给它上色。

顶点着色器和片元着色器都是使用着色器语言(GLSL)语言编写,编写的程序可以直接推送给GPU执行。

public class Triangle {

    /**
     * 三个顶点
     */
    static float triangleCoords[] = {
            0.5f, 0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
    };

    /**
     * 管道
     */
    private FloatBuffer vertexBuffer;

    /**
     * 顶点着色器
     */
    private String vertextShaderCode = "attribute vec4 vPosition;\n" +
            "uniform mat4 vMatrix;\n" +
            "void main(){" +
            "gl_Position=vMatrix*vPosition;" +
            "}";

    /**
     * 片元着色器
     */
    private final String fragmentShaderCode = "precision mediump float;\n" +
            "uniform  vec4 vColor;\n" +
            "void main(){\n" +
            "gl_FragColor=vColor;\t\n" +
            "}";

    int mProgram;

    public Triangle(){
        ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer=bb.asFloatBuffer();
//        把顶点  推送 给GPU
        vertexBuffer.put(triangleCoords);
        vertexBuffer.position(0);

        //创建顶点着色器 并在GPU中编译
        int shader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
        GLES20.glShaderSource(shader,vertextShaderCode);
        //编译顶点着色器
        GLES20.glCompileShader(shader);

        //创建片元着色器 并在GPU中编译
        int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        GLES20.glShaderSource(fragmentShader,fragmentShaderCode);
        //编译片元着色器
        GLES20.glCompileShader(fragmentShader);

        //将顶点着色器和片元着色器放到统一的管理器中进行管理
        mProgram = GLES20.glCreateProgram();
        GLES20.glAttachShader(mProgram,shader);
        GLES20.glAttachShader(mProgram,fragmentShader);

        //连接到着色器程序
        GLES20.glLinkProgram(mProgram);
    }
    public void onSurfaceChanged(GL10 gl, int width, int height) {
         //计算宽高比
        float ratio=(float)width/height;
        //投影矩阵
        Matrix.frustumM(mProjectMatrix, 0, -ratio, ratio, -1, 1, 3, 120);
        //相机
        Matrix.setLookAtM(mViewMatrix, 
                ////摄像机的坐标
                0, 0, 0, 7,
                //目标物的中心坐标
                0f, 0f, 0f,
                //相机方向
                0f, 1f, 0f);
        //计算变换矩阵
        Matrix.multiplyMM(mMVPMatrix,0,mProjectMatrix,0,mViewMatrix,0);
    }

    /**
     * rgba
     */
    float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
    private float[] mViewMatrix=new float[16];
    private float[] mProjectMatrix=new float[16];
    private float[] mMVPMatrix=new float[16];
    public void onDrawFrame(GL10 gl) {
        //开始渲染
        //拿到总的程序
        GLES20.glUseProgram(mProgram);
        //拿到vPosition的地址
        int mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        //设置缩放
        int mMatrixHandler = GLES20.glGetUniformLocation(mProgram, "vMatrix");
        GLES20.glUniformMatrix4fv(mMatrixHandler,1,false,mMVPMatrix,0);
        //允许对这个地址进行读写
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        //给顶点着色器赋值
        GLES20.glVertexAttribPointer(mPositionHandle,3,
                GLES20.GL_FLOAT,false,3*4,vertexBuffer);

        //给片元着色器赋值
        int mColorHandle = GLES20.glGetUniformLocation(mProgram,"vColor");
        GLES20.glUniform4fv(mColorHandle,1,color,0);
        //开始绘制
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,3);
        //关闭读写
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
}

结果:

OpenGl入门


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

结网

结网

王坚 / 人民邮电出版社 / 2010-12-10 / 59.00元

本书以如何创建、发布、推广互联网产品为主线,介绍了互联网产品经理的工作内容以及应对每一部分工作所需的方法和工具。为用户创造价值是产品经理的第一要务,产品经理的工作是围绕用户及具体任务展开的,本书丰富的案例和透彻的分析道出了从发现用户到最终满足用户这一过程背后的玄机。 本书面向现在正在从事及未来将要从事互联网相关工作的创业者和产品经理,也可以作为互联网产品策划人员或相关专业学生的参考书。新版完......一起来看看 《结网》 这本书的介绍吧!

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具