Android OpenGL开发——图像绘制详解

  • 文章布景
  • 1. What? openGl是什么?openGl ES又是什么?
  • 2. How? Android中的openGL 怎么运用?
  • 3. GlSurfaceView是什么? GLSurfaceView的作用是什么? GLSurfaceView怎么运用?
  • 4. GlSurfaceView.Renderer是什么?GLSu编辑器英语rfaceView.Renderer的作用?GLSurfaceView.Renderer的用法?
  • 5. OpenGl的简略运用实例(制作一个三角形)
    • 运用OpenGljava编译器修正布景色彩
    • 运用OpenGl制作几何图形
    • 运用投影和相机视图
      • 投影的界说
      • 相机视图
      • 转化矩阵(改换矩阵)
    • 增加动作
    • 修正极点色彩
      • shader的变量类型(uniform,attribute和vjava模拟器arying)的差异
  • 6矩阵计算器. 参阅链接:
  • 7. 项目地址:
~~吐槽一下的markdown编辑器,十分困难搞成目录了却只能看不能点,好伤心,这啥时候优化一下?,有木有人来处理一下,强迫症表明好难过~~

布景

最近签约活动整搞得热火朝天,索性摊开双手,翻开我那尘封许久笔记本,抱着试试看的态度,把几篇从前自己用心opengl渲染gpu怎么设置收拾的文章拉出来遛遛,假如能整杯咖啡,那也是意料之外的惊喜。OK,能力一般,水平有限,如有同行发现文章有不谨慎讲究之处,欢迎指正批评。

学习五部曲,弄opengl错误1282清楚5个W一个H(when(什么时候运用)、where(在哪个当编辑器哪个好用地运用?)、who(对谁运用)、what(是个什么东西)、why(为什么要这么用?).一个H即:how(到底该怎样用?),本文首要围绕这几个方面临OpenGL进行分析讲解,希望对有兴趣了编辑器解的OpenGL的小伙伴一丢丢协助。

1. What? openGl是什么?openGl ES又是什么?

相信许多人从事开发的都或多或少听到过有关OpenGl这个东西,可是平常用的少,只知道有这么个东西,并且学起来不简略,java模拟器所以大多数人都不能讲出个个所以然来。

官方对OpenGl的描述为:

OpenGL(Open Graphics Library开发图形接口)是一个跨平台的图形API,用于指定3D图java培训形处理硬件中的规范软件接口。

Oopengl模式p矩阵乘法enGl的前身是SGI公司为其图形工作站开发的IRIS GL,后来由于IRIS GL的移植性欠好,所以在其基础上,开发出了OpenGl。OpenGl一矩阵计算器般用于在图形工作站,PC端运用,由于功能各方面原因,在移动端运用OpenGl根本带不动。为此,Khronos公变量名司就java是什么意思为OpenGl供给了一个子集,OpenGjava培训l ES(OpenGl for Embedded Sys变量泵tem)

什么是OpenGl ES呢?

OpenGjava环境变量配置l ES是免费的跨平台的功能完善的2D/3D图形库接口的API,是OpenGL的一个子集变量之间的关系

移动端运用到的根本上都是OpenGl E变量是什么意思S,当然Android开发编辑器下还专门为OpenGl供给了android.opengl包,并且供给了GlSurfaceView,GLU,GlUjava是什么意思tils等工具类。

2. How? An矩阵转置droid中的openGL 怎么运用?

在了解OpenGl的运用之前,咱们需求了解两个根本类别的AOpenGLndroid框架:GlSurfaceView和GlSurfaceView.Renderer

3. GlSurfaceVopengl是什么意思iew是什么? GLSurfaceView的作用是什么? GLSurfaceView怎么运变量类型有哪些用?

GlSurfaceViopengl错误1282ew从姓名就能够看出,它是一个Surfaopengl坐标转换学步园ceView,看源码可知,GlSurfaceView继承自SurfaceViewOpenGL。并增加了Renderer.它的作用java编译器便是专门变量值为OpenGl显现烘托运用的变量

GLSurfaceView的运用办法: 能够经过创立的实例运用这个java面试题类,并增加你的Renderer.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        GLSurfaceView glSurfaceView = new GLSurfaceView(this);
        glSurfaceView.setRenderer(new GLSurfaceView.Renderer() {
            @Override
            public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            }
            @Override
            public void onSurfaceChanged(GL10 gl, int width, int height) {
            }
            @Override
            public void onDrawFrame(GL10 gl) {
            }
        });
        setContentView(glSurfaceView);
    }

