QOpenGLFunctions的使用

1.  QOpenGLFunctions  说明

   QOpenGLFunctions 类提供了跨平台的OpenGl ES2.0 API版本。

  OpenGL 2.0 提供了OpenGL中的子类集合,可以提供跨多个平台的桌面系统以及嵌入式OpenGL的实现。然而,却很难使用子类因为子类需要解决许多平台系统的操作问题。

  因此 QOpenGLFunctions提供了这样的API,可以保证在所有的OpenGL系统中使用,并且也关注不同系统中的OpenGL的版本API的使用。Qt推荐直接继承的方式来使用 QOpenGLFunctions类。

2.  QOpenGLFunctions 使用

class MyGLWindow : public QWindow, protected QOpenGLFunctions
{
Q_OBJECT
public:
MyGLWindow(QScreen *screen = ); protected:
void initializeGL();
void paintGL(); QOpenGLContext *m_context;
}; MyGLWindow(QScreen *screen)
: QWindow(screen), QOpenGLWidget(parent)
{
setSurfaceType(OpenGLSurface);
create(); // Create an OpenGL context
m_context = new QOpenGLContext;
m_context->create(); // Setup scene and render it
initializeGL();
paintGL()
} void MyGLWindow::initializeGL()
{
m_context->makeCurrent(this);
initializeOpenGLFunctions();
}

  paintGL函数中可以使用任意的Opengl ES 2.0 API且不需要明确声明。如直接使用glActiveTexture():

  written by www.icmzn.com

void MyGLWindow::paintGL()
{
m_context->makeCurrent(this);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, textureId);
...
m_context->swapBuffers(this);
m_context->doneCurrent();
}

  An alternative approach is to query the context's associated QOpenGLFunctions instance. This is somewhat faster than the previous approach due to avoiding the creation of a new instance, but the difference is fairly small since the internal data structures are shared, and function resolving happens only once for a given context, regardless of the number of QOpenGLFunctions instances initialized for it.

  可选的方式是查找当前环境关联的QOpenGLFunctions实例, 这比之前快,因为避免了新实例的创建。但是,差异不大因为内部数据结构是共享的,且函数解析往往只在给定的环境中调用一次。

QOpenGLFunctions *glFuncs = QOpenGLContext::currentContext()->functions();
glFuncs->glActiveTexture(GL_TEXTURE1);

  QOpenGLFunctions provides wrappers for all OpenGL ES 2.0 functions, including the common subset of OpenGL 1.x and ES 2.0. While such functions, for example glClear() or glDrawArrays(), can be called also directly, as long as the application links to the platform-specific OpenGL library, calling them viaQOpenGLFunctions enables the possibility of dynamically loading the OpenGL implementation.

  QOpenGLFunctions 提供了对OpenGL ES2.0 包装。包括f OpenGL 1.x and ES 2.0.的子类。只要应用程序链接到指定平台的Opengl库中个,则可以直接调用相应的API,通过借助于QOpenGLFunctions 可以确保能够动态加载Opengl的实现库。

