本文原链接:http://www.cnblogs.com/zouzf/p/4423256.html

环境:Mac 10.9.2   Xcode5.1.1  Qt5.3  cocos2dx-2.2.4

项目基于 cocos2dx 2.x 源码二次封装后的框架进行开发,其中控件部分及相关的触摸事件传递机制等都改掉了;为了提高开发效率,项目还开发了一个 UI 编辑器用于可视化编辑 UI,但只有 win32版,公司都是 Mac 系统,很多同事对于 i3 的 cpu 的要装虚拟机来使用这个编辑器甚是抱怨~~于是 Mac 版本的 UI 编辑提上议程,同事们对于旧版的 UI 编辑器也有各种使用抱怨,于是进行重写~~,兼顾 Mac 和 win,使用 Qt 框架。

win32版本同事不久就做好了,Mac 版本就由我先行一步:先把 GL 渲染到 Qt 这个难点解决。其实,另一个同事在做 cocos2dx 3.x 的 UI 编辑器Mac 版本的时候,已经做了这个功能的,那是真的把 cocos2dx 的 GL 渲染到 Qt 控件上的,但他使用了3.x里的  glfw3native 相关的东西,在处理触摸事件的时候把要进行坐标转换。坐标转换还好, glfw3native 那部分的东西就不太好移植过来了。

后来尝试了一个方法:cocos2dx Cpp 里的 Mac版本是把 GL 渲染到NSWindow上,而 NSWindow 是和工程里的 .xib 文件关联的 (这里可能有误,请了解的朋友指正);如果直接把这个 NSWindow 窗口加到 Qt 控件上会如何?

1、添加对 Qt framework 的库和头文件的引用

安装完 qt,在安装目录下找到 Qt5.3.0/5.3/clang_64/lib 目录, 把 QtCore.framework、QtGui.framework、QtOpenGL.framework、QtWidgets.framework四个文件拷贝到 cocos2d-x-2.2.3/samples/Cpp/HelloCpp/proj.mac/qt 里,qt 是自己建的文件夹。HelloCpp 工程里通过 Build Phases ->Link Binary With Libraries 添加这四个 framework 的引用;HelloCpp 工程里通过 Build Setting->Search Paths->Header Search Paths 添加以下头文件搜索路劲:

qt/QtWidgets.framework/Versions//Headers
qt/QtCore.framework/Versions//Headers
qt/QtGui.framework/Versions//Headers
qt/QtOpenGL.framework/Versions//Headers

2、把 AppController.mm 文件从 HelloCpp 工程移除;把 WGLWidget.h 和 WGLWidget.mm 文件加到 HelloCpp 工程,文件内容具体如下:

 #ifndef WGLWIDGET_H
#define WGLWIDGET_H #include <QWidget>
#include <QtOpenGL>
#include "EAGLView.h" class WGLWidget : public QWidget
{ public:
WGLWidget(QWidget *parent = );
~WGLWidget(); private:
EAGLView* _glView;
NSWindow* _NSWindow;
int glviewWidth;
int glviewHeight; protected: virtual void mouseDoubleClickEvent(QMouseEvent *event);
virtual void closeEvent(QCloseEvent *event);
virtual void resizeEvent(QResizeEvent *event); }; #endif // WGLWIDGET_H
 #include "wglwidget.h"