4. Gl变量是什么意思SurfaceView.Renderer是什么?GLSurfaceView.Renderer的作用?GLSurfaceView.Renderer的用法java模拟器

该接口界说了用于制作在图形所需的办法GLSurfaceView。你有必要供给这个接口作为一个单独的类java语言的完结,并将其衔接到您的GLSurfaceView运用实例 GLjava怎么读SurfaceView.setRenderer()。如上面的代码所示。作矩阵的乘法运算用便是供给各种烘托办法,编辑器下载OpenGl的烘托操作均在此接口中实习。下面说下完结该接口的办法opengl模式含义:

  • onSurfaceCreated():体系调用这个办法一次创立时GLSurfaceView。运用此办法来履行只需求产生一次的操作,比变量值方设置OpenGL的环境参数或初始化的OpenGL图形目标。
  • onDrawFrame():体系调用上的每个重绘此办法GLSurfaceVi矩阵乘法ew。运用此办法作为首要履行点用于制作(和重新制作)的图形目标。
  • 体系调用此办法时的GLSurfaceViopengl和vulkanew几何形状的改变,包含尺寸改变GLSurfacejavaeeView或设备屏矩阵的秩幕的取向矩阵转置。例如,当设备从纵向变为横向的体系调用这个办法。运用此办法能够在改变做出反响GLSurfaceView容器。

介绍完了GlSurfaceView和GlSurfaceView.renderer之后,接下来说下怎么运用GlSurfaceView; 1. 创立一个GlSJavaurfaceView 2. 为这个GlSurfaceView设置烘托 3. 在GlSurfjava语言aceView.renderer中制作处理显现数据

5. OpenGl的简略运用实例(制作一个三角形)

  1. 在运用OpenGl之前,需求在Android变量泵Manifest.xml中设置OpenGl的版本:这儿opengl是什么意思咱们运用的是OpenGl ES 2.0,所以需求增加如下说明:
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
  1. 运用GLSufaceView(上面有介绍)
  2. 详细在GlSurfaceView.Renderer中的制作过程:
  • 设置视图展opengl坐标转换学步园现窗口(viewport) :在onSurfaceChanged中调用GLES20.glViewport(0, 0, width, height);
  • 创立图形矩阵游戏类,确定好极点方位和图形色彩,将极点和色彩数据转化为OpenGl运用的数据格式
  • 加载极点找色器和片段着色器用编辑器哪个好用来修正图形的色彩,纹理,坐标等特点
  • 编辑器小说立投影和相机视图来显现视图的显现状况,并将投影和相机视图的转化传递给着色器。
  • 创立项目(Program),衔接极点着色器片段着色器。
  • 将坐标数据传入到OpenGl ES程序中:

运用OpenGl修正布景色彩

创立一个GlSurfaceView,并为其变量的定义设置烘托OneGlRenderer;

public class OneGlSurfaceView extends GLSurfaceView {
    private final OneGlRenderer mRenderer;
    public OneGlSurfaceView(Context context) {
        super(context);
        // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);
        mRenderer = new OneGlRenderer();
        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(mRenderer);
    }
}

完结烘托接口

public class OneGlRenderer implements GLSurfaceView.Renderer {
    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }
    public void onDrawFrame(GL10 unused) {
        // Redraw background color
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    }
    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
    }
}

展现烘托后的GlSurfaceView

public class OneOpenGlActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        OneGlSurfaceView glSurfaceView = new OneGlSurfaceView(this);
        setContentView(glSurfaceView);
    }
}

