當前位置:首頁 » 文件管理 » opengl深度緩存

opengl深度緩存

發布時間: 2022-11-05 11:06:47

1. opengl中glreadpixels讀取深度緩存的值為啥都是零呀謝謝

WebGL1.0的文檔中對於readPixels方法有明確的說明:The data returned from readPixels must be up-to-date as of the most recently sent drawing command.
也就是說該方法必須在渲染完一幀的頁面之後立即調用才有效果,否則取不到值,比如這樣調用:
gl.viewport(0,0,World.canvas.width,World.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);
scene.draw(camera);
var a = new Uint8Array(4);
gl.readPixels(0,0,1,1,gl.RGBA,gl.UNSIGNED_BYTE,a);
console.log(a);
此處一幀的繪制(scene.draw(camera))完全完成之後再讀取就可以獲取准確值了,你自己可以試一下。

2. OpenGL入門-4

圖像存儲空間 = 圖像的高度 * 圖像寬度 * 每個像素的位元組數

RGB(8位),寬度:199像素點。圖片每行需要多少存儲空間?
199 * 3 * 8 = 597位元組

tga(紋理文件)。1個位元組1個位元組。
OpenGL紋理文件:.tga文件.

OpenGL ES! 壓縮圖片文件.png/jpeg壓縮
當紋理來使用。

//改變像素存儲方式
void glPixelStorei(GLenum pname, GLint param);
//恢復像素存儲方式
void glPixelStoref(GLenum pname,GLfloat param);
//舉例:
//參數1:GL_UNPACK_ALTGNMENT 指定OpenGL 如何從數據緩存區中解包圖像數據
//參數2:表示參數GL_UNPACK_ALIGNMENT 設置的值

//GL_UNPACK_ALIGNMENT 指內存中每個像素行起點的排列請求,允許設置為1(byte排列)、2(排列為偶數btye的行)、4(字word排列)、8(行從雙位元組邊界開始)
glPixelStorei(GL_UNPACK_ALIGNMENT,1);

參數1:x,矩形左下角的窗口坐標
參數2:y,矩形左下角的窗口坐標
參數3:width,矩形的寬,以像素為單位
參數4:height,矩形的高,以像素為單位
參數5:format,OpenGL的像素格式
參數6:type,解釋參數pixels指向的數據,告訴OpenGL 使用緩存區中的什麼數據類型來存儲顏色分量,像素數據的數據類型。
參數7:pixels,指向圖形數據的指針
void glReadPixls(GLint x, GLint y, GLSizei width, GLSizei height, GLenum format, GLenum type, const void *pixels);

glReadBuffer(mode); ->指定讀取的緩存
glWriteBuffer(mode); -> 指定寫入的緩存

void glTexImage1D(GLenum target,GLint level, GLint internalformat,GLsizei width, GLint border, GLenum format, GLenum type, void *data);

void glTextImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint bordr, GLenum format, GLenum type,void *data);

void glTextImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,GLsizei depth, GLint bordr, GLenum format, GLenum type,void *data);

void glTexSubImage1D(GLenum target, GLint level, GLint xOffset, GLsizei width, GLenum format, GLenum type, const GLvoid *data);

void glTexSubImage2D(GLenum target, GLint level, GLint xOffset,GLint yOffset,GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *data);

void glTexSubImage3D(GLenum target, GLint level, GLint xOffset,GLint yOffset,GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *data);

void glCopyTexSubImage1D(GLenum target, GLint level, GLint xOffset, GLint x, GLint y, GLsizei width);

void glCopyTexSubImage2D(GLenum target,GLint level,GLint xOffset, GLint yOffset,GLint x, GLint y,GLsizei width, GLsizei height);

void glCopyTexSubImage3D(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint zOffset, GLint x, GLint y, GLsizei width, GLsizei height);

void glCopyTexImage1D(GLenum target, GLint level, GLenum internalformt, GLint x, GLint y, GLsizei width, GLint border);

void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformt, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);

x,y在顏色緩存區中指定了開始讀取紋理數據的位置;緩存區里的數據,是源緩存區通過glReadBuffer設置的。

//使用函數分配紋理對象
//指定紋理對象的數量 和 指針(指針指向一個屋符號整形數組,由紋理對象標識符填充)。
void glGenTextures(GLsizei n, GLint *texTures);

//綁定紋理狀態
//參數target: GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D
//參數texture:需要綁定的紋理對象
void glBindTexture(GLenum target, GLunit texture);

//刪除綁定紋理對象
//紋理對象 以及 紋理對象指針(指針指向一個無符號整形數組,由紋理對象標識符填充)。
void glDeleteTexture(GLsizei n, GLint *textures);

//測試紋理對象是否有效
//如果texture是一個已經分配空間的紋理對象。那麼這個函數會返回GL_TRUE,否則返回GL_FALSE.
GLboolean glIsTexture(GLuint texture);

