QOpenGLFunctions的使用

Posted 夏天/isummer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QOpenGLFunctions的使用相关的知识,希望对你有一定的参考价值。

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;

以上是关于QOpenGLFunctions的使用的主要内容,如果未能解决你的问题,请参考以下文章

QOpenGLFunctions的正确用法

QOpenGLFunctions 和 PySide2

QOpenGLFunctions类

Qt OpenGL点大小

在使用 QOpenGLFunctions 时将 OpenGL 功能封装在 C++ 对象中

QOpenGLFunctions 缺少重要的 OpenGL 函数