GLCanvasImpl.java是接口GLCanvas的唯一实现类,也就是说二者在功能上完全等同。代码中调用GLCanvas对象函数的地方,等效于调用GLCanvasImpl中的该函数,GLCanvasImpl对该函数有具体的实现。

1.构造函数

    GLCanvasImpl(GL11 gl) {
mGL = gl;
mGLState = new GLState(gl);
initialize();
}

1.1.new GLState(gl)

        public GLState(GL11 gl) {
mGL = gl; // Disable unused state
gl.glDisable(GL11.GL_LIGHTING); // Enable used features
gl.glEnable(GL11.GL_DITHER);
gl.glEnable(GL11.GL_SCISSOR_TEST); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glEnable(GL11.GL_TEXTURE_2D); gl.glTexEnvf(GL11.GL_TEXTURE_ENV,
GL11.GL_TEXTURE_ENV_MODE, GL11.GL_REPLACE); // Set the background color
/// M: Disable transparent
//gl.glClearColor(0f, 0f, 0f, 0f);
gl.glClearColor(0f, 0f, 0f, 1f);
gl.glClearStencil(0); gl.glEnable(GL11.GL_BLEND);
gl.glBlendFunc(GL11.GL_ONE, GL11.GL_ONE_MINUS_SRC_ALPHA); // We use 565 or 8888 format, so set the alignment to 2 bytes/pixel.
gl.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 2);
}

了解OpenGL的用法,知道上面这部分内容只是做了一些绘图时的属性设置,就像我们利用Canvas绘制2D图形时对画笔的设置一样。

1.2.initialize()

    private void initialize() {
GL11 gl = mGL; // First create an nio buffer, then create a VBO from it.
int size = BOX_COORDINATES.length * Float.SIZE / Byte.SIZE;
FloatBuffer xyBuffer = allocateDirectNativeOrderBuffer(size).asFloatBuffer();
xyBuffer.put(BOX_COORDINATES, 0, BOX_COORDINATES.length).position(0);//Opengl中的常见做法,通常把顶点坐标等数据储存在FloatBuffer,ShortBuffer等Buffer中。 int[] name = new int[1];
GLId.glGenBuffers(1, name, 0);//申请一个int缓冲区
mBoxCoords = name[0]; gl.glBindBuffer(GL11.GL_ARRAY_BUFFER, mBoxCoords);//绑定该缓冲区
gl.glBufferData(GL11.GL_ARRAY_BUFFER,
xyBuffer.capacity() * (Float.SIZE / Byte.SIZE),//分配数据初始化该缓冲区
xyBuffer, GL11.GL_STATIC_DRAW); gl.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0); // Enable the texture coordinate array for Texture 1
gl.glClientActiveTexture(GL11.GL_TEXTURE1);
gl.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
gl.glClientActiveTexture(GL11.GL_TEXTURE0);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); // mMatrixValues and mAlpha will be initialized in setSize()
}

这段代码的作用是为顶点坐标BOC_COORDINATES分配了一块缓冲区。

该坐标定义如下:

    private static final float[] BOX_COORDINATES = {
0, 0, 1, 0, 0, 1, 1, 1, // used for filling a rectangle
0, 0, 1, 1, // used for drawing a line
0, 0, 0, 1, 1, 1, 1, 0}; // used for drawing the outline of a rectangle

接下来我们看下在GLCanvas中看到的几个重要函数的实现:

2.drawRect()

    public void drawRect(float x, float y, float width, float height, GLPaint paint) {
GL11 gl = mGL; mGLState.setColorMode(paint.getColor(), mAlpha);
mGLState.setLineWidth(paint.getLineWidth()); saveTransform();
translate(x, y);
scale(width, height, 1); gl.glLoadMatrixf(mMatrixValues, 0);
gl.glDrawArrays(GL11.GL_LINE_LOOP, OFFSET_DRAW_RECT, 4); restoreTransform();
mCountDrawLine++;
}

这里重要的是glDrawArrays这一调用,这是一个真正的绘图函数,参数意义如下:

GL_LINE_LOOP:从第一个顶点到最后一个顶点依次相连,并且第一个顶点和最后一个顶点相连.

OFFSET_DRAW_RECT:从数组缓存中的这一位开始绘制,代码中值为6

4:数组中顶点的数目。

3.drawTexture()

    public void drawTexture(BasicTexture texture, float[] mTextureTransform,
int x, int y, int w, int h) {
mGLState.setBlendEnabled(mBlendEnabled
&& (!texture.isOpaque() || mAlpha < OPAQUE_ALPHA));
if (!bindTexture(texture)) return;
setTextureCoords(mTextureTransform);
mGLState.setTextureAlpha(mAlpha);
textureRect(x, y, w, h);
}

drawTexture()还有另外一个public的复写函数,具体使用到的时候再具体分析,二者中都有比较重要的是textureRect()这个调用:

3.1textureRect()

    private void textureRect(float x, float y, float width, float height) {
GL11 gl = mGL; saveTransform();
translate(x, y);
scale(width, height, 1); gl.glLoadMatrixf(mMatrixValues, 0);
gl.glDrawArrays(GL11.GL_TRIANGLE_STRIP, OFFSET_FILL_RECT, 4); restoreTransform();
mCountTextureRect++;
}

