日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

php open gl,Open GL 资料 01

發(fā)布時間:2025/3/15 php 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 php open gl,Open GL 资料 01 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

publicclassMyGLSurfaceViewextendsGLSurfaceView?{

privatefinalfloatTOUCH_SCALE_FACTOR?=180.0f?/320;

/**

*?具體實現(xiàn)的渲染器

*/

privateOPhoneOglesDevRenderer?mRenderer;

/**

*?記錄上次觸屏位置的坐標

*/

privatefloatmPreviousX,?mPreviousY;

publicMyGLSurfaceView(Context?context)?{

super(context);

//?設置渲染器

mRenderer?=newOPhoneOglesDevRenderer(context);

setRenderer(mRenderer);

//?設置渲染模式為主動渲染

setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);

}

publicvoidonPause()?{

super.onPause();

}

publicvoidonResume()?{

super.onResume();

}

/**

*?響應觸屏事件

*/

@Override

publicbooleanonTouchEvent(MotionEvent?e)?{

floatx?=?e.getX();

floaty?=?e.getY();

switch(e.getAction())?{

caseMotionEvent.ACTION_MOVE:

floatdx?=?x?-?mPreviousX;

floatdy?=?y?-?mPreviousY;

mRenderer.mAngleX?+=?dx?*?TOUCH_SCALE_FACTOR;

mRenderer.mAngleY?+=?dy?*?TOUCH_SCALE_FACTOR;

requestRender();

}

mPreviousX?=?x;

mPreviousY?=?y;

returntrue;

}

}

OpenGL ES開發(fā)簡要框架

開發(fā)OpenGL ES程序,首要做的就是設置視口,設置投影矩陣,設置模型視圖矩陣等。對于設置模型視圖矩陣,我們通常會分別設置相機矩陣和模型矩陣。對于一些全局性的設置,我們通常只需要執(zhí)行一次;而對于那些需要動態(tài)改變的屬性,則應該在相應事件發(fā)生時或者逐幀進行動態(tài)更新。GLSurfaceView.Renderer接口提供了監(jiān)視繪圖表面創(chuàng)建、改變以及逐幀更新的方法,分別是:

/**

*?創(chuàng)建繪圖表面時調(diào)用

*/

@Override

publicvoidonSurfaceCreated(GL10?gl,?EGLConfig?config)

/**

*?當繪圖表面尺寸發(fā)生改變時調(diào)用

*/

@Override

publicvoidonSurfaceChanged(GL10?gl,intwidth,intheight)

/**

*?逐幀渲染

*/

@Override

publicvoidonDrawFrame(GL10?gl)

/** * 創(chuàng)建繪圖表面時調(diào)用 */ @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) /** * 當繪圖表面尺寸發(fā)生改變時調(diào)用 */ @Override public void onSurfaceChanged(GL10 gl, int width, int height) /** * 逐幀渲染 */ @Override public void onDrawFrame(GL10 gl)

通常,我們在onSurfaceCreated()中通過調(diào)用glHint()函數(shù)來設置渲染質(zhì)量與速度的平衡,設置清屏顏色,著色模型,啟用背面剪裁和深度測試,以及禁用光照和混合等全局性設置。相關代碼如下:

publicvoidonSurfaceCreated(GL10?gl,?EGLConfig?config)?{

//全局性設置

gl.glDisable(GL10.GL_DITHER);

gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,?GL10.GL_FASTEST);

//設置清屏背景顏色

gl.glClearColor(0.5f,0.5f,0.5f,1);

//設置著色模型為平滑著色

gl.glShadeModel(GL10.GL_SMOOTH);

//啟用背面剪裁

gl.glEnable(GL10.GL_CULL_FACE);

gl.glCullFace(GL10.GL_BACK);

//啟用深度測試

gl.glEnable(GL10.GL_DEPTH_TEST);

//禁用光照和混合

gl.glDisable(GL10.GL_LIGHTING);

gl.glDisable(GL10.GL_BLEND);

}

在onSurfaceChanged中,我們會根據(jù)繪圖表面尺寸的改變,來即時改變視口大小,以及重新設置投影矩陣。相關代碼如下:

publicvoidonSurfaceChanged(GL10?gl,intwidth,intheight)?{

//設置視口

gl.glViewport(0,0,?width,?height);

//設置投影矩陣

floatratio?=?(float)?width?/?height;//屏幕寬高比

gl.glMatrixMode(GL10.GL_PROJECTION);

gl.glLoadIdentity();

GLU.gluPerspective(gl,45.0f,?ratio,1,5000);

//每次修改完GL_PROJECTION后,最好將當前矩陣模型設置回GL_MODELVIEW

gl.glMatrixMode(GL10.GL_MODELVIEW);

}

}