glTexParameterf(GLenum target, GLenum pname, GLFloat param);
glTexParameteri(GLenum target, GLenum pname, GLint param);
glTexParameterfv(GLenum target, GLenum pname,GLint param);
glTexParameteriv(GLenum target, GLenum pname, GLint *param);

參數1:target,指定這些參數將要應用在那個紋理模式上,比如GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D。
參數2:pname,指定需要設置那個紋理參數。
參數3:param,設定特定的紋理參數值。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
//紋理縮小時,使用鄰近過濾

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GLLINEAR)
//紋理放大時,使用線性過濾

參數1:GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D
參數2:GL_TEXTURE_WRAP_S、GL_TEXTURE_T、GL_TEXTURE_R,針對s,t,r坐標
參數3:GL_REPEAT、GL_CLAMP、GL_CLAMP_TO_EDGE、GL_CLAMP_TO_BORDER
GL_REPEAT:OpenGL在紋理坐標超過1.0的方向上對紋理進行重復;
GL_CLAMP:所需要的紋理單元取自紋理邊界或TEXTURE_BORDER_COLOR.
GL_CLAMP_TO_EDGE環繞模式強制對范圍之外的紋理坐標沿著合法的紋理單元的最後一行或者最後一列來進行采樣。
GL_CLAMP_TO_BORDER:在紋理坐標在0.0到1.0范圍之外的只使用邊界紋理單元。邊界紋理單元是作為圍繞基本圖像的額外的行和列,並與基本紋理圖像一起載入的。

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAR_S,GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAR_T,GL_CLAMP_TO_EDGE);

OpenGL像素格式

像素數據的數據類型

//設置mip貼圖基層
glTexParamteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0);
//設置mip貼圖最大層
glTexParamteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_LEVEL,0);

GLint comFlag;
//判斷紋理是否被成功壓縮
glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_COMPRESSED,&comFlag);

//根據選擇的壓縮紋理格式,選擇最快、最優、自行選擇的演算法方式選擇壓縮格式
glHint(GL_TEXTURE_COMPRESSION_HINT,GL_FASTEST);
glHint(GL_TEXTURE_COMPRESSION_HINT,GL_NICEST);
glHint(GL_TEXTURE_COMPRESSION_HINT,GL_DONT_CARE);

void glCompressedTexImage1D(GLenum target,GLint level,Glenum internalFormat,GLsizei width,GLint border, GLsizei imageSize, void *data);

void glCompressedTexImage2D(GLenum target,GLint level, GLenum internalFormat, GLsizei width, GLint height, GLint border, GLsizei imageSize, void *data);

void glCompressedTextImage3D(GLenum target, Glint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth,GLint border, GLsizei imageSize,void *data);

target: GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D.
level:指定所載入的mip貼圖層次。一般我們都把這個參數設置為0.
internalformat:每個紋理單元中存儲多少顏色成分
width、height、depth參數:指載入紋理底層的寬度、高度、深度。注意:這些值必須是2的整數次方。(這是因為舊版本上遺留下的一個要求。當然現在已經可以支持不是2的整數次方。但是開發者還是習慣使用2的整數次方去設置參數)
border參數:允許為紋理貼圖指定一個邊界寬度。
format、type、data參數:與我們在講glDrawPixels函數對應的參數相同

3. 為openGL的選擇緩沖區分配內存時要考慮什麼因素

你說的緩沖區是指哪個? 是framebuffer嗎? 這個大小是固定的, 和你的解析度有關。 如果是頂點緩存, 那麼都是按量來分的, 一個模型一個緩存, 這樣不可能出現額外開銷吧。 opengl有深度緩存, 重疊模型的信息在這個緩存內,這個也是大小預設的。 一般來說opengl很少有大規模連續緩存(除了framebuffer, 這個同時存在於顯卡或內存(可選)中),其他的緩沖區不用動態改變大小。 而且cpu和gpu是協同關系, 若cpu實時追蹤gpu信息,會浪費大量計算去輪詢, 從理論和效率上來講是不推薦的。 一般所有緩沖區的大小都不應該改變, 這樣會導致同步問題, 比如你的剛讀出去一些數據, 按照你的思路, 可能緩沖的大小就要減半, 可是萬一這個數據之後還有程序要讀的數據,這樣就發生segerror了, 特別是顯卡的工作方式對顯存的分配有著嚴格要求, 不能隨便改變大小的。 最後可能是我理解有問題, 歡迎隨時交流

4. openGL裡面那個深度緩存是什麼東西啊.. 還有那個深度測試又是什麼呢