#import "AppDelegate.h" static AppDelegate s_sharedApplication; WGLWidget::WGLWidget(QWidget *parent /* = 0 */): QWidget(parent)
{
this->glviewWidth = ;
this->glviewHeight = ; setMinimumSize(this->glviewWidth, this->glviewHeight);
setWindowTitle("HelloCpp");
setStyleSheet("background:green"); //以下设置参考自:AppController。mm
NSRect rect = NSMakeRect(, , this->glviewWidth, this->glviewHeight); _NSWindow = [[NSWindow alloc] initWithContentRect:rect
styleMask:(NSBorderlessWindowMask )
backing:NSBackingStoreBuffered
defer:YES]; [_NSWindow setBackgroundColor:[NSColor redColor]];
NSOpenGLPixelFormatAttribute attributes[] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFADepthSize, ,
NSOpenGLPFAStencilSize, , }; NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease]; _glView = [[EAGLView alloc] initWithFrame:rect pixelFormat:pixelFormat]; [_glView reshape]; // set window parameters
[_NSWindow becomeFirstResponder];
[_NSWindow setContentView:_glView];
[_NSWindow setAcceptsMouseMovedEvents:NO]; //通过 EAGLView* 对象来创建 QWindow,然后根据 QWindow 对象来创建 QWidget
QWindow* _glWindow = QWindow::fromWinId((WId) _glView);
QWidget* _glWidget = QWidget::createWindowContainer(_glWindow, parent); _glWidget->setParent(this);
_glWidget->resize(this->glviewWidth, this->glviewHeight); cocos2d::CCApplication::sharedApplication()->run(); } WGLWidget::~WGLWidget()
{ } void WGLWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
if(windowState() & Qt::WindowFullScreen)
showNormal();
else
showFullScreen();
} void WGLWidget::resizeEvent(QResizeEvent *event)
{
QSize size = event->size();
// printf("resizeEvent\n");
// printf("width: %d height: %d\n\n\n", size.width(), size.height()); //重绘 NSWindow 和 GLView 窗口
NSRect rect = NSMakeRect(, , size.width(), size.height());
[_NSWindow setFrame:rect display:YES animate:NO]; cocos2d::CCEGLView* glView = cocos2d::CCEGLView::sharedOpenGLView();
glView->setFrameSize(size.width(), size.height());//
glView->setDesignResolutionSize(this->glviewWidth, this->glviewHeight, kResolutionShowAll); } void WGLWidget::closeEvent(QCloseEvent *event)
{
QWidget::closeEvent(event);
}

3、把 main.m 文件改名为:main.mm,内容修改如下:

 //#import <Cocoa/Cocoa.h>
#include <QApplication>
#include "WGLWidget.h" int main(int argc, char *argv[])
{
QApplication app(argc, argv); WGLWidget mainWindow;
mainWindow.show();
app.installEventFilter(&mainWindow);
return app.exec(); //return NSApplicationMain(argc, (const char **)argv);
}

4、拉伸以下宽高看看效果,达到预期效果

     

5、总结

还是使用cocos2dx 自带的 AppController 类里创建 NSWindow 和 EAGLView 的那一套代码,然后用了个使巧的方法:

    QWindow* _glWindow = QWindow::fromWinId((WId) _glView);
QWidget* _glWidget = QWidget::createWindowContainer(_glWindow, parent); _glWidget->setParent(this);

实现了根据已有的 glview 窗口创建 QtWidget~~在 UI 编辑器里,你喜欢怎么操作这个 widget 都随意了~~

本文原链接:http://www.cnblogs.com/zouzf/p/4423256.html

