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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

OpenGL中的上下文 理解整理

發(fā)布時(shí)間:2023/12/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenGL中的上下文 理解整理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

OpenGL中的上下文(Context)

OpenGL狀態(tài)機(jī)與上下文

OpenGL是一個(gè)狀態(tài)機(jī),它擁有非常多的狀態(tài)變量,并且每個(gè)狀態(tài)變量都有默認(rèn)值。

OpenGL在渲染的時(shí)候需要一個(gè)Context來(lái)記錄了OpenGL渲染需要的所有信息和狀態(tài),可以把它理解成一個(gè)大的結(jié)構(gòu)體,它里面記錄了當(dāng)前繪制使用的顏色、是否有光照計(jì)算以及開(kāi)啟的光源等非常多我們使用OpenGL函數(shù)調(diào)用設(shè)置的狀態(tài)和狀態(tài)屬性。

在程序中,我們?cè)O(shè)置的各種狀態(tài)和默認(rèn)狀態(tài)會(huì)一直生效,直到我們?cè)俅涡薷乃鼈儭顟B(tài)機(jī)并不是一個(gè)好的設(shè)計(jì),多個(gè)繪制算法同時(shí)跑,容易被前面的狀態(tài)所影響,OpenGL為了向前兼容,狀態(tài)機(jī)的形式就被一直延續(xù)下來(lái)了。

GPU的CS模式和上下文

如上所述,OpenGL的一組狀態(tài)機(jī)對(duì)應(yīng)著一個(gè)上下文。OpenGL采用了Client-Server模式,GPU相當(dāng)于一臺(tái)服務(wù)器,可對(duì)應(yīng)多個(gè)客戶端即上下文,一個(gè)客戶端維護(hù)著一組狀態(tài)機(jī)。大部分的OpenGL命令都是異步的,不代表真正地執(zhí)行,只是客戶端向服務(wù)器發(fā)送了一些命令(同時(shí)有一些API可實(shí)現(xiàn)同步功能)。如果兩個(gè)窗口分別對(duì)應(yīng)兩個(gè)不同的繪制上下文,則兩個(gè)窗口彼此狀態(tài)獨(dú)立,繪制狀態(tài)不會(huì)互相影響,宏觀上看繪制也是并行的。

線程私有

OpenGL的繪制命令都是作用在當(dāng)前的Context上,這個(gè)Current Context是一個(gè)線程私有(thread-local)的變量,也就是說(shuō)如果我們?cè)诰€程中繪制,那么需要為該線程制定一個(gè)Current Context的,當(dāng)多個(gè)線程參與繪制任務(wù)時(shí),需要原線程解綁再重新綁定新的線程。多個(gè)線程不能同時(shí)指定同一個(gè)Context為Current Context,否則會(huì)導(dǎo)致崩潰。

OpenGL所創(chuàng)建的資源, 其實(shí)對(duì)程序員可見(jiàn)的僅僅是ID而已, 其內(nèi)容依賴于這個(gè)上下文, 因此在大型程序中的一般做法是申請(qǐng)一條線程專(zhuān)門(mén)用于繪制,創(chuàng)建線程時(shí),為該繪制線程申請(qǐng)一個(gè)繪制上下文,一直作為Current Context,不再進(jìn)行切換。所有的繪制相關(guān)的操作,都在繪制線程完成。但是如果涉及復(fù)雜的OpenGL渲染時(shí), 這樣就未必足夠,當(dāng)有需求需多個(gè)并行的繪制任務(wù)時(shí),則要?jiǎng)?chuàng)建多個(gè)Context,為并行的線程分別綁定不同的上下文。

共享上下文

一個(gè)是進(jìn)程可以創(chuàng)建多個(gè)Context,它們可以分別描繪出不同的圖形界面,就像一個(gè)應(yīng)用程序可以打開(kāi)多個(gè)窗口一樣。每個(gè)OpenGL Context是相互獨(dú)立的,它們都有自己的OpenGL對(duì)象集。但有時(shí)會(huì)有場(chǎng)景需要多個(gè)上下文使用同一份紋理資源的情況,創(chuàng)建Context,意味著系統(tǒng)資源的占用,同一份紋理重復(fù)申請(qǐng)會(huì)造成資源浪費(fèi),因此OpenGL上下文允許共享一部分資源。大部分OpenGL Objects是可以共享的,包括Sync Object和GLSL Objects。Container Objects和Query Objects是不能共享的。例如紋理、shader、Buffer等資源是可以共享的,但Frame Buffer Object(FBO)、Vertex Array Object(VAO)等容器對(duì)象不可共享,但可將共享的紋理和VBO綁定到各自上下文的容器對(duì)象上。上下文創(chuàng)建時(shí)可以指定共享上下文,具體可見(jiàn)示例。