深度緩存中存儲著每個象素點(繪制在屏幕上的)的深度值! 深度測試決定了是否繪制較遠的象素點(或較近的象素點),通常選用較近的, 而較遠優先能實現透視的效果! 補充: 如同在真實的世界中,我們只能看見距離自己較近的東西,而較遠的東西會被較近的東西掩蓋,使我們無法看見! 追問: 如果我不啟用深度測試 被覆蓋的東西能被顯示出來么~?~? 回答: 不能,因為OpenGl本身為你開啟了較近優先的深度檢測,除非你自己開啟較遠優先的深度檢測,

5. openGL裡面那個深度緩存是什麼東西啊.. 還有那個深度測試又是什麼呢

就是里邊存的是深度的信息,用來決定哪個東西畫在前面,哪個東西畫在後面,具體的可以看《OPENGL編程指南》,就是紅寶書。

6. OpenGL -- 對深度測試的理解

例如上圖中兩個圖形混合 混合部分會進行重新渲染

深度緩沖區和顏⾊緩存區是對應的。顏⾊緩存區存儲像素的顏⾊信息,而深度緩沖區存儲像素的深度信息。

在決定是否繪制⼀個物體表⾯時,首先要將表面對應的像素的深度值與當前深度緩沖區中的值進⾏⽐較。如果大於深度緩沖區中的值,則丟棄這部分;否則利⽤這個像素對應的深度值和顏⾊值,分別更新深度緩沖區和顏色緩存區。這個過程稱為深度測試。

fa和near是提供到投影矩陣設置可見視圖截錐的遠近值。

非線性深度緩存
在實踐中可以減少使用這樣的線性深度緩沖區。正確的投影特性的非線性深度方程是和1/z成正比,由於非線性方程和1/z成正比,例如1.0和2.0之間的z值,將變為1.0到0.5之間,將z非常小的時候給了我們很高的精度。方程式如下圖

在深度緩沖區的值不是線性的屏幕空間(它們在視圖空間投影應用之間是線性)。值為0.5的深度緩沖區並不意味著該對象的z值投影上邊的平頭解體的中間;頂點的z值是實際上徐娘當接近平面!可以看到z值和產生深度緩沖區的值在下列圖標中的線性關系

屏幕空間的深度值是非線性如他們在z很小的時候有很高的精度,較大的z值有較低的精度。該片段的深度值會迅速增加,幾乎所有頂點的深度值接近1.0。如果我們⼩小⼼心的靠近物體,你最終可能會看到的色彩越來越暗,意味著它們的值越來越小,這清楚地表明深度值的非線性特性。近的物體相對遠的物體對的深度值比對象較大的影響。只移動幾英寸就能讓暗色完全變亮。但是我們可以讓深度值變換回線性。要實現這一⽬標我們需要讓點應⽤用投影變換逆的逆變換,成為單獨的深度值的過程。這意味著我 們必須⾸首先􏰁新變換范圍 [0,1] 中的深度值為單位化的設備坐標(normalized device coordinates)范圍內 [-1,1] (裁剪空間(clip space))。然後,我們想要反轉⾮非線性⽅方程 。

開啟深度測試

在繪制場景前,清除顏⾊緩存區,深度緩沖。清除深度緩沖區默認值為1.0。

指定深度測試判斷模式

深度緩沖區寫入開關

7. OpenGL 渲染技巧:正背面剔除、深度測試、多邊形偏移、 混合

在繪制3D場景時,我們需要決定哪些部分是對觀察者可⻅的,或者哪些部分是不可見的。對於不可⻅的部分,應該及早丟棄,這種做法叫做 隱藏⾯消除

先繪制紅色部分,再繪制⻩色部分,最後再繪制灰⾊部分,即可解決隱藏面消除的問題。即將場景按照物理距離和觀察者的距離遠近排序,由遠及近的繪制即可。

弊端: 如果三個三⻆形是相互重疊的,油畫演算法將⽆法處理。

從任何⼀個⽅向去觀察一個立方體,最多可以看到3個⾯。如果我們能以某種⽅式去丟棄這部分數據。OpenGL在渲染的性能即可提高超過50%。

任何平⾯都有2個⾯:正⾯和背面,⼀個時刻我們只能看到一面。 通過分析頂點數據的順序 ,OpenGL可以做到檢查所有正面朝向觀察者的面,並渲染它們;從⽽丟棄背面朝向的面。

⚠️注意: 正⾯和背⾯是有三角形的頂點定義順序和觀察者方向共同決定的。若觀察者的觀察⽅向發生改變,正⾯和背面也會發生相應的改變。

弊端: 如果前後兩個點都是正面或是背面,這時OpenGL無法區分哪個面在前,哪個面在後,就可能出現下圖所示的問題。

深度,就是像素點在3D世界中距離攝像機的距離,即Z值。

深度緩存區,就是⼀塊內存區域,專門存儲每個像素點的深度值。深度值(Z值)越⼤,則離攝像機就越遠。

