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. JAVA程序 从命令行接受多个数字,求和之后输出结果

    源程序代码: public class sum{ public static void main(String[] args){ double[] a=new double[4]; a[0]=Doub ...

  2. Informatica_(2)第一个例子

    PowerCenter Repository Manager1.启动客户端程序连接服务器打开客户端(PowerCenter Repository Manager)PCRM;存储库--配置域--添加新域 ...

  3. python自学开始

    95年工科女一枚 java工程师算不上,只能说从事java开发相关的工作,由于对Python有着极其浓厚的兴趣,一周时间了解大概之后,决定从今天开始见缝插针自学Python,为了防止本人三天打鱼两天晒 ...

  4. Go语言之讲解GOROOT、GOPATH、GOBIN

    Go是一门全新的静态类型开发语言,具有自动垃圾回收,丰富的内置类型,函数多返回值,错误处理,匿名函数,并发编程,反射等特性. go命令依赖一个重要的环境变量:$GOPATH GOPATH允许多个目录, ...

  5. [转载]RPM中SPEC常用路径以及宏变量

    转自:http://blog.csdn.net/txgc1009/article/details/6833764 通过命令rpm --showrc查看实现代码.另外直接通过 rpm --eval &q ...

  6. BZOJ2330或洛谷3275 [SCOI2011]糖果

    BZOJ原题链接 洛谷原题链接 很明显的差分约束,但数据范围较大,朴素\(SPFA\)判正环求解会\(T\)(理论上如此,但我看到有挺多人用朴素的还跑得挺快..),所以需要优化. 我们所建立的有向图中 ...

  7. MySQL 检索数据及提高检索速度的方法

    检索数据 mysql> SELECT [DISTINCT] 表名.列名,表名.列名,表名.列名 -- 使用通配符*表示所有列 DISTINCT表示返回不同的值 -> FROM 数据库名.表 ...

  8. 存储过程和函数 PROCEDURE & FUNCTION

    SQL语句执行的时候,要首先编译,然后在被执行.在大型数据库系统中,为了提高效率,将为了完成特定功能的SQL语句集进行编译优化后,存储在数据库服务器中,用户通过指定存储过程的名字来调用执行. 具体而言 ...

  9. SSH无法连上CentOS7的问题

    今天安装完带GNOME的CentOS后发现XShell无法连接上Linux. 原因是sshd服务没有开启.下面是解决办法: 1 ip addr 发现网卡名称为ens33 2 在/etc/sysconf ...

  10. maven下载的jar相应pom文件下载不完整问题。

    今天遇到一个奇葩问题: 同样的项目,我启动报错 : 某个class文件找不到.. 查找maven 依赖也的确没有找到 对应的jar 包. 查找同事项目,可以看到该class对应的 jar 包 是 lo ...