Cocos2dx 把 glview 渲染到 Qt 控件上(Mac 环境)的更多相关文章

  1. 使用opencv在Qt控件上播放mp4文件

    文章目录 简介 核心代码 运行结果 简介 opencv是一个开源计算机视觉库,功能非常多,这里简单介绍一下OpenCV解码播放Mp4文件,并将图像显示到Qt的QLabel上面. 核心代码 头文件 #i ...

  2. Qt判断鼠标在控件上

    QT判断鼠标是否在某子窗口控件上方 需要注意的是,子窗口获取geometry,是相对于父窗口的相对位置,QCursor::pos()获取的是鼠标绝对位置,要不将父窗口的相对位置进行换算,要不将鼠标的绝 ...

  3. 如何获得 Qt窗口部件在主窗口中的位置--确定鼠标是否在某一控件上与在控件上的位置

    用Qt Creator 设计程序时,最方便的就是ui设计器,可以很容易的得到想要的布局. 但是这样自动布局带来的后果是很难知道窗口中某一部件在主窗口中的相对位置. 在处理子窗口鼠标事件时变的很麻烦.主 ...

  4. 一个显示 OpenCV Mat 图像的自定义 Qt 控件

    今天学习 Qt 的时候顺手写了一个,包含一个头文件 qcvdisplay.h 和一个源文件 qcvdisplay.cpp,因为这是 qt 默认的文件命名方式,在 Qt Designer 中提升控件时会 ...

  5. Qt中,将以png为格式的图片在按钮控件上显示

    在Qt编程中,我们常常会遇见这样或那样的小问题,这里,我介绍一个将png为格式的图片在按钮控件上显示的小功能. resistanceBtn = new QPushButton(element); re ...

  6. 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke

    今天关闭一个窗体,报出这样的一个错误"在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke.",这个不用多想,肯定是那个地方没有释放掉.既然碰到这个问题, ...

  7. [MFC] MFC 打开HTML资源(用ID版,也可加载到自己的web控件上)

    @ ^ @:如果是加载到web控件上,就把注释掉的解除注释(改为web控件点后面的函数),把下一句注释 BOOL Button::LoadFromResource(UINT nRes){//打开网页加 ...

  8. 安装SQL Server出现在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke的错误解决办法

    以下是错误报告:   标题: SQL Server 安装程序失败. ------------------------------   SQL Server 安装程序遇到以下错误:   在创建窗口句柄之 ...

  9. 05_android入门_GET方式实现登陆(在控件上显示服务端返回的内容)

    当点击登陆之后,怎么把server端返回的数据,写到指定的控件上尼?,在android怎么实现尼?以下我们通过详细的代码进行分析和实现,希望能对你,在学习android知识上有所帮助. 以下通过代码说 ...

随机推荐

  1. delphi调试需要管理员权限程序报错“Unable to create process:请求的操作需要提升”

    delphi调试启动需要UAC权限的程序的时候会报错“Unable to create process:请求的操作需要提升”.这是因为delphi没有以管理员身份启动,这样delphi createp ...

  2. 用c#开发微信 (18) 多客服

    微信官方的多客服接口原理是通过用户发送的信息,开发者服务器返回一条指定类型的响应信息,使用户的对话状态切换到官方的多客服状态(持续一段时间),这段时间内用户发送的所有信息都不会到达开发者的服务器,而是 ...

  3. WPF快速入门系列(4)——深入解析WPF绑定

    一.引言 WPF绑定使得原本需要多行代码实现的功能,现在只需要简单的XAML代码就可以完成之前多行后台代码实现的功能.WPF绑定可以理解为一种关系,该关系告诉WPF从一个源对象提取一些信息,并将这些信 ...

  4. 跟我一起学WCF(4)——第一个WCF程序

    一.引言 前面几篇文章分享了.NET 平台下其他几种分布式技术,然而前面几种分布式技术专注于某一特定的领域,并且具有不同编程接口,这使得开发人员需要掌握多个API的使用.基于这样的原因,微软在.NET ...

  5. 在.sln文件中设置Visual Studio默认启动项目的简单方法

    昨天在一台电脑上用git新签出一个项目进行build,却出现一堆编译错误,而在原先的开发机上build无任何错误.对比分析后发现,开发机上VS的启动项目(startup project)与这台电脑上的 ...

  6. jpa 注解使用说明

    1.@Entity(name="EntityName") 必须,name为可选,对应数据库中一的个表 2.@Table(name="",catalog=&quo ...

  7. 为什么不能把委托(delegate)放在一个接口(interface)当中?

    stackoverflow上有人问,为什么不能把委托放在一个接口当中? 投票最多的第一个答案第一句话说,“A Delegate is just another type, so you don't g ...

  8. 标签简化Spring-MVC配置

    新填入@RequestMapping标签 和@org.springframework.stereotype.Controller标签 这样做就是通过标签来简化之前,对HandlerMapping的配置 ...

  9. 深入理解JavaScript 事件

    本文总结自<JavaScript高级程序设计>以及自己平时的经验,针对较新浏览器以及 DOM3 级事件标准(2016年8月),对少部分内容作了更正,增加了各种例子及解析. 如无特殊说明,本 ...

  10. STL的string和wstring

    STL有字符串处理类——stirng和wstring,但是用的时候会觉得不是很方便,因为它不能像TCHAR一样根据定义的宏在char类型字符串和wchar_t进行转换,总不能因为程序要Unicode就 ...