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. Python并发编程-协程

    利用Greenlet模块在多线程之间切换 from greenlet import greenlet def eat(): print('eating start') g2.switch() prin ...

  2. Python - 软件设计规范

    为什么要设计好目录结构? "设计项目目录结构",就和"代码编码风格"一样,属于个人风格问题.对于这种风格上的规范,一直都存在两种态度: 一类同学认为,这种个人风 ...

  3. 【JAVAWEB学习笔记】22_ajax:异步校验用户名和站内查询

    Js原生Ajax和Jquery的Ajax 学习目标 案例1-异步校验用户名是否存在 案例2-站内查询 一.Ajax概述 1.什么是同步,什么是异步 同步现象:客户端发送请求到服务器端,当服务器返回响应 ...

  4. 【UOJ #206】【APIO 2016】Gap

    http://uoj.ac/problem/206 对于T=1,直接从两端往中间跳可以遍历所有的点. 对于T=2,先求出最小值a和最大值b,由鸽巢原理,答案一定不小于\(\frac{b-a}{N-1} ...

  5. [Codeforces 1060F] Shrinking Tree

    Link: 传送门 Solution: 原来CF的官方题解也能鸽啊…… 详细题解 该题思路: 1.对于每个点删边方案数为$fac[n-1]$,总贡献为每种方案下满足的概率的和,接下来直接求贡献 2.每 ...

  6. 谈HTTPS中间人攻击与证书校验(二)

    上文说到HTTPS的三次握手:http://www.cnblogs.com/wh4am1/p/6616851.html 不懂的再回头去看看 三.中间人攻击 https握手过程的证书校验环节就是为了识别 ...

  7. setResult()的调用时机

    今天遇到这样一个问题,我在Activity-A中用startActivityForResult()方法启动了Activity-B,并且在B中通过setResult()方法给A返回值,由于某些原因不能在 ...

  8. hdu 1011 树形dp+背包

    题意:有n个房间结构可看成一棵树,有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个房间有一定的敌人,每个士兵可以对抗20个敌人,士兵在某个房间对抗敌人使无法走开,同时有一个价值,问你花费这m个士 ...

  9. poj 1988 并查集(终于看懂一个了/(ㄒoㄒ)/~~)

    题意:有几个stack,初始里面有一个cube.支持两种操作:1.move x y: 将x所在的stack移动到y所在stack的顶部.2.count x:数在x所在stack中,在x之下的cube的 ...

  10. Codeforces Round #302 (Div. 2) C. Writing Code 简单dp

    C. Writing Code Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/544/prob ...