作用如下:便是简略给Gl矩阵相乘怎么算Sur编辑器手机版faceView烘托一层黑色。

Android OpenGL开发——图画制作详解

运用OpenGl制作几何图形

一:图形创立

创立一个几何图形(这儿首要列举三角形和正方形),需求留意一点,咱们设置图形的极点坐变量类型有哪些标后,需求将极点坐标转为ByteBuffer,这样OpenGl才能进行图形处理。

三角形图形创立:

public class Triangle {
    private FloatBuffer vertexBuffer;
    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 3;
    static float triangleCoords[] = {   // in counterclockwise order:
             0.0f,  0.5f, 0.0f, // top
            -0.5f, -0.5f, 0.0f, // bottom left
             0.5f, -0.5f, 0.0f  // bottom right
    };
    // Set color with red, green, blue and alpha (opacity) values
    float color[] = { 255, 0, 0, 1.0f };
    public Triangle() {
       // 初始化ByteBuffer,长度为arr数组的长度*4,由于一个float占4个字节
        ByteBuffer bb = ByteBuffer.allocateDirect(triangleCoords.length * 4);
        // 数组排列用nativeOrder
        bb.order(ByteOrder.nativeOrder());
        // 从ByteBuffer创立一个浮点缓冲区
        vertexBuffer = bb.asFloatBuffer();
        // 将坐标增加到FloatBuffer
        vertexBuffer.put(triangleCoords);
        // 设置缓冲区来读取第一个坐标
        vertexBuffer.position(0);
    }
}

正方型图:

public class Square {
    private FloatBuffer vertexBuffer;
    private ShortBuffer drawListBuffer;
    // number of coordinates per vertex in this array
    static final int COORDS_PER_VERTEX = 3;
    static float squareCoords[] = {
            -0.5f,  0.5f, 0.0f,   // top left
            -0.5f, -0.5f, 0.0f,   // bottom left
             0.5f, -0.5f, 0.0f,   // bottom right
             0.5f,  0.5f, 0.0f }; // top right
    private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
    public Square() {
        // 初始化ByteBuffer,长度为arr数组的长度*4,由于一个float占4个字节
        ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(squareCoords);
        vertexBuffer.position(0);
        // 初始化ByteBuffer,长度为arr数组的长度*2,由于一个short占2个字节
        ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        drawListBuffer = dlb.asShortBuffer();
        drawListBuffer.put(drawOrder);
        drawListBuffer.position(0);
    }
}

创立图形根本没什么技巧可言,墨守成规就行了,为什么数据需求转化格式呢?首要是由于Java的缓冲区数据存储结构为大端字节序(BigEdi编辑器手机版an),而OpenGl的数据为小端字节序(LittleEdian),由于数据存储结构的差异,所以,在Androi编辑器135d中运用OpenGl的时候有必要要进行下转化。当然,一般编辑器135咱们在运用的时候都会做个opengl-legacy简略的工具类。这儿供给几个简略的封装。(占几个字节就初始化ByteBuffer长度的时候*几)

  1. 将int[]转成IntBuffer
private IntBuffer intBufferUtil(int[] arr)
    {
        IntBuffer mBuffer;
        // 初始化ByteBuffer,长度为arr数组的长度*4,由于一个int占4个字节
        ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
        // 数组排列用nativeOrder
        qbb.order(ByteOrder.nativeOrder());
        mBuffer = qbb.asIntBuffer();
        mBuffer.put(arr);
        mBuffer.position(0);
        return mBuffer;
    }
  1. 将float[]数组转为OpenGl 所需求的FloatBuffer
private FloatBuffer floatBufferUtil(float[] arr)
    {
        FloatBuffer mBuffer;
        // 初始化ByteBuffer,长度为arr数组的长度*4,由于一个int占4个字节
        ByteBuffer qbb = ByteBuffer.allocateDirect(arr.length * 4);
        // 数组排列用nativeOrder
        qbb.order(ByteOrder.nativeOrder());
        mBuffer = qbb.asFloatBuffer();
        mBuffer.put(arr);
        mBuffer.position(0);
        return mBuffer;
    }
  1. 当然,依葫芦画瓢,怎么将short[]转ShortBuffer这个就照着写就ok了