这里也有了真正的绘图函数,glDrawArrays。我们分析下它的绘制:

GL_TRIANGLE_STRIP:这个参数解释起来有点复杂,需要设计到OpenGL的绘制单元。可以百度了解。

OFFSET_FILL_RECT:值为0

综上所述,GLCanvas和GLCanvasImpl是实现视图画图布局的地方。至于具体画成什么样则需要查看具体调用的地方传进来的参数的样子。

Android4.2.2 Gallery2源码分析(5)——GLCanvasImpl.java的更多相关文章

  1. Android4.2.2 Gallery2源码分析(4)——GLCanvas.java

    首先申明,找到这个类是在GLRootView.java中发现的线索.这是一个接口,源码中对该接口作了详细的说明: // // GLCanvas gives a convenient interface ...

  2. Android4.2.2 Gallery2源码分析(2)——发现Gallery.java

    上文中,main.xml是我直接提出来的,并没有说明是怎么找到它的,现在说明发现它的理由: 一般我们分析界面布局会用到hierarchyviewer这个工具,从工具中,我们对应到视图,最主要的视图id ...

  3. JVM源码分析之一个Java进程究竟能创建多少线程

    JVM源码分析之一个Java进程究竟能创建多少线程 原创: 寒泉子 你假笨 2016-12-06 概述 虽然这篇文章的标题打着JVM源码分析的旗号,不过本文不仅仅从JVM源码角度来分析,更多的来自于L ...

  4. JDK源码分析:Short.java

    Short是基本数据类型short的包装类. 1)声明部: public final class Short extends Number implements Comparable<Short ...

  5. JDK源码分析:Object.java

    一. 序言 Object.java是一切类的基类,所以了解该类有一定的必要 二 .属性及方法分析 方法列表: private static native void registerNatives(); ...

  6. JDK源码分析:Integer.java部分源码解析

    1)声明部: public final class Integer extends Number implements Comparable<Integer> extends Number ...

  7. JDK源码分析:Byte.java

    Byte是基本数据类型byte的包装类. 1)声明部分: public final class Byte extends Number implements Comparable<Byte> ...

  8. Java集合系列:-----------03ArrayList源码分析

    上一章,我们学习了Collection的架构.这一章开始,我们对Collection的具体实现类进行讲解:首先,讲解List,而List中ArrayList又最为常用.因此,本章我们讲解ArrayLi ...

  9. [源码分析]Java1.8中StringJoiner的使用以及源码分析

    [源码分析]StringJoiner的使用以及源码分析 StringJoiner是Java里1.8新增的类, 或许有一部分人没有接触过. 所以本文将从使用例子入手, 分析StringJoiner的源码 ...

随机推荐

  1. SQL必知必会 -------- 聚集函数、分组排序

    聚集函数 1.AVG()函数 输入:SELECT AVG(prod_price) AS avg_price FROM Products 输出: 警告:只用于单个列AVG()只能用来确定特定数值列的平均 ...

  2. Java常用工具类之时间转换(注释乱码,全)

    package com.wazn.learn.util; import java.text.ParseException; import java.text.SimpleDateFormat; imp ...

  3. 图形管线之旅 Part6

    原文:<A trip through the Graphics Pipeline 2011> 翻译:往昔之剑   转载请注明出处   欢迎回来.这次我们去看看三角形的光栅化.但在光栅化三角 ...

  4. Failed to add VMware DC to zone due to : This DC is being managed by other CloudStack deployment.

    1.下载VMware-PowerCLI 2.安装VMware-PowerCLI 安装过程中会重复重启,请确认重启,不要设置稍后手动重启. 3.在开始,菜单中选择 vmware ->VMware ...

  5. Inno Setup Winfrom 打包工具

    1.下载并安装Inno Setup 编译器 2.安装完成后打开Inno Setup 编译器: 3.选择[用「脚本向导」创建新的脚本文件(S)]: 4.点击[下一步]: 5.填写制作后程序的基本信息: ...

  6. 如何配置FastReport.Net环境

    利用FastReport.Net工具箱中的EnvironmentSettings组件可以控制FastReport.Net的环境设置.把EnvironmentSettings组件放到窗体上,并使用下面的 ...

  7. Java并发(十):读写锁ReentrantReadWriteLock

    先做总结: 1.为什么用读写锁 ReentrantReadWriteLock? 重入锁ReentrantLock是排他锁,在同一时刻仅有一个线程可以进行访问,但是在大多数场景下,大部分时间都是提供读服 ...

  8. 【洛谷】2990:[USACO10OPEN]牛跳房子Cow Hopscotch【单调队列优化DP】

    P2990 [USACO10OPEN]牛跳房子Cow Hopscotch 题目描述 The cows have reverted to their childhood and are playing ...

  9. PHP -- 简单表单提交

    网上看博文,一步步入门~~ 简单表单,简单提交 @_@!! <?php //php代码部分开始 echo "<html>"; echo "<hea ...

  10. 简单破解 Sencha Architect 2.2 (ExtJs Designer)

    Sencha Architect 2是ExtJS和Sencha Touch的官方可视化IDE工具.最新版本是2.2,说是破解,其实是修改License来实现无限试用而已. 1.先下载安装官方软件,大约 ...