轉載請註明出處:https://www.jianshu.com/p/8049014b7952android
圖形頂點和紋理的座標展現:數組
頂點的座標數據如上面截圖所示,這兩組數據該這樣理解,首先肯定4個圖形頂點的座標(第一組數據),這是一個正方形,其座標系爲openGL座標系,以中心點爲原點,見下左圖;第二組數據右邊的一個座標系是紋理座標系,已左上角爲原點(android中應該作了轉換,本來的opengl中是以左下角爲原點的)。函數
紋理就是貼圖,就是將紋理矩形中按照圖中標記的順序(也就是紋理座標數組的順序),挨個紋理頂點都對應到圖形頂點繪製的矩形中,這樣就完成了把紋理徹底貼到了opengl繪製的圖形中。3d
由於手機設備的寬高通常是不相等的(或者說顯示區域不相等),因此幾乎沒有顯示區域是一個規則的矩形,這樣就須要進行矩陣變換,在不產生拉伸的狀況下將圖片繪製到屏幕中。這個矩陣就須要下面的邏輯來獲取出來。cdn
僅討論豎屏情景(w<h),在Camera preview時,會計算一個映射矩陣,如上面的函數,imgWidth和imgHeight表明Camera中preview到的圖片的大小,如720x1280(通常Camera中傳上來的圖片都是w>h的,如1280x720,這裏爲了與屏幕的方向保持一致,因此將w和h換了下位置);viewWidth和viewHeight表明的是手機中顯示區域的大小。blog
將這兩個矩形的高歸一,兩個矩形的大小就變爲了:(sWhImg,1)和(sWhView,1),這裏的歸一表示將兩個矩形等比縮小,將縱座標變爲1。圖片
第一種狀況,當sWhImg > sWhView時it
這種狀況表示圖片較大,顯示區域較小,圖片若是要所有顯示到屏幕上,須要在x軸上作收縮動做,示意圖以下,左側中綠色表明屏幕顯示區域,紫色表明圖片,右側的藍色正方形爲紋理大小。io
Matrix.orthoM函數表示正交投影,表示的是一個物體的左右上下先後在屏幕上展示的部分,由於這裏是二維的,全部就光考慮左右上下(x軸和y軸),y軸方向,徹底展現。X軸方向須要展現的部分是這樣計算的:在上文中,咱們已經得知紋理的寬高均爲1,圖片要拉伸並貼到整個紋理中,在高均爲1的狀況下,寬要從sWhImg 變爲1,當圖片的寬爲sWhImg時,屏幕須要顯示的部分爲sWhView,那當圖片的寬被拉伸到1的狀況下,屏幕須要顯示的部分也要進行等比拉伸(scale),寬度爲x,x的值是多少呢?class
因此最終咱們的正交矩陣,左右之間的範圍爲(-sWhView/sWhImg,sWhView/sWhImg),上下的範圍爲(-1,1)
第二種狀況,當sWhView > sWhImg時
這種狀況下,說明若是將高(h)歸一化了以後,圖片的大小不足以在顯示區域內展現,若是要展現的話,必然會發生圖片的拉伸。這種狀況下,須要將寬(w)歸一,當w爲1時,h則分別變爲了1/sWhView和1/sWhImg,由於sWhView比較大,那麼1/sWhView必然比較小,這樣圖片在x軸上跟顯示區域同樣大,在Y軸上比顯示區域要大,這樣就跟第一種狀況下相似,在Y軸方向上,截取圖片的一部分顯示在屏幕中,這樣就不會產生拉伸。以下圖所示。
圖片的寬爲1,對應到紋理中,寬不變,高從1/sWhImg變爲了1,被拉伸了(拉伸和壓縮統一被稱爲拉伸,單詞爲stretch)。屏幕須要顯示的紋理一樣發生了拉伸,變爲了y,y的計算方式與上面相同
正交矩陣中,左右的可見範圍爲(-1,1),上下的可見範圍爲(-sWhImg/sWhView, sWhImg/sWhView)。