3. 不同版本的 QOpenGLFunctions

  The QAbstractOpenGLFunctions class is the base class of a family of classes that expose all functions for each OpenGL version and profile.

   QAbstractOpenGLFunctions 类提供了对每个Opengl版本的API函数的基本集合。

  OpenGL implementations on different platforms are able to link to a variable number of OpenGL functions depending upon the OpenGL ABI on that platform. For example, on Microsoft Windows only functions up to those in OpenGL 1.1 can be linked to at build time. All other functions must be resolved at runtime. The traditional solution to this has been to use either QOpenGLContext::getProcAddress() or QOpenGLFunctions. The former is tedious and error prone and means dealing directly with function pointers. The latter only exposes those functions common to OpenGL ES 2 and desktop OpenGL. There is however much new OpenGL functionality that is useful when writing real world OpenGL applications.

  OpenGL 实现不同平台上的相应的API,因为其可以直接连接到相应平台上的API接口。如在微软系统中,只能提供Opengl 1.1 接口使用。其他的函数必须在运行时解析。传统的解决方法是使用 QOpenGLContext::getProcAddress() or QOpenGLFunctions. 前者直接操作相应的函数指针,因此乏味且容易出错。后者则展示了嵌入式Opengl ES 2 和桌面Opengl的公共接口函数。则在使用Opengl 应用显示渲染时,足够新的函数API。

  Qt now provides a family of classes which all inherit from QAbstractOpenGLFunctions which expose every core OpenGL function by way of a corresponding member function. There is a class for every valid combination of OpenGL version and profile. Each class follows the naming convention:

  Qt 现在提供了继承自的 QAbstractOpenGLFunctions大家族, 都提供了OpenGl 核心函数对应相应的函数版本。因此对应每个有效的Opengl版本都有相应的类。且每个类遵循下述规约:

  上述每个类都继承自 QAbstractOpenGLFunctions  。其中Opengl 3.1 移除了大量的deprecated 函数,因此足够简洁且更加通用的API。而对于Opengl 3.2 ,则采用了定义两种类的方式: Opengl 3.2 core 以及 Opengl 3.2 Compatibility。

  对于Core类型的类,则其不包含在前一版本Opengl 3.1中摒弃的函数API;对于Compatibility 类型的类,则其包含所有的函数API在core版本,以及相应的前一版本Opengl 3.1中并且的函数API。通过这样的方法,Compatibility 的类允许用户使用新版本的Opengl,但是也可以保持使用合法的core API . 因此推荐使用 Core的类。

  但是需要注意的是,对于API接口实现,如苹果公司,没有实现显影的Compatibility的类,因此,如果你希望使用新的Opengl的API在OSX系统中,你应该确保你使用Core 类通过借助于QSurfaceFormat::setProfile()

  Qt 提供了多有版本与Core以及Compatibility的实现,对于Opengl版本Opengl 3.1 到Opengl 4.3,如下所示:

  A pointer to an object of the class corresponding to the version and profile of OpenGL in use can be obtained from QOpenGLContext::versionFunctions(). If obtained in this way, note that the QOpenGLContext retains ownership of the object. This is so that only one instance need be created.

QAbstractOpenGLFunctions * QOpenGLContext::versionFunctions(const QOpenGLVersionProfile &versionProfile = QOpenGLVersionProfile()) const

  函数 QOpenGLContext::versionFunctions可以返回对于该环境中versionProfile相应的QAbstgractOpenglFuncation指针。在使用人一个API之前,需要通过使用当前环境变量通过该函数 QAbstractOpenGLFunctions::initializeOpenGLFunctions()来初始化,然后才能使用。注意:如果这样使用,则当前的Opengl环境变量则仍然是返回的对象指针所致的Object。这是因为只能有一个instance创建。

  Before calling any of the exposed OpenGL functions you must ensure that the object has resolved the function pointers to the OpenGL functions. This only needs to be done once per instance with initializeOpenGLFunctions(). Once initialized, the object can be used to call any OpenGL function for the corresponding version and profile. Note that initializeOpenGLFunctions() can fail in some circumstances so check the return value. Situations in which initialization can fail are if you have a functions object for a version or profile that contains functions that are not part of the context being used to resolve the function pointers.

  在调用任何的OpenGL functions之前,必须要确保当前的Object已经解决了函数指针指向Opengl 函数的问题。这只需要在初始化initializeOpenGLFunctions()时,执行一次。一旦初始化, 当前的对象Object能够使用来调用Opengl 的API 到相应的版本中。注意:在一些环境中,初始化initializeOpenGLFunctions()也会发生调用失败的情况,因此来检查返回的值。如对于使用的版本不兼容当前的环境的情况下,就会初始化失败。

  If you exclusively use function objects then you will get compile time errors if you attempt to use a function not included in that version and profile. This is obviously a lot easier to debug than undefined behavior at run time.

  如果你仅仅(只,独家)使用函数Object,如果你调用该函数对象之外的版本API,则将会返回兼容的异常。

TYPE * QOpenGLContext::versionFunctions() const

  该函数则返回当前环境中的函数版本的函数对象指针。同时,也要在使用之前调用initializeOpenGLFunctions来再次初始化该函数对象,将该对象重新绑定到当前的环境实例中。

  一般都是来使用该函数的模板类型,从而可以自动转换为正确的函数来行。因此是可以请求一个不同版本的函数对象,即与当前环境对象中的函数对象不同。即如下图采用模板方法来获取指定的函数对象版本。

 代码示例:

QOpenGLFunctions_3_3_Core* funcs = ;
funcs = context->versionFunctions<QOpenGLFunctions_3_3_Core>();
if (!funcs) {
qWarning() << "Could not obtain required OpenGL context version";
exit();
}
funcs->initializeOpenGLFunctions();

  注意:请求其他不同的函数对象也可能会调用失败,并且返回NULL空指针,即请求不满足当前使用环境中的函数对象。例如:

  • Requesting a 3.3 core profile functions object would succeed.
  • Requesting a 3.3 compatibility profile functions object would fail. We would fail to resolve the deprecated functions.
  • Requesting a 4.3 core profile functions object would fail. We would fail to resolve the new core functions introduced in versions 4.0-4.3.
  • Requesting a 3.1 functions object would succeed. There is nothing in 3.1 that is not also in 3.3 core.

