首先,要了解opengl 在android中只有三种绘制方式-点,线,和三角形。
点的描绘方式:GL_POINTS
线的描绘方式:GL_LINES(每两个顶点作为独立的线)
GL_LINE_STRIF(从第0个顶点到最后一个顶点依次相连)
GL_LINE_LOOP(从第0个顶点到最后一个顶点依次相连,最后一个顶点连接初始顶点)
GL_TRIANGLES(以 每三个顶点来 形成三角形)
GL_TRIANGLES_STRIP(n,n+1,n+2 依次连接的顶点形成的 所有三角形)
GL_TRIANGLES_FAN (以第0个顶点确定,其余两个顶点依次为n,n+1来绘制三角形 )
在绘制图像时,首先建一个类定义创建的图形形状。
第一步骤: float verticesArray 确定顶点, short indicesArray (索引)确定顺序。
第二步骤: 创建类如:Square(){}来缓冲数据;
ByteBuffer vbb = ByteBuffer.allocateDirect(verticesArray.length * 4)开辟新的累存块
vbb.order(ByteOrder.nativeOrder())
FloatBuffer vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);放入索引坐标数据
vertexBuffer.position(0);起始位置设定
第三步骤: 创建方法来构造形状
draw( GL10 gl )-->
gl.glColor4f(1.0f,0.0f,0.0f,1.0f);设置颜色
gl.glTranslatef(0.1f,0,-2.0f);创建的形状初始坐标
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);采用顶点坐标数组
gl.glVertexPointer(3//坐标数,GL10.GL_FIXED,0,vertexBuffer//顶点坐标缓冲 )指定顶点坐标数据
gl.glDrawElement(绘制方式,indicesArray.length//索引数,GL10.GL_UNSIGNED_SHORT//,索引缓冲)绘制图像
public class Square { private float vertices[] = { -0.1f, 0.1f, 0.0f, -0.1f, -0.1f, 0.0f, 0.1f, -0.1f, 0.0f, 0.1f, 0.1f, 0.0f, }; private short[] indices = {0, 1, 2, 0, 2, 3}; private FloatBuffer vertexBuffer; private ShortBuffer indexBuffer; public Square() { ByteBuffer v_byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4); v_byteBuffer.order(ByteOrder.nativeOrder()); vertexBuffer = v_byteBuffer.asFloatBuffer(); vertexBuffer.put(vertices); vertexBuffer.position(0); ByteBuffer i_byteBuffer = ByteBuffer.allocateDirect(indices.length * 2); i_byteBuffer.order(ByteOrder.nativeOrder()); indexBuffer = i_byteBuffer.asShortBuffer(); indexBuffer.put(indices); indexBuffer.position(0); } public void draw(GL10 gl) { gl.glColor4f(0.8f,0.0f,0.0f,1.0f); // gl.glLoadIdentity(); gl.glTranslatef(0.1f,0,-2.0f); // 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);
其次,再创建接口类(GLSurfaceView.Renderer)作为你要放入图像的画布。
重写方法:onSurefaceCreated,onDrawFrame和onSurfaceChanged
gl.glShadeModel(GL10.GL_SMOOTH);抗锯齿
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_NICEST);Hind模式
gl.glClearColor(0.0f,0.8f,0.0f,0.5f);桌布颜色
gl.glClearDepthf(1.0f);深度清理缓存
}
第二步骤:onDrawFrame(GL10 gl){
将之前描绘的图形初始化
gl.glClear(GL10.GL_COLOR_BUFFER_BIT| GL10.GL_DEPTH_BUFFER_BIT);清理缓存
gl.glLoadIdentity()设置当前矩阵为单位矩阵
gl.glPushMatrix();
drawLine.draw(gl);绘制图像
gl.glPopMatrix();
}
第三步骤:onSurfaceChanged(GL10 gl,int width,int height){
gl.glViewport(0,0,width,height)设置视图
gl.glMatrixMode(GL10.GL_PROJECTION);设置为投影矩阵
gl.glLoadIdentity()设置当前矩阵为单位矩阵
GLU.gluPerspective(gl,45.0f,(float)width/(float)height,0.1f,100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
public class MyRenderer implements GLSurfaceView.Renderer { Drawcub drawcub; public void onSurfaceCreated(GL10 gl, EGLConfig config){ gl.glShadeModel(GL10.GL_SMOOTH);//抗锯齿 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_NICEST);//Hind模式 gl.glClearColor(0.0f,0.0f,0.2f,0.5f);//桌布颜色 gl.glClearDepthf(1.0f);//深度清理缓存 } public void onDrawFrame(GL10 gl){ Square square = new Square(); DrawPoint drawPoint = new DrawPoint(); DrawLine drawLine = new DrawLine(); gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // Replace the current matrix with the identity matrix gl.glLoadIdentity(); gl.glPushMatrix(); // square.draw(gl); drawcub.drawSelf(gl); gl.glPopMatrix(); } public void onSurfaceChanged(GL10 gl,int width,int height){ gl.glViewport(0,0,width,height); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); GLU.gluPerspective(gl,45.0f,(float)width/(float)height,0.1f,100.0f); drawcub = new Drawcub(0,0,0,3,(float)width/(float)height); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); }
最后setContentView将初始化的GLSrefaceView(),放入activity中。
public class SceneRenderer implements GLSurfaceView.Renderer { Drawcub drawcub; public void onSurfaceCreated(GL10 gl, EGLConfig config){ gl.glShadeModel(GL10.GL_SMOOTH);//抗锯齿 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_NICEST);//Hind模式 gl.glClearColor(0.0f,0.0f,0.2f,0.5f);//桌布颜色 gl.glClearDepthf(1.0f);//深度清理缓存 } public void onDrawFrame(GL10 gl){ Square square = new Square(); DrawPoint drawPoint = new DrawPoint(); DrawLine drawLine = new DrawLine(); gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // Replace the current matrix with the identity matrix gl.glLoadIdentity(); gl.glPushMatrix(); // square.draw(gl); drawcub.drawSelf(gl); gl.glPopMatrix(); } public void onSurfaceChanged(GL10 gl,int width,int height){ gl.glViewport(0,0,width,height); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); GLU.gluPerspective(gl,45.0f,(float)width/(float)height,0.1f,100.0f); drawcub = new Drawcub(0,0,0,3,(float)width/(float)height); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); }
续写,写了一个好玩的东西。
MainActivity:
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); GLSurfaceView view = new GLSurfaceView(this); view.setRenderer(new MyRenderer()); setContentView(view); } }MyRenderer:
public class MyRenderer implements GLSurfaceView.Renderer { float positionX =0; float positionY =0; float positionZ =0; float length = 0.5f; float distance = 5; private float angle; Cube cube = new Cube(positionX,positionY,positionZ,length); SquareTest squareTest = new SquareTest(); boolean flag =true; public void onSurfaceCreated(GL10 gl, EGLConfig config){ gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); gl.glShadeModel(GL10.GL_SMOOTH); //add 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){ gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); gl.glTranslatef(positionX ,positionY, positionZ-distance); gl.glPushMatrix(); gl.glRotatef(angle, 5, 5, 5); // square.onDraw(gl); cube.onDraw(gl); gl.glPopMatrix(); gl.glPushMatrix(); DynamicPicture(); } private void DynamicPicture(){ angle++; if (flag == true){ distance = distance+ 0.02f; if (distance>=12){ flag = false; } }else if (flag ==false){ distance = distance-0.02f; if(distance<=6){ flag =true; } } } public void onSurfaceChanged(GL10 gl,int width, int height){ gl.glViewport(0,0,width,height); gl.glMatrixMode(GL10.GL_PROJECTION); gl.glLoadIdentity(); GLU.gluPerspective(gl,45.0f,(float)width/(float)height,0.1f,100.0f); gl.glMatrixMode(GL10.GL_MODELVIEW); gl.glLoadIdentity(); } }
Cube:
public class Cube { FloatBuffer verticesBuffer; ShortBuffer indexBuffer; int verticesCount ; int indexCount; public Cube(float positionX,float positionY,float positionZ, float length){ float vertices[] = { positionX-length,positionY-length,positionZ-length, -(positionX-length),positionY-length,positionZ-length, -(positionX-length),-(positionY-length),positionZ-length, positionX-length,-(positionY-length),positionZ-length, positionX-length,positionY-length,-(positionZ-length), -(positionX-length),positionY-length,-(positionZ-length), -(positionX-length),-(positionY-length),-(positionZ-length), positionX-length,-(positionY-length),-(positionZ-length), }; short index[]={ 0,1,1,2,2,3,3,0, 4,5,5,6,6,7,7,4, 0,4,1,5,2,6,3,7 }; ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4); vbb.order(ByteOrder.nativeOrder()); verticesBuffer = vbb.asFloatBuffer(); verticesBuffer.put(vertices); verticesBuffer.position(0); // ByteBuffer ibb = ByteBuffer.allocateDirect(index.length*2); ibb.order(ByteOrder.nativeOrder()); indexBuffer = ibb.asShortBuffer(); indexBuffer.put(index); indexBuffer.position(0); verticesCount = vertices.length; indexCount = index.length; } public void onDraw(GL10 gl){ gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 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_FLOAT gl.glDrawElements(GL10.GL_LINES, indexCount, GL10.GL_UNSIGNED_SHORT, indexBuffer); gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); gl.glDisable(GL10.GL_CULL_FACE); } }