在onDrawFrame中,需要編寫的是每幀實際渲染的代碼,包括清屏,設置模型視圖矩陣,渲染模型,以及相應的update函數(shù)。相關代碼如下:

publicvoidonDrawFrame(GL10?gl)?{

//一般的opengl程序,首先要做的就是清屏

gl.glClear(GL10.GL_COLOR_BUFFER_BIT?|?GL10.GL_DEPTH_BUFFER_BIT);

//緊接著設置模型視圖矩陣

setUpCamera(gl);

//渲染物體

drawModel(gl);

//更新時間

updateTime();

}

設置模型視圖矩陣(即GL_MODELVIEW矩陣)時,我們通常分別設置相機和物體矩陣。在設置相機矩陣時,我們可以通過調(diào)用

GLU.gluLookAt (GL10 gl, float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ) 傳入視點位置(eyeX, eyeY, eyeZ)、被觀察體的中心位置(centerX, centerY, centerZ)以及相機向上方向的向量(upX, upY, upZ)。相關代碼如下:

/**

*?設置相機矩陣

*?@param?gl

*/

privatevoidsetUpCamera(GL10?gl)?{

gl.glMatrixMode(GL10.GL_MODELVIEW);

gl.glLoadIdentity();

GLU.gluLookAt(gl,?mfEyeX,?mfEyeY,?mfEyeZ,?mfCenterX,?mfCenterY,?mfCenterZ,0,1,0);

}

OpenGL ES中采用的是矩陣堆棧體系。對于模型視圖矩陣,堆棧深度至少為16;對于投影矩陣或者紋理矩陣,則至少為2。由于OpenGL ES中的矩陣操作,都是針對當前棧頂?shù)木仃?#xff0c;因此很多時候需要配對使用glPushMatrix()和glPopMatrix()來進行保存和恢復矩陣現(xiàn)場。在本例中,渲染模型之前,我們首先使用glPushMatrix()來復制當前模型視圖矩陣,并將其推入到棧頂,之后所有的矩陣操作均針對該矩陣。然后我們通過調(diào)用glRotate()函數(shù),進行適當?shù)男D(zhuǎn),在渲染模型完畢之后,通過調(diào)用glPopMatrix()將當前矩陣彈出,恢復之前的矩陣現(xiàn)場。相關代碼如下:

/**

*?渲染模型

*?@param?gl

*/

privatevoiddrawModel(GL10?gl)?{

gl.glPushMatrix();

{

//首先對模型進行旋轉(zhuǎn)

gl.glRotatef(mfAngleX,1,0,0);//繞X軸旋轉(zhuǎn)

gl.glRotatef(mfAngleY,0,1,0);//繞Y軸旋轉(zhuǎn)

if(mModel.containsAnimation())?{

//如果模型有動畫,那么按時間就更新動畫

if(mMsPerFrame?>0)?{

mModel.animate(mMsPerFrame?*0.001f);//將毫秒數(shù)轉(zhuǎn)化為秒,?/1000

}

mModel.fillRenderBuffer();//更新頂點緩存

}

mModel.render(gl);//渲染模型

mModel.renderJoints(gl);//渲染關節(jié),骨骼

}

gl.glPopMatrix();

}

OpenGL ES中支持三種渲染圖元:點(GL_POINTS)、線(GL_LINES)和三角形(GL_TRIANGLES)。在本例子中,模型實體采用三角形渲染(對應函數(shù)mModel.render(gl)),而對于有骨骼信息的模型,會使用點和線來渲染骨骼輔助信息(對應函數(shù)mModel.renderJoints(gl))。OpenGL ES拋棄了OpenGL中傳統(tǒng)但低效的glBegin()、glEnd()的渲染方式,采用了更為高效的批量渲染模式,使用java.nio.Buffer對象來存儲渲染數(shù)據(jù),之后通過調(diào)用glVertexPointer()、glNormalPointer()、glColorPointer()以及glTextureCoordPointer()傳入Buffer對象來分別設置頂點位置、法線、顏色和紋理坐標渲染數(shù)據(jù)。在設置渲染數(shù)據(jù)的同時,需要通過調(diào)用glEnableClientState()函數(shù),分別傳入GL_VERTEX_ARRAY、GL_NORMAL_ARRAY、GL_COLOR_ARRAY和GL_TEXTURE_COORD_ARRAY來通知底層引擎啟用相應渲染屬性數(shù)據(jù)。這四個渲染屬性并非要全部設置,而是可以根據(jù)需要只是啟用其中的某幾個。在本例中,渲染模型實體時,僅啟用了頂點位置數(shù)據(jù)和紋理坐標數(shù)據(jù);在渲染點線的骨骼輔助信息時,則僅僅啟用了頂點位置數(shù)據(jù)。對于那些沒有被啟用的渲染屬性,必須要確保其當前處于為非活動狀態(tài)(即調(diào)用glDisableClientState()),否則就可能會對渲染結(jié)果造成一定影響,或者白白加重底層管線運算負擔。

