欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

使用OpenGL怎么實現(xiàn)ES透視投影-創(chuàng)新互聯(lián)

使用OpenGL怎么實現(xiàn)ES透視投影?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

成都創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),瓊中黎族企業(yè)網(wǎng)站建設(shè),瓊中黎族品牌網(wǎng)站建設(shè),網(wǎng)站定制,瓊中黎族網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,瓊中黎族網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。

剪裁坐標(biāo)

當(dāng)頂點著色器寫入一個值到gl_Position時,這個點要求必須在剪裁空間中,即它的x、y、z坐標(biāo)必須在[-w,w]之間,任何這個范圍之外的點都是不可見的。

這里需要注意以下,對于attribute類型的屬性量。OpenGL會用默認(rèn)的值替換屬性中未指定的分量,前三個分量會被設(shè)定為0,最后一個分量w會被設(shè)定為1.

站在gl_position的角度來說,[-w,w]之間的坐標(biāo)點才是可見的,否則都是不可見會被剪裁掉。往前看,在做投影變換的時候我們說,在視景體內(nèi)的物體有效,視景體外的會被剪裁,實際上是對應(yīng)的,剪裁就是發(fā)生在圖元裝配階段判斷所有的坐標(biāo)是否在[-w,w]之間。

剪裁實際上就是判斷每一個最小三角形、直線、點單元的坐標(biāo)是否規(guī)范。

透視除法

對上面的剪裁坐標(biāo)的點的x、y、z坐標(biāo)除以它的w分量,除以w的坐標(biāo)叫做歸一化設(shè)備坐標(biāo)。如果w分量大,除以w后的點就接近(0,0,0),在三維空間中,距離我們較遠(yuǎn)的坐標(biāo)如果它的w分量較大,進(jìn)行透視除法后,就距離原點越近,原點作為遠(yuǎn)處物體的消失點,就有三維場景的效果。

視口變換

前面已經(jīng)使用過視口變換的函數(shù)glViewport了,視口是一個而為矩形窗口區(qū)域。是OpenGL渲染操作最終顯示的地方。

public static native void glViewport(
  int x,
  int y,
  int w,
  int h
 );

從歸一化設(shè)備坐標(biāo)(x,y,z)到窗口坐標(biāo)(X,Y,Z)的轉(zhuǎn)換公式

使用OpenGL怎么實現(xiàn)ES透視投影

上面公式中的f和n是如下API設(shè)置的

public static native void glDepthRangef(
  float n,
  float f
 );

n,f指定所需的深度范圍,n,f的取值限于(0.0,1.0)之間,n,f的默認(rèn)值為0.0和1.0

glDepthRangef函數(shù)和glViewport函數(shù)指定的值用于將頂點位置從歸一化設(shè)備坐標(biāo)轉(zhuǎn)換為窗口坐標(biāo)。

利用w分量產(chǎn)生三維效果

在前面的代碼中,修改傳入的頂點坐標(biāo),增加w分量

float[] vertexArray = new float[] {
   (float) -0.5, (float) -0.5, 0, 1,
   (float) 0.5, (float) -0.5, 0, 1,
   (float) -0.5, (float) 0.5, 0, 3,
   (float) 0.5, (float) 0.5, 0, 3
  };

同時修改頂點著色器:

private String vertexShaderCode = "uniform mat4 uMVPMatrix;"
   + "attribute vec4 aPosition;"
   + "void main(){"
   + "gl_Position = uMVPMatrix * aPosition;"
   + "}";

以及獲取uProjectionMatrix以及傳入頂點數(shù)據(jù)對應(yīng)的代碼,就可以看到如下所示效果

使用OpenGL怎么實現(xiàn)ES透視投影

透視投影

然而這樣讓物體產(chǎn)生三維效果的做法太死板了,如果我們還要讓物體平移縮放旋轉(zhuǎn),這樣固定的指定w的值就不太好了。

透視投影這個時候就能派上用場了,利用透視投影矩陣自動生成w的值。投影矩陣主要是為w產(chǎn)生正確的值,這樣在渲染管線的后續(xù)操作中做透視除法,遠(yuǎn)處的物體就看起來比進(jìn)出物體小,很容易想到,可以利用頂點位置的z分量,將這個距離映射到w分量上,z越大,w也越大。

有兩個函數(shù)可以生成透視投影矩陣frustumM和perspectiveM。參數(shù)具體含義可以參考下面的圖

public static void perspectiveM(float[] m, // 生成的投影矩陣
        int offset,
        float fovy, // 視角角度
        float aspect, // 近平面的寬高比
        float zNear, // 近平面
        float zFar) // 遠(yuǎn)平面

frustumM函數(shù)原型

public static void frustumM(float[] m, int offset,
 float left, float right, float bottom, float top, // 近平面左右下上部與中心點的距離
 float near, float far //近平面和元平面與攝像機觀察點的距離 
 )

使用OpenGL怎么實現(xiàn)ES透視投影

透視投影背后的數(shù)學(xué)原理

創(chuàng)建下面的矩陣

使用OpenGL怎么實現(xiàn)ES透視投影

a表示視角焦距,焦距等于1/tan(視野/2)
取aspect=1.8,視野45度即a = 1,f = 10,n = 5,得到的透視投影矩陣為

使用OpenGL怎么實現(xiàn)ES透視投影

計算下面幾個點

