Android4.2.2 Gallery2源码分析(5)——GLCanvasImpl.java
来源:互联网 发布:好东东网络课 编辑:程序博客网 时间:2024/05/17 23:56
GLCanvasImpl.java是接口GLCanvas的唯一实现类,也就是说二者在功能上完全等同。代码中调用GLCanvas对象函数的地方,等效于调用GLCanvasImpl中的该函数,GLCanvasImpl对该函数有具体的实现。
1.构造函数
- GLCanvasImpl(GL11 gl) {
- mGL = gl;
- mGLState = new GLState(gl);
- initialize();
- }
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);
- }
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()
- }
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
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++;
- }
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);
- }
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++;
- }
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
- Android4.2.2 Gallery2源码分析(5)——GLCanvasImpl.java
- Android4.2.2 Gallery2源码分析(4)——GLCanvas.java
- Android4.2.2 Gallery2源码分析(6)——GLView.java
- Android4.2.2 Gallery2源码分析(4)——GLCanvas.java
- Android4.2.2 Gallery2源码分析(6)——GLView.java
- Android4.2.2 Gallery2源码分析(3)——分析Gallery.java
- Android4.2.2 Gallery2源码分析(3)——分析Gallery.java
- Android4.2.2 Gallery2源码分析(2)——发现Gallery.java
- Android4.2.2 Gallery2源码分析(2)——发现Gallery.java
- Android4.2.2 Gallery2源码分析(1)——从布局入手
- Android4.2.2 Gallery2源码分析(7)——canvas的调用堆栈
- Android4.2.2 Gallery2源码分析(8)——假装的Activity
- Android4.2.2 Gallery2源码分析(9)——三个界面的跳转
- Android4.2.2 Gallery2源码分析(10)——Activity于View的结合
- Android4.2.2 Gallery2源码分析(11)——Gallery的层次结构图
- Android4.2.2 Gallery2源码分析(1)——从布局入手 .
- Android4.2.2 Gallery2源码分析(7)——canvas的调用堆栈
- 如何申请微信公众平台帐号
- mysql 安装与主从配置
- Mini2440 Linux移植_01
- 使用ab进行页面的压力测试
- 关于内存函数GlobalLock(),GlobalAlloc(),GlobalUnLock()用法
- Android4.2.2 Gallery2源码分析(5)——GLCanvasImpl.java
- jackson
- Oracle高级应用之合并MERGE
- Oracle 绝对值函数
- php基础(三)
- 使用SNMP进行网络设备的监控管理
- 经典的指针错误,在方法中,指针不要相互赋值,应该赋这个指针的内容。
- ext/hash_map:进一步提高字符串为键的哈希表的性能
- SVG文档语法结构