public class Polygon{
/** The buffer holding the Polygon‘s vertices
保存Polygon對象頂點坐標的FloatBuffer
*/
private FloatBuffer vertexBuffer;
/** The initial vertex definition
保存Polygon對象頂點坐標的的float數組
*/
private float vertices[] = {
0.0f, 1.0f, 0.0f, //Top
-1.0f, -1.0f, 0.0f, //Bottom Left
1.0f, -1.0f, 0.0f //Bottom Right
};
/**
* The Triangle constructor.
*
* Initiate the buffers.
*/
public Triangle() {
//this is the common method to initiate the FloatBuffer
//下面是一種常用的初始化FloatBuffer的方法,本人還見到過一種方法,如下:
//vertexBuffer = FloatBuffer.wrap(vertices)
//但是如果用這種方法在運行的時候會報錯,指出你的FloatBuffer沒有序列化,
//不明白原因,如有明白的高手幫解釋一下,不勝感激
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
}
/**
* The object own drawing function.
* Called from the renderer to redraw this instance
* with possible changes in values.
*
* @param gl - The GL context
*/
public void draw(GL10 gl) {
//這就是Polygon被繪制的方法,下面都是一些在draw方法中經常用到的簡單的設置,
//在此不一一解釋了
//Set the face rotation
gl.glFrontFace(GL10.GL_CW);
//Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
//Enable vertex buffer
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
2)下面就是Renderer子類,它就是一個OpenGL渲染器,就是真正繪制3D圖形的地方,主要是重寫三個方法(三個方法將在下面一一標出),設置一些屬性,來完成我們想要達到的效果,代碼如下:
public class Myrenderer implements Renderer {
public Myrenderer () {
triangle = new Triangle();
square = new Square();
}
/**
* The Surface is created/init()
這個方法是當surface創建時調用的方法,主要是設置一些屬性
*/
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //Black Background
gl.glClearDepthf(1.0f); //Depth Buffer Setup
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
//Really Nice Perspective Calculations
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
}
/**
* Here we do our drawing
*/
public void onDrawFrame(GL10 gl) {
//這個方法就是真正繪制3D圖形的方法,系統會根據機器的性能在固定的時間間隔自動調用這個方法
//這裡通過設置gl的屬性,和我們定義的Polygon類的頂點坐標來繪制我們想要達到的效果
//Clear Screen And Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity(); //Reset The Current Modelview Matrix
gl.glTranslatef(0.0f, -1.2f, -6.0f); //Move down 1.2 Unit And Into The Screen 6.0
square.draw(gl); //Draw the square
gl.glTranslatef(0.0f, 2.5f, 0.0f); //Move up 2.5 Units
triangle.draw(gl); //Draw the triangle
}
/**
* If the surface changes, reset the view
*/
public void onSurfaceChanged(GL10 gl, int width, int height) {
//這個方法是當surface改變時調用的方法,也是設置一些gl的屬性,
//大體的設置沒有太大變化,所以這基本上是一個通用的寫法
if(height == 0) { //Prevent A Divide By Zero By
height = 1; //Making Height Equal One
}
gl.glViewport(0, 0, width, height); //Reset The Current Viewport
gl.glMatrixMode(GL10.GL_PROJECTION); //Select The Projection Matrix
gl.glLoadIdentity(); //Reset The Projection Matrix
//Calculate The Aspect Ratio Of The Window
GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW); //Select The Modelview Matrix
gl.glLoadIdentity(); //Reset The Modelview Matrix
}
}
3)最後就是把我們的GLSurfaceView通過activity的setContentView()方法加載到屏幕上,代碼如下:
public class Run extends Activity {
/** The OpenGL View */
private GLSurfaceView glSurface;
/**
* Initiate the OpenGL View and set our own
* Renderer */
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Create an Instance with this Activity
glSurface = new GLSurfaceView(this);
//Set our own Renderer
glSurface.setRenderer(new Lesson02());
//Set the GLSurface as View to this Activity
setContentView(glSurface);
}
/**
* Remember to resume the glSurface
*/
@Override
protected void onResume() {
super.onResume();
glSurface.onResume();
}
/**
* Also pause the glSurface
*/
@Override
protected void onPause() {
super.onPause();
glSurface.onPause();
}
}
希望給剛剛入門的同學一些幫助,也希望和高手們交流一下經驗。