使用OpenGL怎么實現(xiàn)ES透視投影

上面這三個點越來越遠(yuǎn),通過透視投影后,z和w都變大了,可以想到,在后面的透視除法時,x和y分量都會變小,于是就會出現(xiàn)距離越遠(yuǎn),匯聚到一個點,也就是三維效果。

同時也可以看到,上面的幾個點他們的z坐標(biāo)都是負(fù)值,這也從側(cè)面表達(dá)了,事實上所有的有效的點z坐標(biāo)必須是負(fù)值,也就是從攝像機的坐標(biāo)來看是在z軸負(fù)方向,也就是必須在視景體里面,這一點通過攝像機矩陣來保證。

前面使用正交投影,它的矩陣不會使得w粉量增加,于是通過透視除法也不會使w分量增加,所以正交投影不會出現(xiàn)近大遠(yuǎn)小的效果,透視投影會出現(xiàn)近大遠(yuǎn)小的效果

透視投影例子

在上面矩形Demo的基礎(chǔ)上修改上面的正方形的頂點數(shù)據(jù)

float vertices[] = new float[] {
  (float) -0.5, (float) -0.5 + + (float)(-0.1*i), (float) (1*i),
  (float) 0.5, (float) -0.5 + + (float)(-0.1*i), (float) (1*i),
  (float) -0.5, (float) 0.5 + + (float)(-0.1*i), (float) (1*i),
  (float) 0.5, (float) 0.5 + + (float)(-0.1*i), (float) (1*i)
};

在繪圖時,定義一個數(shù)組,傳遞不同的i值,比如繪制四個正方形,這四個正方形的距離越來越遠(yuǎn)。

mRectangles = new Rectangle[5];
   for (int i = 0; i < mRectangles.length; i++) {
    mRectangles[i] = new Rectangle(i); 
   }

在onSurfaceChanged函數(shù)里面設(shè)置攝像機位置和透視投影矩陣

Matrix.perspectiveM(mProjectionMatrix, 0, 45, (float)width/height, 2, 15);
   Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 12, 0, 0, 0, 0, 1, 0);

然后在onDrawFram函數(shù)里面繪制這5個矩形

for (Rectangle rectangle : mRectangles) {
  Matrix.setIdentityM(mModuleMatrix, 0);
  Matrix.rotateM(mModuleMatrix, 0, xAngle, 1, 0, 0);
  Matrix.rotateM(mModuleMatrix, 0, yAngle, 0, 1, 0);
  Matrix.multiplyMM(mViewProjectionMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
  Matrix.multiplyMM(mMVPMatrix, 0, mViewProjectionMatrix, 0, mModuleMatrix, 0);
  rectangle.draw(mMVPMatrix);
}

為了呈現(xiàn)出3d效果,增加觸摸旋轉(zhuǎn)事件,這樣滑動屏幕就可以看到三維物體的全貌

public boolean onTouchEvent(MotionEvent e) {
  float y = e.getY();
  float x = e.getX();
  switch (e.getAction()) {
  case MotionEvent.ACTION_MOVE:
   float dy = y - mPreviousY;
   float dx = x - mPreviousX;
   mMyRender.yAngle += dx;
   mMyRender.xAngle+= dy;
   requestRender();
  }
  mPreviousY = y;
  mPreviousX = x;
  return true;
 }

然后就可以看到三維效果。

使用OpenGL怎么實現(xiàn)ES透視投影

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。

本文標(biāo)題:使用OpenGL怎么實現(xiàn)ES透視投影-創(chuàng)新互聯(lián)
網(wǎng)站網(wǎng)址:http://chinadenli.net/article46/dcphhg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站做網(wǎng)站、網(wǎng)站收錄動態(tài)網(wǎng)站、電子商務(wù)網(wǎng)頁設(shè)計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
久热这里只有精品九九| 99久久精品国产麻豆| 国产精品激情对白一区二区| 午夜福利视频偷拍91| 亚洲高清中文字幕一区二区三区| 亚洲中文字幕免费人妻| 亚洲天堂国产精品久久精品| 91精品国产av一区二区| 精品国产一区二区欧美| 国产精品久久女同磨豆腐| 国产精品人妻熟女毛片av久久| 又大又长又粗又猛国产精品| 久草国产精品一区二区| 欧美日韩一级aa大片| 99久久精品国产日本| 欧美一级黄片免费视频| 午夜福利在线观看免费| 国产精品久久久久久久久久久痴汉| 欧美av人人妻av人人爽蜜桃| 视频一区二区三区自拍偷| 久久人妻人人澡人人妻| 亚洲一区二区精品国产av| 欧美日韩三区在线观看| 爽到高潮嗷嗷叫之在现观看| 免费性欧美重口味黄色| 欧美多人疯狂性战派对| 一区二区三区日韩在线| 亚洲中文字幕有码在线观看| 亚洲国产天堂av成人在线播放| 中文字幕人妻一区二区免费| 在线免费视频你懂的观看| 99秋霞在线观看视频| 国产成人高清精品尤物| 最近日韩在线免费黄片| 日韩欧美在线看一卡一卡| 东京热男人的天堂久久综合| 国产精品亚洲综合色区韩国| 日韩欧美国产三级在线观看| 人妻一区二区三区多毛女| 久久精品亚洲情色欧美| 欧美精品一区二区水蜜桃|