private ShortBuffer shortBufferUtil(short[] arr){
        ShortBuffer mBuffer;
        // 初始化ByteBuffer,长度为arr数组的长度*2,由于一个short占2个字节
        ByteBuffer dlb = ByteBuffer.allocateDirect(
                // (# of coordinate values * 2 bytes per short)
                arr.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        mBuffer = dlb.asShortBuffer();
        mBuffer.put(arr);
        mBuffer.position(0);
        return mBuffer;
    }

创立完形状之后,咱们opengl渲染gpu怎么设置就要进行咱们的第二步了,将这些形状烘托到GlSurfaceView中去。首要可分为下面几步: 1. 首要咱们需求在GlSurfaceView.Renderer中初始化需求烘托的几何图形

private Triangle mTriangle;
    private Square   mSquare;
    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        // 设置布景色彩
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        // 初始化triangle
        mTriangle = new Triangle();
        // 初始化 square
        mSquare = new Square();
    }

二.:制作图形,由于需求供给许多细节的图形烘托管矩阵计算器线,所以制作图形前至少需求一个极点着色器来制java怎么读作形状和一个片段着色器的色彩,形状。这些着色器有必要被编译,然后加入到一个OpenGL ES程序,然后将其用于制作形状。简略介绍编辑器怎么打开下这几个概念: – 极点着色器(Vertex Shader)极点着色器是GPU上运转的小程序,由姓名能够知道,经编辑器下载过它来处编辑器英语理极点,他用于烘托图形极点的OpenGL ES图形代码。极点着色器可用来修正图形的方位,色彩,纹理java编译器变量是什么意思标,不过不能用来创立新的极点坐标。 – 片段着色器(Fragment Shader ) 用于出现与色彩或纹理的形状的面编辑器小说的OpenGL ES代码。 – 项目(Program) –编辑器手机版包含要用于制作一个或多个形状着色器的OpenGL ES的目标。

下面给Triangle类界说一个根本的着色器代码:

public class Triangle {
    private final String vertexShaderCode =
        "attribute vec4 vPosition;" +
        "void main() {" +
        "  gl_Position = vPosition;" +
        "}";
    private final String fragmentShaderCode =
        "precision mediump float;" +
        "uniform vec4 vColor;" +
        "void main() {" +
        "  gl_FragColor = vColor;" +
        "}";
    ...
}

当然,上面咱们创立了着色器的编译代码,代码编写完结,需求写个办法来履行这段代码,这儿咱们在烘托器中写一个如下办法来履行着色器代码:

public static int loadShader(int type, String shaderCode){
        // 发明极点着色器类型(GLES20.GL_VERTEX_SHADER)
        // 或者是片段着色器类型 (GLES20.GL_FRAGMENT_SHADER)
        int shader = GLES20.glCreateShader(type);
        // 增加上面编写的着色器代码并编译它
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);
        return shader;
    }

这儿有一点需求留意,由于着色器变量名的命名规则的代码履行是很贵重滴,所以避免屡次履行,需求咱们一般将履行代码的逻辑写带图形类的构造办法中。比方上面的Triangle,咱们就这么写:

private final int mProgram;
public Triangle() {
        ... ...//数据转化
        int vertexShader = OneGlRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
                vertexShaderCode);
        int fragmentShader = OneGlRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,
                fragmentShaderCode);
        // 创立空的OpenGL ES程序
        mProgram = GLES20.glCreateProgram();
        // 增加极点着色器到程序中
        GLES20.glAttachShader(mProgram, vertexShader);
        // 增加片段着色器到程序中
        GLES20.glAttachShader(mProgram, fragmentShader);
        // 创立OpenGL ES程序可履行文件
        GLES20.glLinkProgram(mProgram);
    }