4. 使用某一个版本的QOpenGLFunctions

    QOpenGLFunctions_2_1 ,提供了OpenGL 2.1 的规范。即其包装了Opengl2.1 的规范,可以直接使用Opengl2.1 的API。

endl;

QOpenGLFunctions的相关的使用(1)的更多相关文章

  1. 嵌入式单片机STM32应用技术(课本)

    目录SAIU R20 1 6 第1页第1 章. 初识STM32..................................................................... ...

  2. QOpenGLFunctions的使用(2)

    QOpenGLFunctions的使用(2) 前一小结请参考:QOpenglFuncations(1) www.icmzn.com 本小节介绍相关的类: 1. The QGLContext class ...

  3. java中的字符串相关知识整理

    字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...

  4. SQL Server相关书籍

    SQL Server相关书籍 (排名不分先后) Microsoft SQL Server 企业级平台管理实践 SQL Server 2008数据库技术内幕 SQL Server性能调优实战 SQL S ...

  5. dotNET跨平台相关文档整理

    一直在从事C#开发的相关技术工作,从C# 1.0一路用到现在的C# 6.0, 通常情况下被局限于Windows平台,Mono项目把我们C#程序带到了Windows之外的平台,在工作之余花了很多时间在M ...

  6. 在ASP.NET Core应用中如何设置和获取与执行环境相关的信息?

    HostingEnvironment是承载应用当前执行环境的描述,它是对所有实现了IHostingEnvironment接口的所有类型以及对应对象的统称.如下面的代码片段所示,一个HostingEnv ...

  7. virtualbox linux虚拟机相关

    linux虚拟机设置为静态IP 在virtualbox中安装好linux虚拟机后,如果采用的是NAT方式的话,linux虚拟机默认采用dhcp方式自动上网,而且用的是NetworkManager服务而 ...

  8. WebGIS中等值面展示的相关方案简析

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 等值面是气象.环保等相关项目上常用到的效果展示.在传统的CS项 ...

  9. .NET同步与异步之相关背景知识(六)

    在之前的五篇随笔中,已经介绍了.NET 类库中实现并行的常见方式及其基本用法,当然.这些基本用法远远不能覆盖所有,也只能作为一个引子出现在这里.以下是前五篇随笔的目录: .NET 同步与异步之封装成T ...

随机推荐

  1. 比较两个List列表,取得List中不同项返回

    /// <summary> /// 比对模型及属性数组 /// </summary> /// <typeparam name="TM">< ...

  2. mysql 8小时timeout问题

    MySQL> show variables like '%timeout%'; +--------------------------+-------+ | Variable_name      ...

  3. 关于python的字符编码

    理论特别多,金角大王讲的非常细致和深入浅出. 我来个简短的总结: python2的编码:默认是ascii,可以改变成gbk,utf-8等,但是用什么编码写的,就存储成什么编码.如果搬到linux,默认 ...

  4. Use Laravel/homestead 环境维护基于 brophp 开发的老项目

    1 前言 laravel/homestead 无疑是 laravel 项目开发的最佳环境. 如何使用这个环境维护基于 Brophp (或 Thinkphp) 开发的老项目呢? 以下是测试成功的步骤. ...

  5. Spring ConversionService 类型转换(二) ConversionService

    Spring ConversionService 类型转换(二) ConversionService Spring 系列目录(https://www.cnblogs.com/binarylei/p/1 ...

  6. spring colud 博客

    https://blog.csdn.net/forezp/article/details/70148833

  7. 关于部署传统的Dynamic Web项目

    现在大部分都是采用maven构建的项目,但是偶尔也会遇到一些较老的项目,采用的是传统的动态Web项目. 我最近碰到这样一个项目,项目用的jar包都放在了WEB-INF/lib目录下.之前的人采用的部署 ...

  8. Flex 得到一个对象的所有属性

    var obj:Object =..... ///需要处理的对象 fieldname:Array = ObjectUtil.getClassInfo(obj)["properties&quo ...

  9. 3、iOS Xcode创建protocol(代理).h文件

  10. php获取响应状态码

    $ch = curl_init('http://www.jb51.net'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_exec($ch); ...