上下文的創(chuàng)建方法

不同的操作系統(tǒng),都有各自的上下文創(chuàng)建方法和設(shè)置當(dāng)前上下文的API。

最簡(jiǎn)單的上下文可以通過(guò)Glut或是Glfw創(chuàng)建。例如Glut的函數(shù)GlutCreateWindow除了創(chuàng)建了一個(gè)窗口,同時(shí)還創(chuàng)建了一個(gè)Context,并將創(chuàng)建的Context設(shè)置為Current Context。還可以使用glutInitContextVersion接口指定Context版本。

對(duì)于Windows平臺(tái)首先創(chuàng)建一個(gè)設(shè)備上下文(Device Context,DC),DC的創(chuàng)建可以輸入一個(gè)GPU參數(shù),從而指定DC和DC對(duì)應(yīng)的上下文將在哪個(gè)GPU上跑。以DC為輸入,可以創(chuàng)建一個(gè)繪制上下文。創(chuàng)建繪制上下文以后,調(diào)用MakeCurrent,將創(chuàng)建的上下文設(shè)置為當(dāng)前的繪制上下文。glew庫(kù)中的wglew.h封裝了windows下創(chuàng)建上下文的方法。

對(duì)于Linux平臺(tái)可以使用EGL提供的接口創(chuàng)建上下文。

創(chuàng)建了繪制上下文,并設(shè)置為當(dāng)前上下文以后,還不能使用OpenGL最新的特性,調(diào)用OpenGL 1.1以后的API仍然會(huì)崩潰。一般我們使用Glew庫(kù),調(diào)用glewInit(),得到OpenGL隨顯卡驅(qū)動(dòng)一起發(fā)布的新特性的函數(shù)入口地址。

上下文類(lèi)型

在OpenGL 3.0版本之前,所有的OpenGL Context是統(tǒng)一的,都是一種兼容之前版本的模式(例如使用OpenGL 1.1編寫(xiě)的代碼,在支持OpenGL 2.1的設(shè)備上可以正常的運(yùn)行)。這些版本的OpenGL API也被稱(chēng)之為固定管線(相比較之后引入shader的可編程管線來(lái)說(shuō)), 但是從3.0開(kāi)始有了變化:

  • 1、 OpenGL 3.0 引入了廢棄機(jī)制,標(biāo)記了許多OpenGL的函數(shù)是廢棄的(但是3.0并沒(méi)有真正移除它們,也就是說(shuō)3.0版本仍然是一個(gè)可以向后兼容的Context)
  • 2、 OpenGL 3.1發(fā)布刪除了之前3.0標(biāo)記的過(guò)時(shí)函數(shù)(固定管線相關(guān)的函數(shù)),但是為了之前的OpenGL代碼可用, 引入了一個(gè)擴(kuò)展ARB_compatibility,這個(gè)擴(kuò)展可以讓OpenGL 3.1支持之前的OpenGL固定管線的內(nèi)容。
  • 3、 正是由于這個(gè)問(wèn)題,在OpenGL 3.2中正式引入了模式的概念(Profile),模式就將二者分離開(kāi)來(lái)了。OpenGL 3.2 中模式包括:
    • (1) Core Profile 只包含最新的Shader相關(guān)的函數(shù),程序必須使用Shader編寫(xiě)
      (2)compatibility Profile 可以兼容之前的OpenGL固定管線的內(nèi)容,也可以使用Core Profile中的內(nèi)容
  • 4、 3.2以后的版本直到OpenGL目前最新的版本(OpenGL 4.6)都是按照這種模式來(lái)做的。

opengl多線程繪制

實(shí)現(xiàn)效果:opengl開(kāi)啟兩個(gè)線程,一個(gè)線程用于繪制,另一個(gè)線程用于加載紋理。

實(shí)現(xiàn)方法:opengl是單線程的,其他線程不能訪問(wèn)另外線程的紋理資源,但是,如果兩個(gè)線程共享上下文,就可以訪問(wèn)彼此的紋理資源。

繪制線程:創(chuàng)建兩個(gè)上下文

//只有主要代碼 ... context = eglCreateContext(display, config, NULL, ctxAttribs); context1 = eglCreateContext(display, config, context, ctxAttribs); ...eglMakeCurrent(display, eglSurface, eglSurface, context);

加載紋理線程:綁定繪制線程中兩個(gè)上下文中的一個(gè)

eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, context1);

參考:
https://www.khronos.org/opengl/wiki/OpenGL_Context

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的OpenGL中的上下文 理解整理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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