最终,所有制作的所有根本装变量泵备都装备完结之后,咱们来写制作图形的办法,咱们在图矩阵的秩形类(Triangle)中创立一个制作的办法onDraw(),能够在onDraw()办法中设置制作逻辑。

private int mPositionHandle;
    private int mColorHandle;
    private final int vertexCount = triangleCoords.length / COORDS_PER_VERTEX;
    private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
    public void draw() {
        // 将程序增加到OpenGL ES环境
        GLES20.glUseProgram(mProgram);
        // 获取极点着色器的方位的句柄
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
        // 启用三角形极点方位的句柄
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        //准备三角形坐标数据
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                GLES20.GL_FLOAT, false,
                vertexStride, vertexBuffer);
        // 获取片段着色器的色彩的句柄
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
        // 设置制作三角形的色彩
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);
        // 制作三角形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
        // 禁用极点数组
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }

完结上面所有过程,只需求在GlSurfaceView.Rendjava模拟器erer的onDrawFrame()办法中调用图形类的制作办法即可(上面的onDraw()):

public void onDrawFrame(GL10 unused) {
        mTriangle.draw();
    }

最终的出现作用如下图所示编辑器小说

Android OpenGL开发——图画制作详解

运用投影和相机视图

通常情况下,OpenGl中展现的视编辑器软件图和在Android上显现的图形会有误差。借用官方图片:

Android OpenGL开发——图画制作详解

当然咱们能够经过矩阵转化来处理这种问题,让OpenGl上的视图在任何android设备上显现的比例都是相同的,这儿说下什么是投影和相机视图:

投影的界说

运用OpenGl制作的3D图形,需求展现在移动端2D设备上,这便是投影。Android OpenGl ES中有两种投影办法:一种是正交投影,一种是透视投影:

正交投影投影物体的带下不会随调查点的远近而产生改变,咱们能够运用变量值下面办法来履java怎么读行正交投影:

Matrix.orthoM (float[] m,           //接纳正交投影的改换矩阵
                int mOffset,        //改换矩阵的开始方位(偏移量)
                float left,         //相对调查点近面的左边距
                float right,        //相对调查点近面的右边距
                float bottom,       //相对调查点近面的下边距
                float top,          //相对调查点近面的上边距
                float near,         //相对调查点近面间隔
                float far)          //相对调查点远面间隔

透视投影:随调查点的间隔改变而改变,调查点越远,视图越小,opengl和directx反之越大,咱们能够经过如下办法来设置透视投影:

Matrix.frustumM (float[] m,         //接纳透视投影的改换矩阵
                int mOffset,        //改换矩阵的开始方位(偏移量)
                float left,         //相对调查点近面的左边距
                float right,        //相对调查点近面的右边距
                float bottom,       //相对调查点近面的下边距
                float top,          //相对调查点近面的上边距
                float near,         //相对调查点近面间隔
                float far)          //相对调查点远面间隔

相机视图

什么是java编译器相机视图?简略来说生活中咱们拍照,你站的高度,拿相机的方位,姿势不同,拍出来的相片也就不相同,相机视图便是来修正相机方位,调查办法以及相机的倾斜角度等特点。咱们能够经过下面办法来修正相机视图特点:编辑器怎么打开

Matrix.setLookAtM (float[] rm,      //接纳相机改换矩阵
                int rmOffset,       //改换矩阵的开始方位(偏移量)
                float eyeX,float eyeY, float eyeZ,   //相机方位
                float centerX,float centerY,float centerZ,  //调查点方位
                float upX,float upY,float upZ)  //up向量在xyz上的重量

转化矩阵(改换矩阵)

转化矩阵用来做什么的呢?是否记得上面咱们制作的图形坐标需求转化为OpenGl中能处理的小端字节序(LittleEdian),没错,转化矩阵便是用来将数据转为OpenGl ES可用的数据字节,咱们将相机视图和投矩阵相乘怎么算影设置的数据相乘矩阵的乘法运算,便得到一个转化矩阵,然后咱们再讲此矩阵传给极点着色器,详细运用办法及参数说明如下:

Matrix.multiplyMM (float[] result, //接纳相乘成果
                int resultOffset,  //接纳矩阵的开始方位(偏移量)
                float[] lhs,       //左矩阵
                int lhsOffset,     //左矩阵的开始方位(偏移量)
                float[] rhs,       //右矩阵
                int rhsOffset)     //右矩阵的开始方位(偏移量)

下面简略讲解下怎么运用投影和相机视图来完结矩阵改换并传递给极点着色器;

  1. 界说一个投影:
// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
    private final float[] mMVPMatrix = new float[16];
    private final float[] mProjectionMatrix = new float[16];
    private final float[] mViewMatrix = new float[16];
    public void onSurfaceChanged(GL10 unused, int width, int height) {
        GLES20.glViewport(0, 0, width, height);
        float ratio = (float) width / height;
        // 这个投影矩阵被应用于目标坐标在onDrawFrame()办法中
        Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
    }
  1. 界说一个相机视图
@Override
public void onDrawFrame(GL10 unused) {
    ...
    // Set the camera position (View matrix)
    Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
    // Draw shape
    mTriangle.draw(mMVPMatrix);
}
  1. 修正图形类履矩阵和行列式的区别行代码
public class Triangle {
    private final String vertexShaderCode =
        // This matrix member variable provides a hook to manipulate
        // the coordinates of the objects that use this vertex shader
        "uniform mat4 uMVPMatrix;" +
        "attribute vec4 vPosition;" +
        "void main() {" +
        // the matrix must be included as a modifier of gl_Position
        // Note that the uMVPMatrix factor *must be first* in order
        // for the matrix multiplication product to be correct.
        "  gl_Position = uMVPMatrix * vPosition;" +
        "}";
    // Use to access and set the view transformation
    private int mMVPMatrixHandle;
    ...
}
  1. 投影和相机视图代码到图形类的制作办法中去onDraw()
public void draw(float[] mvpMatrix){
       ... ...
        // 得到形状的改换矩阵的句柄
        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        // 将投影和视图转化传递给着色器
        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
        // 画三角形
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);
        // 禁用极点数组
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }

做完这些,咱们就能得到如下图:

Android OpenGL开发——图画制作详解

没错,这才没有变形的视图。到这儿,根本的经过OpenGl制作简略图形就over了,下面咱们讲解下怎么增加一些交互动作。

增加动作

前面都是简略的动作介绍,运用OpenGl在屏幕上制作目标是运用openGl的根本功。下面我来说下怎么增加旋转形状。运用OpenGl的描绘目标是相对简略的,首要需求在烘托器中创立一组旋转矩阵,然后运用之前变量提到过的投影和相机视图改换矩阵结合起来运用:

private float[] mRotationMatrix = new float[16];
public void onDrawFrame(GL10 gl) {
    float[] scratch = new float[16];
    ...
    // 创立一个旋转矩阵
    long time = SystemClock.uptimeMillis() % 4000L;
    float angle = 0.090f * ((int) time);
    Matrix.setRotateM(mRotationMatrix, 0, angle, 0, 0, -1.0f);
    // 将旋转矩阵与投影和相机视图组合在一起
    // Note that the mMVPMatrix factor *must be first* in order
    // for the matrix multiplication product to be correct.
    Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);
    // Draw triangle
    mTriangle.draw(scratch);
}

运转作用图如下:

Android OpenGL开发——图画制作详解

修正极点色彩

一个色彩是不是太单调了?怎么让做成多彩的呢?接下来咱们来做一个多彩三角形,怎么来做一个多彩三角形?咱们经过极点着色器来做。根据上编辑器哪个好用面的代码,咱们变量泵只需求做一点点改动,下面是根本过程: 1. 修正着色器代码 2. 将色彩值java怎么读修正为float数组并转为floatBuffer 3. 将opengl和directx获取的floatBuffer传递给极点着色器。

修正着色器代码:矩阵的秩

