QOpenGLFunctions的相关的使用(1)
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,如下所示:
- QOpenGLFunctions_3_1
- QOpenGLFunctions_3_2_Core
- QOpenGLFunctions_3_2_Compatibility
- QOpenGLFunctions_3_3_Core
- QOpenGLFunctions_3_3_Compatibility
- QOpenGLFunctions_4_0_Core
- QOpenGLFunctions_4_0_Compatibility
- QOpenGLFunctions_4_1_Core
- QOpenGLFunctions_4_1_Compatibility
- QOpenGLFunctions_4_2_Core
- QOpenGLFunctions_4_2_Compatibility
- QOpenGLFunctions_4_3_Core
- QOpenGLFunctions_4_3_Compatibility
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)的更多相关文章
- 嵌入式单片机STM32应用技术(课本)
目录SAIU R20 1 6 第1页第1 章. 初识STM32..................................................................... ...
- QOpenGLFunctions的使用(2)
QOpenGLFunctions的使用(2) 前一小结请参考:QOpenglFuncations(1) www.icmzn.com 本小节介绍相关的类: 1. The QGLContext class ...
- java中的字符串相关知识整理
字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...
- SQL Server相关书籍
SQL Server相关书籍 (排名不分先后) Microsoft SQL Server 企业级平台管理实践 SQL Server 2008数据库技术内幕 SQL Server性能调优实战 SQL S ...
- dotNET跨平台相关文档整理
一直在从事C#开发的相关技术工作,从C# 1.0一路用到现在的C# 6.0, 通常情况下被局限于Windows平台,Mono项目把我们C#程序带到了Windows之外的平台,在工作之余花了很多时间在M ...
- 在ASP.NET Core应用中如何设置和获取与执行环境相关的信息?
HostingEnvironment是承载应用当前执行环境的描述,它是对所有实现了IHostingEnvironment接口的所有类型以及对应对象的统称.如下面的代码片段所示,一个HostingEnv ...
- virtualbox linux虚拟机相关
linux虚拟机设置为静态IP 在virtualbox中安装好linux虚拟机后,如果采用的是NAT方式的话,linux虚拟机默认采用dhcp方式自动上网,而且用的是NetworkManager服务而 ...
- WebGIS中等值面展示的相关方案简析
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 等值面是气象.环保等相关项目上常用到的效果展示.在传统的CS项 ...
- .NET同步与异步之相关背景知识(六)
在之前的五篇随笔中,已经介绍了.NET 类库中实现并行的常见方式及其基本用法,当然.这些基本用法远远不能覆盖所有,也只能作为一个引子出现在这里.以下是前五篇随笔的目录: .NET 同步与异步之封装成T ...
随机推荐
- c# 把对象加入队列,对象为全局变量,对象改变队列值也跟着改变
若程序把对象加入队列,对象为全局变量,对象改变队列值也跟着改变,如下: filecontent 为两个字段的属性值. class FileContent { // public string Htt ...
- java学习笔记1--基础知识
1.java数据类型 2.类之间的几种关系
- 快速掌握Ajax-Ajax基础实例(Ajax返回Json在Java中的实现)
(转)实例二:Ajax返回Json在Java中的实现 转自http://www.cnblogs.com/lsnproj/archive/2012/02/09/2341524.html#2995114 ...
- Thrift.0
0. Thrift的特性 1. 安装Thrift编译器 [Todo] http://thrift.apache.org/docs/install/ http://thrift.apache.org/d ...
- JianShu_failban2实现动态屏蔽的功能
一,首先是服务安装 #vim /etc/yum.repos.d/Centos-Base.repo 在最新新增 [atrpms] name=Red Hat Enterprise Linux $relea ...
- How-to Install VMware Tools on Debian Stretch 9 32/64bit Linux+GNU
在虚拟机VMWARE上安装debian9 安装vmwaretools时候遇到问题 询问我IFCONFIG安装在哪里? 新版的debian不知道是用户权限问题还是使用了其他网络配置工具 vmwareto ...
- 通过脚本命令cacls提升某个用户都某路径的操作权限
摘要----项目需要对服务器上的某个路径下的目录,修改权限:给Users用户组的用户添加修改写入权限. 原理----通过批处理脚本实现,命令使用 icacls 修改ACL 来达到修改权限的目的. 操作 ...
- random库的常见用法
import random print( random.randint(1,10) ) # 产生 1 到 10 的一个整数型随机数 print( random.random() ) # 产生 0 到 ...
- 【算法】Escape
The students of the HEU are maneuvering for their military training. The red army and the blue army ...
- CentOS下利用mysqlbinlog恢复MySQL数据库
如果不小心对数据库进行误操作,而又没有及时备份怎么办?这恐怕是广大的coder经常遇到的一类问题.我今天就因为不小心删除了某个数据库,但最后的备份是1个礼拜前的,唯一能解决的办法就是通过mysqlbi ...