QOpenGLFunctions的使用(2)
前一小結請參考:QOpenglFuncations(1) www.icmzn.com
本小節介紹相關的類:
1. The QGLContext class
The QGLContext class包裝了OpenGL的渲染環境類,即所有的QOpengl的繪制都在該環境中進行。
An OpenGL rendering context is a complete set of OpenGL state variables. The rendering context's format is set in the constructor, but it can also be set later with setFormat(). The format options that are actually set are returned by format(); the options you asked for are returned by requestedFormat(). Note that after a QGLContext object has been constructed, the actual OpenGL context must be created by explicitly calling the create() function. ThemakeCurrent() function makes this context the current rendering context. You can make no context current using doneCurrent(). The reset() function will reset the context and make it invalid.
OpenGL渲染換金,就是一個完整的OpenGL的狀態變量集合。 在構造函數中QGLContext::QGLContext(const QGLFormat & format)需要指定渲染的格式,也可以通過setFormat()來進行后續的設置。實際設置的format options可以通過format()返回。而options則通過requestFormat()來返回。注意: 一旦QGLComtext 環境對象構造完畢,則需要通過顯示調用create()函數來創建Opengl的實際的環境變量、
inline QGLContext* createOpenGLContext() { QOpenGLContext *context = new QOpenGLContext(); QSurfaceFormat format; format.setVersion(2,1); format.setProfile(QSurfaceFormat::CompatibilityProfile); context->setFormat(format); QGLContext *result = QGLContext::fromOpenGLContext(context); result->create(); return result; }
makeCurrent() 函數作用就是將該環境變量作為當前的渲染環境變量,這樣所有的GL函數都可以在該環境變量下操作。可以在非main UI 線程之外的線程調用這個方法,從而確保從UI線程中將該環境變量設置為相關的線程中,從而在線程中完成相應的繪制。void QGLContext::moveToThread(QThread * thread)。
可以通過使用doneCurrent()函數來設置當前環境中空的GL環境變量。正常情況下不需要調用該函數,QGLContext會自動調用。
If you're using double buffering you can swap the screen contents with the off-screen buffer using swapBuffers().
如果使用雙緩存方式來使用OpenGGL,則在off-screen 緩存中使用swapBuffers()函數。void QGLContext::swapBuffers() const,作用是完成OpenGL 一幀數據的渲染,確保再次調用makeCurrent(),然后在開始新的繪制。
注意:QGLContext 不是線程安全的。
2. The QSurface class
The QSurface class is an abstraction of renderable surfaces in Qt.
The size of the surface is accessible with the size() function。即返回Surface的像素數量size。The rendering specific attributes of the surface are accessible through the format() function.通過format來設置其格式。
(1)The QSurfaceFormat class
即表示QSurface的格式。The format includes the size of the color buffers, red, green, and blue; the size of the alpha buffer; the size of the depth and stencil buffers; and number of samples per pixel for multisampling. In addition, the format contains surface configuration parameters such as OpenGL profile and version for rendering, whether or not to enable stereo buffers, and swap behaviour.
格式包括顏色緩沖的大小,rgb, 透明緩沖的大小。 深度緩存代銷。 每個像素多采樣的數量。 另外, 也包含surface配置參數,如Opengl的profile,以及版本來渲染。以及是否雙緩存。等。
默認的 QSurfaceFormat. 是Opengl 2.0版本,因為其提供了最高的跨平台移植性,以及Opengl的實現。
3. QOpenGLContext
The QOpenGLContext class represents a native OpenGL context, enabling OpenGL rendering on a QSurface.
QOpenGLContex類表征了native OpenGl Contex, 保證OpenGl渲染在QSurface。
QOpenGLContext represents the OpenGL state of an underlying OpenGL context. To set up a context, set its screen and format such that they match those of the surface or surfaces with which the context is meant to be used, if necessary make it share resources with other contexts withsetShareContext(), and finally call create(). Use the return value or isValid() to check if the context was successfully initialized.
QOpenGLContext 表征了Opengl的環境的狀態。
A context can be made current against a given surface by calling makeCurrent(). When OpenGL rendering is done, call swapBuffers() to swap the front and back buffers of the surface, so that the newly rendered content becomes visible. To be able to support certain platforms, QOpenGLContextrequires that you call makeCurrent() again before starting rendering a new frame, after calling swapBuffers().
通過makeCurrent()來使OpenGL環境稱為當前相應的OpenGL, 當OpenGL渲染完畢,調用swapBuffers()來交換前后Surface的緩存。這樣,新渲染的內容就可以顯示出來。在支持某些平台下,調用swapBuffers()之后,QOpenglContex還要求再次此調用makeCurrent()在開始渲染一新的內容之前。
If the context is temporarily not needed, such as when the application is not rendering, it can be useful to delete it in order to free resources. You can connect to the aboutToBeDestroyed() signal to clean up any resources that have been allocated with different ownership from the QOpenGLContextitself.
當contex暫時沒有使用個,如應用沒有渲染操作,可以delete 來釋放資源。通過連接 aboutToBeDestroyed() 信號 來清理資源,即這些資源是被不同的QOpenGLContex創建的。
Once a QOpenGLContext has been made current, you can render to it in a platform independent way by using Qt's OpenGL enablers such asQOpenGLFunctions, QOpenGLBuffer, QOpenGLShaderProgram, and QOpenGLFramebufferObject. It is also possible to use the platform's OpenGL API directly, without using the Qt enablers, although potentially at the cost of portability. The latter is necessary when wanting to use OpenGL 1.x or OpenGL ES 1.x.
一旦,QOpenGLContex稱為當前的環境,則就可以渲染,且以平台無關的方式來使用Qt的OpenGL,如QOpenglFunctions,QOpenglBuffer,QOpenglShaderPro等等。同時,也能夠直接使用平台相關的OpenGL的API來直接繪制渲染,這樣,就會損失移植性的代價。
可以查看OpenGL Window 的例子,其中使用了QOpenGLContex的用法。
(1)線程相關性
QOpenglContex的環境實例可以移到任意其他不同的線程中 moveToThread()。 不要從QOpenglContext對象所屬的不同的其他線程中調用makeCurrent().一個contex只能夠存在一個當前線程中,且相應的surface。並且注意:一個線程只能夠有一個contgext實例。
(2)Context Resource Sharing環境資源共享
Resources, such as framebuffer objects, textures, and vertex buffer objects can be shared between contexts. Use setShareContext() before callingcreate() to specify that the contexts should share these resources. QOpenGLContext internally keeps track of a QOpenGLContextGroup object which can be accessed with shareGroup(), and which can be used to find all the contexts in a given share group. A share group consists of all contexts that have been successfully initialized and are sharing with an existing context in the share group. A non-sharing context has a share group consisting of a single context.
資源,如緩存對象,紋理,頂點緩存對象能夠共享,在不同的QOpenglContext實例之間。 在調用create()之前調用setShareContext()從而可以指定該context共享這些資源。QOpenglContext內部保持跟蹤QOpenglContextGroup對象,即通過shareGroup() 組合在一個組中,則可以在一個共享的組中公用查找相應的資源。共享組由成功初始化后的其他context,並且共享一個共享組中的現存的context。 非共享context則只有一個context的共享組。
(3)Default Framebuffer 默認的框架緩存
On certain platforms, a framebuffer other than 0 might be the default frame buffer depending on the current surface. Instead of calling glBindFramebuffer(0), it is recommended that you use glBindFramebuffer(ctx->defaultFramebufferObject()), to ensure that your application is portable between different platforms. However, if you use QOpenGLFunctions::glBindFramebuffer(), this is done automatically for you.
在某一類的平台下, 框架緩存依賴於當前的surface。不調用glBindFrameBuffer(0), 但是,推薦使用glBindFramebuffer(ctx->defaultFramebufferObject()) 的方式,來確保應用程序可移植性。然而,如果使用 QOpenGLFunctions::glBindFramebuffer(),,則自動執行處理。
bool QOpenGLContext::create()
以當前的配置來創建OpenGL環境。當前配置包括: format,sharecontext, screen。
If the OpenGL implementation on your system does not support the requested version of OpenGL context, then QOpenGLContext will try to create the closest matching version. The actual created context properties can be queried using the QSurfaceFormat returned by the format() function. For example, if you request a context that supports OpenGL 4.3 Core profile but the driver and/or hardware only supports version 3.2 Core profile contexts then you will get a 3.2 Core profile context.
如果平台上的Opengl 實現不支持請求的Opengl版本,則QOpenglContext會視圖創建一個最接近的版本實現的環境實例。這樣實際創建的版本可以通過format()來查看。如,如果請求支持OpenGl 4.3 Core 的版本,但是驅動或者硬件只支持 3.2Core的版本,這樣,實際創建的就是3.2 Core版本的環境。
endl;