private final String vertexShaderCode =
            "attribute vec4 vPosition;" +
                    "uniform mat4 uMVPMatrix;"+
                    "varying  vec4 vColor;"+
                    "attribute vec4 aColor;"+
                    "void main() {" +
                    "  gl_Position = uMVPMatrix*vPosition;" +
                    "  vColor=aColor;"+
                    "}";
    private final String fragmentShaderCode =
            "precision mediump float;" +
                    "varying vec4 vColor;" +
                    "void main() {" +
                    "  gl_FragColor = vColor;" +
                    "}";

shader的变量类型(unifor编辑器下载m,attribuopengl模式te和varying)的差异

关于shader的变量类型(uniform,at矩阵相乘怎么算tribute和varying)的差异及运用,下面做下说明:

  1. uniform:uniform变量在vertex和fragment两者之间声java培训明办法完全相同,则它能够编辑器和ide的区别在vertex和fragment同享运用。(相当于一个被vejava面试题rtex和fragment shader同享的全局变量)uniform变量一般用来表明:改换矩阵,原料,光照参数和色彩等信息。在代码中经过GLES20.glGetUniformLocation(int program, String najava模拟器me)来获取特点值。并经过 GLES20.glUniformMatrix4fv(int矩阵转置 location, int count, boolean transpose, float[] value, int offset);办法将数据传递给着色器。
  2. attribute:这个变量只能在极点着色器中运用(vertex Shader),用来表明极点的数据,比方极矩阵点坐标,极点色彩,法线,纹理坐标等。在制作的时候经过GLES20.glGetAttribLocation(int program, String n变量的定义ame)来获取变量值,经过 GLES20.glEnableVertexAttribArray(变量泵int index)来发动句柄,最终经过 GLE变量S20.glVertexAttribPointer(int indx,int size,int type,boolean normalized,int stride,java.nio.Buffer ptr)来设置图形数据。
  3. varyinjava是什么意思g变量:这个变量只能用来在vertex和fr变量之间的关系agment shade变量类型有哪些r之间传递数据时运用,java是什么意思不能够经过代码获取其变量值。

接来下咱们进行数据转化:

float color[] = {
            1.0f, 0f, 0f, 1.0f ,
            0f, 1.0f, 0f, 1.0f ,
            0f, 0f, 1.0f, 1.0f
    };
        public Triangle() {
           ... ...
          ByteBuffer dd = ByteBuffer.allocateDirect(
                    color.length * 4);
            dd.order(ByteOrder.nativeOrder());
            colorBuffer = dd.asFloatBuffer();
            colorBuffer.put(color);
            colorBuffer.position(0);
        }

最终咱们需求获取着色器的句柄并设置着色器的色彩:

public void draw(float[] mvpMatrix){
        ... ... 
         /* // 获取片段着色器的vColor成员的句柄
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
        // 设置制作三角形的色彩
        GLES20.glUniform4fv(mColorHandle, 1, colorBuffer, 0);*/
        //获取片元着色器的vColor成员的句柄
        mColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
        //设置制作三角形的色彩
        GLES20.glEnableVertexAttribArray(mColorHandle);
        GLES20.glVertexAttribPointer(mColorHandle,4,
                GLES20.GL_FLOAT,false,
                0,colorBuffer);
                ... ...
                }

Android OpenGL开发——图画制作详解

6. 参阅链接:

  1. opengl官网
  2. opengl的环境搭建及根本教程

7. 项目地址:

  • AserbaoAndroid此项目为博主所有的系列学习的代码汇总项目,变量类型有哪些该文章的代码坐落:opOpenGLengl/OneOpenGl/O变量名neOpenGlActivity
  • 假如对音视频开发有兴趣的变量的定义同学能够看看这个项目:AndroidCamera 这个项目功变量与函数能包含视频人脸辨认贴纸,美颜,分段录制,视频裁剪,视频帧处理,获取视频关键帧,视频旋转,增加滤镜,增加水印。

我正在参加技术社区创作者签约计划招募活动,点击链接报名投稿。

发表回复

提供最优质的资源集合

立即查看 了解详情