上一篇自己动手写opengl 由于时间原因停止了更新,现在继续。
public static class DisplayInfo{ Canvas canvas; int height; int width; } private static DisplayInfo mInfo; public static void initDrawEnvirement(DisplayInfo info){ mInfo = info; } public enum MatrixMode{ MODE_MODEL_VIEW, MODE_PROJECTION } //for testing public static M4 mCurrentSurfaceViewProjectionMatrix = null; public static M4 mCurrentSurfaceViewModelViewMatrix = null; public static Stack<M4> mModelViewMatrixStack = new Stack<M4>(); public static Stack<M4> mProjectionMatrixStack = new Stack<M4>(); public static M4 mCurrentModelViewMatrix = new M4(); public static M4 mCurrentProjectionMatrix = new M4(); public static M4 mCurrentViewPortMatrix = new M4(); public static MatrixMode mMatrixMode = MatrixMode.MODE_MODEL_VIEW; public static float mViewPortZNear = 0.0f; public static float mViewPortZFar = 1.0f; public static GLColor mVertexColor = new GLColor(0, 0, 0); public static ArrayList<GLVertex> mVertexList = new ArrayList<GLVertex>();
从上面可以看到我们的变量基本上有以下几个
1. ModelView matrix
2.Project matrix
3.Viewport matrix
这几个矩阵就构成了把一个3D空间的(x,y,z)转换为2D空间的所有的东西。下面看看他们如何实现他们,与矩阵相关的几个函数如下:
glLoadIdentity
public static void glLoadIdentity(){ if(mMatrixMode == MatrixMode.MODE_MODEL_VIEW){ mCurrentModelViewMatrix.setIdentity(); }else{ mCurrentProjectionMatrix.setIdentity(); } }
glPushMatrix
public static void glPushMatrix(){ if(mMatrixMode == MatrixMode.MODE_MODEL_VIEW){ mModelViewMatrixStack.push(new M4(mCurrentModelViewMatrix)); }else{ mProjectionMatrixStack.push(new M4(mCurrentProjectionMatrix)); } }
glPopMatrix
public static void glPopMatrix(){ if(mMatrixMode == MatrixMode.MODE_MODEL_VIEW){ mCurrentModelViewMatrix = mModelViewMatrixStack.pop(); }else{ mCurrentProjectionMatrix = mProjectionMatrixStack.pop(); } }
glMultMatrix
public static void glMultMatrix(M4 m){ if(mMatrixMode == MatrixMode.MODE_MODEL_VIEW){ mCurrentModelViewMatrix.multiply(m); }else{ mCurrentProjectionMatrix.multiply(m); } }public static void glDepthRangef( float zNear, float zFar ){ mViewPortZNear = zNear; mViewPortZFar = zFar; }
public static void glViewport( int x, int y, int width, int height ) { int surfaceHeight = mInfo.height; float far = mViewPortZFar; float near = mViewPortZNear; float sx = width/2.0f; float ox = sx + x; float sy = height/2.0f; float oy = sy + surfaceHeight - height - y; float A = (far - near)/2.0f; float B = (far + near)/2.0f; // compute viewport matrix float[][] f = new float[4][4]; f[0][0] = sx; f[0][1] = 0; f[0][2] = 0; f[0][3] = ox; f[1][0] = 0; f[1][1] =-sy; f[1][2] = 0; f[1][3] = oy; f[2][0] = 0; f[2][1] = 0; f[2][2] = A; f[2][3] = B; f[3][0] = 0; f[3][1] = 0; f[3][2] = 0; f[3][3] = 1; mCurrentViewPortMatrix = new M4(); mCurrentViewPortMatrix.m = f; }
这下好了所有矩阵都有了,唯一的事情就是指定顶点和绘制方式了
看上去是不是很简单呢,接下就是绘制了
这个阶段主要有两个任务,一个是图元组装,另一个是图元处理。
所谓图元组装是指顶点数据根据设置的绘制方式被结合成完整的图元。例如,点绘制方式仅需要一个单独的顶点,此方式下每个顶点为一个图元;线段绘制方式则需要两个顶点,此方式下每两个顶点构成一个图元;三角形绘制方式下需要三个顶点构成一个图元。图元处理最重要的工作是裁剪,其任务是消除位于半空间(half-space)之外的部分几何图元,这个半空间是由一个剪裁平面所定义的。例如,点剪裁就是简单的接受或者拒绝顶点,线段或者多边形剪裁可能需要增加额外的顶点,具体取决于直线或者多边形与剪裁平面之间的位置关系之所以要进行裁剪时因为随着观察位置角度的不同,并不总能看到(显示到设备屏幕上)特定3D物体某个图元的全部裁剪时,若图元完全位于视景体以及自定义裁剪平面的内部,则将图元传递到后面的步骤进行处理;如果完全位于视景体或者自定义裁剪平面的外部,则丢弃该图元;如果其有一部分位于内部,另一部分位于外部,则需要裁剪该图元。
如果需要源代码,请下载此软件到手机上。
http://a.app.qq.com/o/simple.jsp?pkgname=com.wa505.kf.epassword
参考文章
http://blog.csdn.net/u013746357/article/details/52799601
http://www.songho.ca/opengl/gl_transform.html
http://mobile.51cto.com/aengine-437172.htm