為什麼需要深度緩沖區?

深度緩沖區和顏⾊緩存區是對應的。顏⾊緩存區存儲 像素的顏⾊信息 ,而深度緩沖區存儲 像素的深度信息

在決定是否繪制⼀個物體表⾯時,首先要將表面對應的像素的深度值與當前深度緩沖區中的值進⾏⽐較。如果大於深度緩沖區中的值,則丟棄這部分;否則利⽤這個像素對應的深度值和顏⾊值,分別更新深度緩沖區和顏色緩存區。這個過程稱為 深度測試

深度值,⼀般由16位、24位或者32位值表示,通常是24位。

使⽤正⾯/背面剔除法和深度測試法解決了OpenGL的渲染效率問題。

由於精度的限制,對於相差非常小的深度值(比如在同一個深度進行2次渲染),就可能出現不能正確區分兩個深度值的問題,導致測試的結果隨機出現。所以,顯示時2個畫⾯交錯出現,就會出現閃爍問題。

增大重疊或深度值接近的2個圖形的深度值差距,使得OpenGL可以區分兩個深度值。

步驟三: 關閉Polygon Offset

在OpenGL中提⾼渲染效率的⼀種⽅式。 只刷新屏幕上發⽣變化的部分。

OpenGL渲染時會把顏色值存在顏⾊緩存區中,每個⽚段的深度值也是放在深度緩沖區。

當混合功能被開啟時,源顏色和⽬標顏色的組合方式是 混合方程式 控制的。在默認情況下,混合方程式如下所示:

混合函數經常用於實現在其他一些不透明的物體前面繪制一個透明物體的效果。

實際上不止一種顏色混合方程式,OpenGL有5個不同的方程式進行選擇。

表中R、G、B、A 分別代表 紅、綠、藍、Alpha
表中下標S、D,分別代表源、⽬標
表中C 代表常量顏⾊(默認⿊色)

下⾯通過一個常見的混合函數組合來說明問題:

如果顏色緩存區已經有一種顏⾊紅色(1, 0, 0, 0)
在這上面混合一種alpha為0.6的藍色(0, 0, 1, 0.6)

最終顏色是以原先的紅色(⽬標顏色)與後來的藍色(源顏色)進⾏組合。源顏色的alpha值越高,添加的藍色顏色成分越高,⽬標顏⾊所保留的成分就會越少。

8. opengl+獲得深度值Z總在變

摘要 在開始介紹深度緩存之前,先了解一下隱藏表面消除。

9. OPENGL怎麼讀深度緩存區的數據

讀取幀緩存中(x,y)點的深度值保存到Depth里
-----
這個(x,y)點和物體的頂點(Vertex)一樣是參與了各種變換的(視變換/投影變換),所以可能並不是最終的窗口的(x,y)的位置。如果需要窗口中從(x,y)開始的數據,需要指定(x,y)是位於窗口坐標的.

10. opengl es深度測試是gpu執行嗎

在OpenGL ES中默認是不開啟深度測試的,不使用深度測試的時候,先繪制較近的物體,然後繪制較遠的物體,當遠處的物體和近處的物體出現重疊時導致近處的物體被遠處的物體遮擋,這不符合實際的現象,也不是我們想要的效果。
深度測試則是可以解決這種問題,開啟深度測試後,深度緩存中存儲著的每個像素點都包含深度信息,當繪制新的像素時,先和深度緩存中的深度值進行比較,當深度值比深度緩存中的深度值大時(也就是離相機遠)則使用原來大顏色值繪制,反之則使用新的顏色值。
現在大部分的GPU都提供一個叫做提前深度測試(Early Depth Testing)的硬體特性。提前深度測試允許深度測試在片段著色器之前運行。只要我們清楚一個片段永遠不會是可見的(它在其他物體之後),我們就能提前丟棄這個片段。

熱點內容
交換機ip地址為什麼要配置 發布:2024-10-06 20:31:56 瀏覽:375
qq瀏覽器如何取消保存密碼 發布:2024-10-06 20:14:48 瀏覽:649
shell腳本ctrlc 發布:2024-10-06 20:10:37 瀏覽:888
壓縮板好嘛 發布:2024-10-06 20:10:28 瀏覽:670
java編譯基礎教程 發布:2024-10-06 20:09:47 瀏覽:268
我的世界電腦java怎麼玩伺服器 發布:2024-10-06 19:16:54 瀏覽:480
存儲空間大於存儲池中的可用容量 發布:2024-10-06 19:15:28 瀏覽:33
什麼叫估演算法 發布:2024-10-06 19:15:20 瀏覽:87
c語言庫編譯 發布:2024-10-06 19:09:23 瀏覽:747
啊里雲系統電視如何更換安卓系統 發布:2024-10-06 18:50:09 瀏覽:577