Android中2D计算机图形学二维变换变换时如何切换...

Android OpenGl ES 初级学习笔记
算是图形学吧,那神马,图形学也开始上课了&&*****************Android OpenGl ES 学习笔记*******************&&& &&&& By xbw零:【为何学OpenGl ES】作为一个图形库,OpenGl被很多游戏大作使用。移动端的OpenGl ES则是从节省性能考虑,精简了OpenGl,使之更适合移动平台。OpenGl当然是为了绘制3D图形的,对于开发3D游戏或一些涉及到3D图形显示的软件都要用这个,如iReader的模拟出的书本翻页效果。其实我觉得即使对于2D图形,很多地方用opengl比系统自带的绘图函数好用的多,比如贴图旋转平移什么的~&&一:【构造OpenGL ES View】&1.关于GLSurfaceView&Android平台提供的OpenGL ES API主要定义在包android.opengl ,javax.microedition.khronos.egl ,javax.microedition.khronos.opengles,java.nio等几个包中,其中类GLSurfaceView为这些包中的核心类:&* 起到连接OpenGL ES与Android 的View层次结构之间的桥梁作用。* 使得Open GL ES库适应于Anndroid系统的Activity生命周期。* 使得选择合适的Frame buffer像素格式变得容易。* 创建和管理单独绘图线程以达到平滑动画效果。* 提供了方便使用的调试工具来跟踪OpenGL ES函数调用以帮助检查错误。&&&因此编写OpenGL ES应用的起始是从类GLSurfaceView开始,设置GLSurfaceView只需调用一个方法来设置OpenGLView用到的Renderer。一般的android程序主Activity中用setContentView来设置程序用到的layout布局,即程序的界面效果,opengl只需要构造好Renderer,将其添加入GlSurfaceView,再setContentView将activity设置为用这个gl的view作为显示就行了。&2.关于GLSurfaceView.Renderer&定义了一个统一图形绘制的接口,它定义了如下三个接口函数:* onSurfaceCreated:在这个方法中主要用来设置一些绘制时不常变化的参数,比如:背景色,是否打开z-buffer等。* onDrawFrame:定义实际的绘图操作。* onSurfaceChanged:如果设备支持屏幕横向和纵向切换,这个方法将发生在横向&-&纵向互换时.此时可以重新设置绘制的纵横比率。&~~~~~~~则得到一个OpenGl应用的基本框架模板~~~~~~~~~~* TutorialPartI.java (主Activity)&public class TutorialPartI extends Activity {&// Called when the activity is first created.&@Override&public void onCreate(Bundle savedInstanceState) {&super.onCreate(savedInstanceState);&this.requestWindowFeature(Window.FEATURE_NO_TITLE); // (NEW)&getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,&WindowManager.LayoutParams.FLAG_FULLSCREEN); // (NEW)&&GLSurfaceView view = new GLSurfaceView(this);//构造view&view.setRenderer(new OpenGLRenderer());&setContentView(view);&}}&&&* OpenGLRenderer.java(关键)&public class OpenGLRenderer implements Renderer {&public void onSurfaceCreated(GL10 gl, EGLConfig config) {&// Set the background color to black ( rgba ).&gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); &// OpenGL docs.&// Enable Smooth Shading, default not really needed.&gl.glShadeModel(GL10.GL_SMOOTH);// OpenGL docs.&// Depth buffer setup.&gl.glClearDepthf(1.0f);// OpenGL docs.&// Enables depth testing.&gl.glEnable(GL10.GL_DEPTH_TEST);// OpenGL docs.&// The type of depth testing to do.&gl.glDepthFunc(GL10.GL_LEQUAL);// OpenGL docs.&// Really nice perspective calculations.&gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, // OpenGL docs.&GL10.GL_NICEST);&}&&public void onDrawFrame(GL10 gl) {&// Clears the screen and depth buffer.&gl.glClear(GL10.GL_COLOR_BUFFER_BIT | // OpenGL docs.&GL10.GL_DEPTH_BUFFER_BIT);&}&&public void onSurfaceChanged(GL10 gl, int width, int height) {&// Sets the current view port to the new size.&gl.glViewport(0, 0, width, height);// OpenGL docs.&// Select the projection matrix&gl.glMatrixMode(GL10.GL_PROJECTION);// OpenGL docs.&// Reset the projection matrix&gl.glLoadIdentity();// OpenGL docs.&// Calculate the aspect ratio of the window&GLU.gluPerspective(gl, 45.0f,&(float) width / (float) height,&0.1f, 100.0f);&// Select the modelview matrix&gl.glMatrixMode(GL10.GL_MODELVIEW);// OpenGL docs.&// Reset the modelview matrix&gl.glLoadIdentity();// OpenGL docs.&}}&~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&&二:【3D绘图基本概念】&一个3D图形通常是由一些小的基本元素(顶点,边,面,多边形)构成,每个基本元素都可以单独来操作。&1.Vertex(顶点):3D建模的最小单位一个顶点也可以代表一个点光源或是Camera的位置。* 通常的顶点定义方式,数组形式:private float vertices[] = {&-1.0f, &1.0f, 0.0f, &// 0, Top Left&-1.0f, -1.0f, 0.0f, &// 1, Bottom Left& 1.0f, -1.0f, 0.0f, &// 2, Bottom Right& 1.0f, &1.0f, 0.0f, &// 3, Top Right};//定义了4个顶点,分别是x,y,z轴坐标,相对于原点o .定义的效果是:& 0 & & &3&& & &o点&& 1 & & &2* 与Android的View类canvas绘图不用,canvas用的屏幕坐标系,即屏幕左上角为原点(0,0),向右正x,向下正y,坐标点的值单位1为1像素。opengl用的世界坐标系,以屏幕中心为(0,0,0),单位可自行决定,绘制时是按比例的~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~* 为了3D绘图的性能,通常用buffer类存放顶点颜色等等信息:ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length* 4); & //一个float等于4个byte,因此要*4vbb.order(ByteOrder.nativeOrder());//设置字节序FloatBuffer vertexBuffer = vbb.asFloatBuffer();//不同buf转换vertexBuffer.put(vertices); &//即将以上的数组放入buffervertexBuffer.position(0);//这个position值表示下一个可以读写的字节的缺省位置,相当于一个指针~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~* 有了顶点的定义,下面一步就是如何将它们传给OpenGL ES库。OpenGl使用管道机制,来开关某些功能gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//打开传递buf功能gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);//将定义点的数组buf传递到openglgl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//关闭传递buf功能&2.Edge(边)在OpenGL中,通常无需直接来定义一个边,而是通过顶点定义一个面,从而又面定义了这个面所拥有的边。修改两端点,从而可以修改一条边&3.Face(面)在OpenGL ES中,面特指一个三角形,由三个顶点和三条边构成,对一个面所做的变化影响到连接面的所有顶点和边,面多边形* 定义面的顶点的顺序很重要,在拼接曲面的时候,顶点的顺序定义了面的朝向(前向或是后向),为了获取绘制的高性能,一般情况不会绘制面的前面和后面,只绘制面的&前面&。虽然&前面&&后面&的定义可以应人而易,但一般为所有的&前面&定义统一的顶点顺序(顺时针或是逆时针方向)。&~~~~~~~~~~~~~~设置面的三种操作~~~~~~~~~~* gl.glFrontFace(GL10.GL_CCW); //设置逆时针方法为面的"前面"。顺时针为CW* gl.glEnable(GL10.GL_CULL_FACE);//打开忽略"后面"设置* gl.glCullFace(GL10.GL_BACK);//明确指明&忽略&哪个面~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~4.Polygon (多边形)多边形由多个面(三角形)拼接而成,在三维空间上,多边形不一定表示这个Polygon在同一平面上~~~~~~实例:~~~~~private short[] indices = {0,1,2,0,2,3}; &//顶点连接顺序ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2); &//indices为short型,要*2 。(byte 8位,short 16位)ibb.order(ByteOrder.nativeOrder()); &ShortBuffer indexBuffer = ibb.asShortBuffer();&indexBuffer.put(indices); &//放入数据indexBuffer.position(0);~~~~~~~~~~~~~~~~~~~~~~~~~~~&5.Render (渲染)定义好了多边形,下面是如何使用OpenGL ES的API来绘制(渲染)这个多边形。OpenGL ES提供了两类方法来绘制一个空间几何图形:* public abstract void glDrawArrays(int mode, int first, int count)//使用VetexBuffer来绘制,顶点的顺序由vertexBuffer中的顺序指定。若没定义indices就用这个函数* public abstract void glDrawElements(int mode, int count, int type, Buffer indices) //可以重新定义顶点的顺序,顶点的顺序由indices指定。* 上面两方法中的mode分类:GL_POINTS(独立的点)、GL_LINE_STRIP(按顺序不间断的一条线)、GL_LINE_LOOP(首尾封闭)、GL_LINES(两两相连的多条线段)、GL_TRIANGLES(三三组成的分离的三角形)、GL_TRIANGLE_STRIP(相连的三角形)、GL_TRIANGLE_FAN(以起点为公共顶点的相连多个三角形)&~~~~~~~~~~举例,下面是绘制一个正方形~~~~~~~~~~~* Square.javapublic class Square {&private float vertices[] = {&-1.0f, &1.0f, 0.0f, &// 0, Top Left&-1.0f, -1.0f, 0.0f, &// 1, Bottom Left&1.0f, -1.0f, 0.0f, &// 2, Bottom Right&1.0f, &1.0f, 0.0f, &// 3, Top Right&};&private short[] indices = { 0, 1, 2, 0, 2, 3 };&private FloatBuffer vertexB&private ShortBuffer indexB&&&public Square() {&ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);&vbb.order(ByteOrder.nativeOrder());&vertexBuffer = vbb.asFloatBuffer();&vertexBuffer.put(vertices);&vertexBuffer.position(0);&&ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);&ibb.order(ByteOrder.nativeOrder());&indexBuffer = ibb.asShortBuffer();&indexBuffer.put(indices);&indexBuffer.position(0);&}&&public void draw(GL10 gl) {&gl.glFrontFace(GL10.GL_CCW);&gl.glEnable(GL10.GL_CULL_FACE);&gl.glCullFace(GL10.GL_BACK);&&gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);&gl.glVertexPointer(3, GL10.GL_FLOAT, 0,vertexBuffer);&&gl.glDrawElements(GL10.GL_TRIANGLES, indices.length,&GL10.GL_UNSIGNED_SHORT, indexBuffer);&&gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);&gl.glDisable(GL10.GL_CULL_FACE); &//一般有enable必对应一个disable函数&}}* 相应的在OpenGlRenderer中加入Square对象的实例化,并在其onDrawFrame函数中调用square.draw(gl);* 这时,并不能看到画面,还需要在draw之前调用gl.glLoadIdentity();//每次调用onDrawFrame时重置,防止每次都后移4单位gl.glTranslatef(0, 0, -4);//由于OpenGl Es渲染时,默认坐标是(0,0,0),其中Z轴为0,这个0的基准为屏幕,即绘制时贴着屏幕画的。所以要后平移4个单位,从立体的视角&向屏幕里面去一点&~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&三:【3D坐标变换】&1.Coordinate System(坐标系)OpenGl使用右手坐标系:右手拇指指x轴正向,中指y轴正向,着z轴正向为掌心向外&2.Translate (平移)之前的glTranslatef(float x,float y,float z)即为平移变换函数,可以进行多次平移变换,其结果为多个平移矩阵的累计结果,矩阵的顺序不重要,可以互换&3.Rotate(旋转)glRotatef(float angle,float x,float y,float z)函数,除了xyz,还有一个旋转变换角度angle,定义旋转的参照矢量方向。多次旋转次序很重要。glRotatef(angle,-x,-y,-z)和glRotatef(-angle,x,y,z)等价的。~~~~~~~~~~~示例~~~~~~~~~~~gl.glRotatef(90f, 1.0f, 0.0f, 0.0f);//拇指指+x,向四指方向旋转gl.glRotatef(90f, 0.0f, 1.0f, 0.0f);//下同gl.glRotatef(90f, 0.0f, 0.0f, 1.0f);//***多次旋转的话坐标轴是跟随着几何体一起旋转的,下一次旋转是在前一次旋转得到的坐标轴基础上转的~~~~~~~~~~~~~~~~~~~~~~~~~~~&4.Translate & Rotate (平移和旋转组合变换)就是上面那句话:坐标变换都是相对于变换的Mesh本身的坐标系而进行的&5.Scale(缩放)方法public abstract void glScalef (float x, float y, float z)用于缩放变换。gl.glScalef(2f, 2f, 2f)即xyz均乘以二&6.Translate & Scale(平移和缩放组合变换)同样当需要平移和缩放时,变换的顺序也会影响最终结果,因为这时候单位&1&发生了变化&7.矩阵操作,单位矩阵如果需要将当前矩阵回复最初的无变换的矩阵,可以使用单位矩阵(无平移,缩放,旋转),使用public abstract void glLoadIdentity()在栈中保存当前矩阵和从栈中恢复所存矩阵,可以使用public abstract void glPushMatrix();public abstract void glPopMatrix();~~~~~~~~~~~~~~~~~~~~举例~~~~~~~~~~~``~~~~~~~~~~~绘制3个正方形A,B,C,使的B比A小50%,C比B小50%。 然后以屏幕中心逆时针旋转A,B以A为中心顺时针旋转,C以B为中心顺时针旋转同时以自己中心高速逆时针旋转gl.glTranslatef(0, 0, -10);//得到原始矩阵gl.glPushMatrix();//存储原始矩阵gl.glRotatef(angle, 0, 0, 1);//变换原始矩阵,得到Asquare.draw(gl);//画出A&gl.glPopMatrix();//回归原始矩阵gl.glPushMatrix();//存储原始矩阵gl.glRotatef(-angle, 0, 0, 1);//绕原始矩阵中心旋转gl.glTranslatef(2, 0, 0);//右移gl.glScalef(.5f, .5f, .5f);//缩小,得到Bsquare.draw(gl);//画出B&gl.glPushMatrix();//存储Bgl.glRotatef(-angle, 0, 0, 1);//绕B的中心旋转gl.glTranslatef(2, 0, 0);//右移gl.glScalef(.5f, .5f, .5f);//缩小gl.glRotatef(angle*10, 0, 0, 1);//绕右移且缩小后的中心转,得到Csquare.draw(gl);//画出C&gl.glPopMatrix();gl.glPopMatrix();&angle++;//角度自增~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&四:【给图形上色】OpenGL ES使用颜色是RGBA模式(红,绿,蓝,透明度).不同于一般情况下的10进制的RGB,即三原色均为0~255.OpenGl中三种颜色使用0.0f~1.0f的浮点数。1相当于255。&1.Flat coloring(单色)通知OpenGL使用单一的颜色来渲染,OpenGL将一直使用指定的颜色来渲染直到你指定其它的颜色,具体方法public abstract void glColor4f(float red, float green, float blue, float alpha)缺省值均为1,即为白色不透明&2.Smooth coloring(平滑颜色过渡)当给每个顶点定义一个颜色时,OpenGL自动为不同顶点颜色之间生成中间过渡颜色(渐变色)* 颜色同顶点一样,也是用数组 + buffer的方式定义的,例如下:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~float[] colors = {&1f, 0f, 0f, 1f, // vertex 0 red&0f, 1f, 0f, 1f, // vertex 1 green&0f, 0f, 1f, 1f, // vertex 2 blue&1f, 0f, 1f, 1f, // vertex 3 magenta};~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);cbb.order(ByteOrder.nativeOrder());colorBuffer = cbb.asFloatBuffer();colorBuffer.put(colors);colorBuffer.position(0);~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~然后在draw方法中加入gl.glEnableClientState(GL10.GL_COLOR_ARRAY);gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);//然后要记得disablegl.glDisableClientState(GL10.GL_COLOR_ARRAY);~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&五.【从平面到立体,绘制真正的3D图形】设计原则,创建并使用一个Mesh(网格)类来构造各种不同的3D图形。* Mesh.java ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~public class Mesh {private FloatBuffer verticesBuffer =private ShortBuffer indicesBuffer =private int numOfIndices = -1;&private float[] rgba= new float[] { 1.0f, 1.0f, 1.0f, 1.0f };&private FloatBuffer colorBuffer =&public float x = 0;public float y = 0;public float z = 0;&public float rx = 0;public float ry = 0;public float rz = 0;&public void draw(GL10 gl) {gl.glFrontFace(GL10.GL_CCW);gl.glEnable(GL10.GL_CULL_FACE);gl.glCullFace(GL10.GL_BACK);gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);gl.glVertexPointer(3, GL10.GL_FLOAT, 0, verticesBuffer);gl.glColor4f(rgba[0], rgba[1], rgba[2], rgba[3]);//渲染单色if (colorBuffer != null) { &//若colorbuffer不为空则再渲染渐变色gl.glEnableClientState(GL10.GL_COLOR_ARRAY);gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);}&gl.glTranslatef(x, y, z);gl.glRotatef(rx, 1, 0, 0);gl.glRotatef(ry, 0, 1, 0);gl.glRotatef(rz, 0, 0, 1);&gl.glDrawElements(GL10.GL_TRIANGLES, numOfIndices,GL10.GL_UNSIGNED_SHORT, indicesBuffer);gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);gl.glDisable(GL10.GL_CULL_FACE);}&protected void setVertices(float[] vertices) {ByteBuffer vbb= ByteBuffer.allocateDirect(vertices.length * 4);vbb.order(ByteOrder.nativeOrder());verticesBuffer = vbb.asFloatBuffer();verticesBuffer.put(vertices);verticesBuffer.position(0);}&protected void setIndices(short[] indices) {ByteBuffer ibb= ByteBuffer.allocateDirect(indices.length * 2);ibb.order(ByteOrder.nativeOrder());indicesBuffer = ibb.asShortBuffer();indicesBuffer.put(indices);indicesBuffer.position(0);numOfIndices = indices.}&protected void setColor(float red, float green,float blue, float alpha) {rgba[0] =rgba[1] =rgba[2] =rgba[3] =}&protected void setColors(float[] colors) {ByteBuffer cbb= ByteBuffer.allocateDirect(colors.length * 4);cbb.order(ByteOrder.nativeOrder());colorBuffer = cbb.asFloatBuffer();colorBuffer.put(colors);colorBuffer.position(0);}}//在这个Mesh类中,定义有ver(点)和ind(路径),并有相应的set方法来生成Buffer,还有颜色的set,旋转与平移的xyz值定义。在使用时,只需要定义一个图形类从Mesh派生,然后按顺序加入顶点与连接路径,或颜色,即可得到一个自定的3D图形。例如一个Cube正方体:* Cube.java~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`public class Cube extends Mesh {&public Cube(float width, float height, float depth) {&width &/= 2;&height /= 2;&depth &/= 2;&&float vertices[] = { -width, -height, -depth, // 0&width, -height, -depth, // 1&width, &height, -depth, // 2&-width, &height, -depth, // 3&-width, -height, &depth, // 4&width, -height, &depth, // 5&width, &height, &depth, // 6&-width, &height, &depth, // 7&}; & & &//8个顶点定义好后&&short indices[] = { 0, 4, 5,&0, 5, 1,&1, 5, 6,&1, 6, 2,&2, 6, 7,&2, 7, 3,&3, 7, 4,&3, 4, 0,&4, 7, 6,&4, 6, 5,&3, 0, 1,&3, 1, 2, }; & //按一定顺序把8个点连起来&&setIndices(indices);&setVertices(vertices); //两个set,就得到了一个单色正方体。&}}~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&&六:【材质渲染】前面是用颜色给图形上色,这里讲的是用bitmap位图来渲染&1.创建Bitmap对象方法同android中的获取bitmap的方法,即:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&Bitmap bitmap = BitmapFactory.decodeResource(contect.getResources(),R.drawable.icon);~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~* 要注意的是,有些设备对使用的Bitmap的大小有要求,要求Bitmap的宽度和长度为2的几次幂(1,2,4,8,16,32,64.。。。),如果使用不和要求的Bitmap来渲染,可能只会显示白色。&2.创建材质(Generating a texture)&* 首先,获取一个texture 的id~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~int[] textures = new int[1];// Tell OpenGL to generate textures.gl.glGenTextures(1, textures, 0);~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&* textures中存放了创建的Texture ID,使用同样的Texture Id ,也可以删除一个Texture,调用方法gl.glDeleteTextures(1, textures, 0);&* 然后调用这个函数时通知opengl使用这个textures:gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);&*下一步需要给Texture填充设置参数,用来渲染的Texture可能比要渲染的区域大或者小,这时需要设置Texture需要放大或是缩小时OpenGL的模式~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&gl.glTexParameterf(GL10.GL_TEXTURE_2D,&GL10.GL_TEXTURE_MAG_FILTER,&GL10.GL_LINEAR);//当texures小了,需要放大gl.glTexParameterf(GL10.GL_TEXTURE_2D,&GL10.GL_TEXTURE_MIN_FILTER,&GL10.GL_LINEAR);//当texures需要缩小~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&参数GL10.GL_LINEAR和GL10.GL_NEAREST,前者是模糊处理的,后者清晰&3.UV Mapping告知OpenGL库如何将Bitmap的像素映射到Mesh上,分两步&* &1&定义UV坐标UV Mapping指将Bitmap的像素映射到Mesh上的顶点。UV坐标定义image左上角(0,0),右下角(1,1)(因为使用的2D Texture),即映射这两个点到vertics坐标上即可。例如~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~float textureCoordinates[] = {0.0f, 1.0f,&1.0f, 1.0f,&0.0f, 0.0f,&1.0f, 0.0f };//应该也相当于一个路径,染色顺序是左下右下左上右上~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~float textureCoordinates[] = {0.0f, 0.5f,&0.5f, 0.5f,&0.0f, 0.0f,&0.5f, 0.0f };//这样会得到image左上四分之一图来渲染~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~float textureCoordinates[] = {0.0f, 2.0f,&2.0f, 2.0f,&0.0f, 0.0f,&2.0f, 0.0f };//这样超出Texture的边界了,这时有两种设置方法* GL_REPEAT 重复Texture。* GL_CLAMP_TO_EDGE 只靠边线绘制一次例如:gl.glTexParameterf(GL10.GL_TEXTURE_2D,&GL10.GL_TEXTURE_WRAP_S,&GL10.GL_REPEAT);gl.glTexParameterf(GL10.GL_TEXTURE_2D,&GL10.GL_TEXTURE_WRAP_T,&GL10.GL_REPEAT);//这样设置的结果是UV坐标系x方向一直重复,y方向也一直重复填充~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~&* &2&绑定Texture与图片GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);&4.使用Texture为了能够使用上面定义的Texture,需要创建一Buffer来存储UV坐标:FloatBuffer byteBuf = ByteBuffer.allocateDirect(texture.length * 4);byteBuf.order(ByteOrder.nativeOrder());textureBuffer = byteBuf.asFloatBuffer();textureBuffer.put(textureCoordinates);textureBuffer.position(0);&5.最后是渲染gl.glEnable(GL10.GL_TEXTURE_2D);// Tell OpenGL where our texture is located.gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);// Tell OpenGL to enable the use of UV coordinates.gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);// Telling OpenGL where our UV coordinates are.gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);&// ... here goes the rendering of the mesh ...&// Disable the use of UV coordinates.gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);// Disable the use of textures.gl.glDisable(GL10.GL_TEXTURE_2D);&* * 这里有非常重要的一点,我在构造一个旋转三棱锥并往上贴图时就遇到过一个问题,图形在模拟器上运行正常,但是到了手机上就贴不上图。百度才知出现这个问题原因有很多种,首先图片的大小必须得是2的幂次。还有网友是用png格式图时,要将PNG24改成PNG8-256色解决的,另外还有人是通过建立三种dpi的drawable文件夹解决的。&&到此,OpenGl ES算是入门了吧。&>&android中图片图形变换特效处理Demo
android中图片图形变换特效处理Demo
上传大小:721KB
本Demo从原理上说明了图片图形变换的原理,通过修改图片中每个像素点的位置来达到图片的图形变换。并且最后通过一个实现图片旗帜形状飘动Demo来说明,其中运用到了自定义View,自定义属性,数学上的三角函数正弦函数等知识
综合评分:0(0位用户评分)
下载个数:
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var q = $("#form1").serializeArray();
console.log(q);
var res_area_r = $.trim($(".res_area_r").val());
if (res_area_r == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
var mess = $(".res_area_r").val();
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, _username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click",'.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
$(".res_area_r").val($.trim($(".res_area").val()));
评论共有0条
审核通过送C币
Android开发 所有资源大集合。
创建者:qq_
Android studio
创建者:wz_txwy
android通用
创建者:preferg
上传者其他资源上传者专辑
仅使用TextView高仿京东淘宝各种APP活动倒计时样式aar包
仅使用TextView高仿京东淘宝各种APP活动倒计时样式
仅使用TextView高仿京东淘宝各种APP活动倒计时样式Demo
android中手机联系人字母索引表
mikyou的异步加载的缓存和优化
移动开发热门标签
VIP会员动态
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
android中图片图形变换特效处理Demo
会员到期时间:
剩余下载个数:
剩余C币:593
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
(仅够下载10个资源)
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动***等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
android中图片图形变换特效处理Demo

参考资料

 

随机推荐