另外需要注意的是OPhone中要傳入gl*Pointer()函數(shù)的Buffer對象必須要為direct模式申請的,這樣可以確保緩存對象放置在Native的堆中,以免受到Java端的垃圾回收機制的影響。對于FloatBuffer、ShortBuffer和IntBuffer等多字節(jié)的緩存對象,它們的字節(jié)順序必須設置為nativeOrder,否則會極大降低程序執(zhí)行效率。

在設置好各個渲染屬性的數(shù)據(jù)之后,就要通過調(diào)用glDrawArrays()或者glDrawElements()來進行數(shù)據(jù)的最終提交渲染。前者表示傳入的數(shù)據(jù)是最終要渲染的數(shù)據(jù),可以直接渲染,而后者會根據(jù)傳入的索引,由底層重組最終要真正渲染的數(shù)據(jù)。相比之下,后者可以節(jié)省更多的內(nèi)存。下面的代碼展示了以三角形來渲染模型實體,啟用頂點位置數(shù)據(jù)和紋理坐標數(shù)據(jù),未啟用法線和顏色數(shù)據(jù):

/**

*?渲染實體模型

*?@param?gl

*/

publicvoidrender(GL10?gl)?{

gl.glPushMatrix();

{

//設置默認顏色

gl.glColor4f(1.0f,0.5f,0.5f,1.0f);

//啟用客戶端狀態(tài)

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

//遍歷所有的MS3D?Group,渲染每一個Group

for(inti?=0;?i

if(mpGroups[i].getTriangleCount()?==0)?{

//如果該Group包含的三角形個數(shù)為零,則直接跳過

continue;

}

//得到相應紋理

TextureInfo?tex?=?mpTexInfo[i?%?mpTexInfo.length];

if(tex?!=null)?{

//如果紋理不為空,則綁定相應紋理

gl.glBindTexture(GL10.GL_TEXTURE_2D,?tex.mTexID);

//啟用紋理貼圖

gl.glEnable(GL10.GL_TEXTURE_2D);

//綁定紋理坐標數(shù)據(jù)

gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

gl.glTexCoordPointer(2,?GL10.GL_FLOAT,0,

mpBufTextureCoords[i]);

}else{

//如果紋理為空,禁用紋理貼圖

//禁用紋理客戶端狀態(tài)

gl.glDisable(GL10.GL_TEXTURE_2D);

gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

}

//綁定頂點數(shù)據(jù)

gl.glVertexPointer(3,?GL10.GL_FLOAT,0,?mpBufVertices[i]);

//提交渲染

gl.glDrawArrays(GL10.GL_TRIANGLES,0,?mpGroups[i]

.getTriangleCount()?*3);

}

//渲染完畢,重置客戶端狀態(tài)

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

gl.glDisable(GL10.GL_TEXTURE_2D);

}

gl.glPopMatrix();

}

程序中渲染骨骼關節(jié)輔助信息的部分,就是以點和線的模型進行渲染,相關代碼如下

/**

*?渲染骨骼幫助信息

*?@param?gl

*/

publicvoidrenderJoints(GL10?gl)?{

if(!containsJoint())?{

return;

}

//為保證骨骼始終可見,暫時禁用深度測試

gl.glDisable(GL10.GL_DEPTH_TEST);

//設置點和線的寬度

gl.glPointSize(4.0f);

gl.glLineWidth(2.0f);

//僅僅啟用頂點數(shù)據(jù)

gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

//渲染骨骼連線

gl.glColor4f(1.0f,0.0f,0.0f,1.0f);//設置顏色

gl.glVertexPointer(3,?GL10.GL_FLOAT,0,?mBufJointLinePosition);

//提交渲染

gl.glDrawArrays(GL10.GL_LINES,0,?mJointLineCount);

//渲染關節(jié)點

gl.glColor4f(1.0f,1.0f,0.0f,1.0f);//設置顏色

gl.glVertexPointer(3,?GL10.GL_FLOAT,0,?mBufJointPointPosition);

//提交渲染

gl.glDrawArrays(GL10.GL_POINTS,0,?mJointPointCount);

//重置回默認狀態(tài)

gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

gl.glPointSize(1.0f);

gl.glLineWidth(1.0f);

gl.glEnable(GL10.GL_DEPTH_TEST);

}

