Android开发之OpenGL教程.docx
《Android开发之OpenGL教程.docx》由会员分享,可在线阅读,更多相关《Android开发之OpenGL教程.docx(46页珍藏版)》请在冰豆网上搜索。
Android开发之OpenGL教程
OpenGLESTutorialforAndroid
–PartI
I'mgoingtowriteacoupleoftutorialsonusingOpenGLESonAndroidphones.ThetheoryofOpenGLESisthesameondifferentdevicessoitshouldbequiteeasytoconvertthemtoanotherplatform.
Ican'talwaysrememberwhereIfoundparticularinfosoImightnotalwaysbeabletogiveyoutherightreference.IfyoufeelthatIhaveborrowedstufffromyoubuthaveforgottentoaddyouasareference,pleasee-mailme.
InthecodeexamplesIwillhavetwodifferentlinksforeachfunction.TheactualfunctionwillbelinkedtotheandroiddocumentationandafterthatIwillalsolinktheOpenGLdocumentations.Likethis:
gl.glClearColor(0.0f,0.0f,0.0f,0.5f);//OpenGLdocs.
So,let'sstart.
InthistutorialIwillshowyouhowtosetupyourOpenGLESviewthat’salwaysagoodplacetostart.
SettingupanOpenGLESView
SettingupaOpenGLviewhasneverbeenhardandonAndroiditisstilleasy.Therereallyareonlytwothingsyouneedtogetstarted.
GLSurfaceView
GLSurfaceViewisaAPIclassinAndroid1.5thathelpsyouwriteOpenGLESapplications.
∙ProvidingthegluecodetoconnectOpenGLEStotheViewsystem.
∙ProvidingthegluecodetomakeOpenGLESworkwiththeActivitylife-cycle.
∙Makingiteasytochooseanappropriateframebufferpixelformat.
∙Creatingandmanagingaseparaterenderingthreadtoenablesmoothanimation.
∙Providingeasy-to-usedebuggingtoolsfortracingOpenGLESAPIcallsandcheckingforerrors.
IfyouwanttogetgoingfastwithyourOpenGLESapplicationthisiswhereyoushouldstart.
Theonlyfunctionyouneedtocallonis:
publicvoidsetRenderer(GLSurfaceView.Rendererrenderer)
Readmoreat:
GLSurfaceView
GLSurfaceView.Renderer
GLSurfaceView.Rendererisagenericrenderinterface.Inyourimplementationofthisrendereryoushouldputallyourcallstorenderaframe.
Therearethreefunctionstoimplement:
//Calledwhenthesurfaceiscreatedorrecreated.
publicvoidonSurfaceCreated(GL10gl,EGLConfigconfig)
//Calledtodrawthecurrentframe.
publicvoidonDrawFrame(GL10gl)
//Calledwhenthesurfacechangedsize.
publicvoidonSurfaceChanged(GL10gl,intwidth,intheight)
onSurfaceCreated
Hereit'sagoodthingtosetupthingsthatyoudon'tchangesooftenintherenderingcycle.Stufflikewhatcolortoclearthescreenwith,enablingz-bufferandsoon.
onDrawFrame
Hereiswheretheactualdrawingtakeplace.
onSurfaceChanged
Ifyourdevicesupportsflippingbetweenlandscapeandportraityouwillgetacalltothisfunctionwhenithappens.Whatyoudohereissettinguppthenewratio.
Readmoreat:
GLSurfaceView.Renderer
Puttingittogether
Firstwecreateouractivity,wekeepitcleanandsimple.
packagese.jayway.opengl.tutorial;
importandroid.app.Activity;
importandroid.opengl.GLSurfaceView;
importandroid.os.Bundle;
publicclassTutorialPartIextendsActivity{
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
GLSurfaceViewview=newGLSurfaceView(this);
view.setRenderer(newOpenGLRenderer());
setContentView(view);
}
}
Ourrenderertakeslittlebitmoreworktosetup,lookatitandIwillexplainthecodeabitmore.
packagese.jayway.opengl.tutorial;
importjavax.microedition.khronos.egl.EGLConfig;
importjavax.microedition.khronos.opengles.GL10;
importandroid.opengl.GLU;
importandroid.opengl.GLSurfaceView.Renderer;
publicclassOpenGLRendererimplementsRenderer{
/*
*(non-Javadoc)
*
*@see
*android.opengl.GLSurfaceView.Renderer#onSurfaceCreated(javax.
*microedition.khronos.opengles.GL10,javax.microedition.khronos.
*egl.EGLConfig)
*/
publicvoidonSurfaceCreated(GL10gl,EGLConfigconfig){
//Setthebackgroundcolortoblack(rgba).
gl.glClearColor(0.0f,0.0f,0.0f,0.5f);//OpenGLdocs.
//EnableSmoothShading,defaultnotreallyneeded.
gl.glShadeModel(GL10.GL_SMOOTH);//OpenGLdocs.
//Depthbuffersetup.
gl.glClearDepthf(1.0f);//OpenGLdocs.
//Enablesdepthtesting.
gl.glEnable(GL10.GL_DEPTH_TEST);//OpenGLdocs.
//Thetypeofdepthtestingtodo.
gl.glDepthFunc(GL10.GL_LEQUAL);//OpenGLdocs.
//Reallyniceperspectivecalculations.
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,//OpenGLdocs.
GL10.GL_NICEST);
}
/*
*(non-Javadoc)
*
*@see
*android.opengl.GLSurfaceView.Renderer#onDrawFrame(javax.
*microedition.khronos.opengles.GL10)
*/
publicvoidonDrawFrame(GL10gl){
//Clearsthescreenanddepthbuffer.
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|//OpenGLdocs.
GL10.GL_DEPTH_BUFFER_BIT);
}
/*
*(non-Javadoc)
*
*@see
*android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(javax.
*microedition.khronos.opengles.GL10,int,int)
*/
publicvoidonSurfaceChanged(GL10gl,intwidth,intheight){
//Setsthecurrentviewporttothenewsize.
gl.glViewport(0,0,width,height);//OpenGLdocs.
//Selecttheprojectionmatrix
gl.glMatrixMode(GL10.GL_PROJECTION);//OpenGLdocs.
//Resettheprojectionmatrix
gl.glLoadIdentity();//OpenGLdocs.
//Calculatetheaspectratioofthewindow
GLU.gluPerspective(gl,45.0f,
(float)width/(float)height,
0.1f,100.0f);
//Selectthemodelviewmatrix
gl.glMatrixMode(GL10.GL_MODELVIEW);//OpenGLdocs.
//Resetthemodelviewmatrix
gl.glLoadIdentity();//OpenGLdocs.
}
}
Fullscreen
JustaddthislinesintheOpenGLDemoclassandyouwillgetfullscreen.
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);//(NEW)
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);//(NEW)
...//Previouscode.
}
Thisisprettymuchallyouneedtogetyourviewupandrunning.Ifyoucompileandrunityouwillseeaniceblackscreen.
OpenGLESTutorialforAndroid
–PartII
PrevioustutorialwasallaboutsettinguptheGLSurfaceView.Besuretoreaditbeacuseit'sareallyimportentonetobeabletocontinue.
Buildingapolygon
Inthistutorialwewillrenderourfirstpolygon.
3Dmodelsarebuiltupwithsmallerelements(vertices,edges,faces,andpolygons)whichcanbemanipulatedindividually.
Vertex
Avertex(verticesinplural)isthesmallestbuildingblockof3Dmodel.Avertexisapointwheretwoormoreedgesmeet.Ina3Dmodelavertexcanbesharedbetweenallconnectededges,pacesandpolygons.Avertexcanalsobearepresentforthepositionofacameraoralightsource.Youcanseeavertexintheimagebelowmarkedinyellow.
Todefinetheverticesonandroidwedefinethemasafloatarraythatweputintoabytebuffertogainbetterperformance.Lookattheimagetotherightandthecodebelowtomatchtheverticesmarkedontheimagetothecode.
privatefloatvertices[]={
-1.0f,1.0f,0.0f,//0,TopLeft
-1.0f,-1.0f,0.0f,//1,BottomLeft
1.0f,-1.0f,0.0f,//2,BottomRight
1.0f,1.0f,0.0f,//3,TopRight
};
//afloatis4bytes,thereforewemultiplythenumberifverticeswith4.
ByteBuffervbb=ByteBuffer.allocateDirect(vertices.length*4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffervertexBuffer=vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
Don'tforgetthatafloatis4bytesandtomultiplyitwiththenumberofverticestogettherightsizeontheallocatedbuffer.
OpenGLEShaveapipelinewithfunctionstoapplywhenyoutellittorender.Mostofthesefunctionsarenotenabledbydefaultsoyouhavetoremembertoturntheonesyouliketouseon.Youmightalsoneedtotellthesefunctionswhattoworkwith.SointhecaseofourverticesweneedtotellOpenGLESthatit’sokaytoworkwiththevertexbufferwecreatedwealsoneedtotellwhereitis.
//Enabledthevertexbufferforwritingandtobeusedduringrendering.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//OpenGLdocs.
//Specifiesthelocationanddataformatofanarrayofvertex
//coordinatestousewhenrendering.
gl.glVertexPointer(3,GL10.GL_FLOAT,0,vertexBuffer);//OpenGLdocs.
Whenyouaredonewiththebufferdon'tforgettodisableit.
//Disabletheverticesbuffer.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);//OpenGLdocs.
Edge
Edgeisalinebetweentwovertices.Theyareborderlinesoffacesandpolygons.Ina3Dmodelanedgecanbesharedbetweentwoadjacentfacesorpolygons.Transforminganedgeaffectsallconnectedvertices,facesandpolygons.InOpenGLESyoudon'tdefinetheedges,youratherdefinethefacebygivingthemtheverticesthatwouldbuildupthethreeedges.Ifyouwouldlikemodifyanedgeyouchangethetwoverticesthatmakestheedge.Youcanseeanedgeintheimagebelowmarkedinyellow.
Face
Faceisatriangle.Faceisasurfacebetweenthreecornerverticesandthreesurroundingedges.Transformingafaceaffectsallconnectedvertices,edgesandpolygons.
Theorderdoesmatter.
Whenwindingupthefacesit'simportanttodoitintherightdirectionbecausethedirectiondefineswhatsidewillbethefrontfaceandwhatsidewillbethebackface.Whythisisimportantisbecausetogainperformancewedon'twanttodrawbothsidessoweturnoffthebackface.Soit'sagoodideatousethesamewindingalloveryourproject.ItispossibletochangewhatdirectionthatdefinesthefrontfacewithglFrontFace.
gl.glFrontFace(GL10.GL_CCW);//OpenGLdocs
TomakeOpenGLskipthefacesthatareturnedintothescreenyoucanusesomethingcalledback-faceculling.Whatisdoesisdetermineswhetherapolygonofagraphicalobjectisvisiblebycheckingifthefaceiswindupinthe