紋理操作??????? 在前面的代碼中,我們看到了啟用、綁定紋理等操作。紋理映射是3D中非常重要的一塊,如果沒有紋理,整個3D世界就會只是一些單純的色塊。OPhone中目前支持2D紋理映射(貼圖尺寸必須要為2的N次方),并支持2個以上的紋理貼圖單元。由于紋理數(shù)據(jù)存儲在OpenGL ES服務器端(可以理解為GPU端,即Graphics Process Unit,圖形處理單元),因此需要我們從客戶端(即外部的應用程序端)將像素數(shù)據(jù)傳入,由底層將這些像素轉(zhuǎn)換成更為高效的、對硬件更為友好的紋素格式。OpenGL ES中的每一個紋理都被當作一個紋理對象,它除了包括紋理像素數(shù)據(jù)之外,還包括該紋理的其他屬性,比如名字、過濾模式、混合模式等。開發(fā)者需要首先向底層申請一個紋理名稱,之后上傳紋理像素數(shù)據(jù),以及設置其他屬性。下面的代碼向我們展示了如何在OPhone中創(chuàng)建一個紋理對象:

/**

*?創(chuàng)建一個紋理對象

*?@param?context?-?應用程序環(huán)境

*?@param?gl?-?opengl?es對象

*?@param?resID?-?R.java中的資源ID

*?@param?wrap_s_mode?-?紋理環(huán)繞S模式

*?@param?wrap_t_mode?-?紋理環(huán)繞T模式

*?@return?申請好的紋理ID

*/

publicstaticintgetTexture(Context?context,?GL10?gl,intresID,

intwrap_s_mode,intwrap_t_mode)?{

//申請一個紋理對象ID

int[]?textures?=newint[1];

gl.glGenTextures(1,?textures,0);

//綁定這個申請來的ID為當前紋理操作對象

inttextureID?=?textures[0];

gl.glBindTexture(GL10.GL_TEXTURE_2D,?textureID);

//設置當前紋理對象的過濾模式

gl.glTexParameterf(GL10.GL_TEXTURE_2D,?GL10.GL_TEXTURE_MIN_FILTER,

GL10.GL_NEAREST);

gl.glTexParameterf(GL10.GL_TEXTURE_2D,?GL10.GL_TEXTURE_MAG_FILTER,

GL10.GL_LINEAR);

//設置環(huán)繞模式

gl.glTexParameterf(GL10.GL_TEXTURE_2D,?GL10.GL_TEXTURE_WRAP_S,

wrap_s_mode);

gl.glTexParameterf(GL10.GL_TEXTURE_2D,?GL10.GL_TEXTURE_WRAP_T,

wrap_t_mode);

//設置混合模式

gl.glTexEnvf(GL10.GL_TEXTURE_ENV,?GL10.GL_TEXTURE_ENV_MODE,

GL10.GL_REPLACE);

//開始載入紋理

InputStream?is?=?context.getResources().openRawResource(resID);

Bitmap?bitmap;

try{

bitmap?=?BitmapFactory.decodeStream(is);

}finally{

try{

is.close();

}catch(IOException?e)?{

//?Ignore.

}

}

//綁定像素數(shù)據(jù)到紋理對象

GLUtils.texImage2D(GL10.GL_TEXTURE_2D,0,?bitmap,0);

bitmap.recycle();

returntextureID;

}

創(chuàng)建好紋理對象之后,在使用時,需要首先通過調(diào)用gl.glEnable(GL10.GL_TEXTURE_2D)來通知底層開啟紋理貼圖操作,之后綁定相應的紋理ID到當前紋理貼圖單元,同時通過調(diào)用glTexCoordPointer()來設置好相應的紋理坐標信息,最終提交渲染時,底層就會自動進行紋理映射操作。當紋理不再被使用時,可以通過調(diào)用glDeleteTextures()來將其刪除。

輸入事件響應

我們可以重載GLSurfaceView的onTouchEvent()方法,從而監(jiān)測用戶對屏幕的觸摸事件。本例中,我們根據(jù)觸摸位置的改變,來對模型進行繞Y軸和X軸的旋轉(zhuǎn)。如果有需要,開發(fā)者還可以重載鍵盤按鍵onKeyDown()方法。值得注意的是,由于這些事件和渲染線程是分別獨立的線程,因此有些操作如果需要確保在渲染線程內(nèi)部執(zhí)行的話,可以調(diào)用queueEvent (Runnable)來將該操作附加到渲染線程操作隊列中。相關代碼如下:

/**

*?響應觸屏事件

*/

@Override

publicbooleanonTouchEvent(MotionEvent?e)?{

floatx?=?e.getX();

floaty?=?e.getY();

switch(e.getAction())?{

caseMotionEvent.ACTION_MOVE:

floatdx?=?x?-?mPreviousX;

floatdy?=?y?-?mPreviousY;

mRenderer.mfAngleY?+=?dx?*?TOUCH_SCALE_FACTOR;

mRenderer.mfAngleX?+=?dy?*?TOUCH_SCALE_FACTOR;

requestRender();

}

mPreviousX?=?x;

mPreviousY?=?y;

returntrue;

}

總結(jié)

以上是生活随笔為你收集整理的php open gl,Open GL 资料 01的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。