本文原链接: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. Asp.Net Web API 2第十四课——Content Negotiation(内容协商)

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...

  2. 在Linux CentOS 6.6上安装Python 2.7.9

    CentOS 6.6自带的是Python 2.6.6,而编译llvm需要Python 2.7以上. checking for python... /usr/bin/python checking fo ...

  3. AutoMapper在ABP框架中的使用说明

    为了说明AutoMapper如何使用,我专门开设了一个专题来讲,如果您还没有查看该专题,请点击这里.既然系统地学习了AutoMapper,那么接下来就是该用它实战的时候了.今天,我们就来揭开AutoM ...

  4. 结对实验报告-android计算器设计

     一:引言  目前手机可以说是普及率非常高的电子设备了,由于其便于携带,使用方便,资费适中等等原因,现在手机已经在一定程度开始代替固定电话的通话功能,以及一些原来电脑软件上的功能了.手机上的软件也随着 ...

  5. 实验六 序列信号检测器的VHDL设计

    一.实验目的 (1)进一步熟悉Quartus II软件和GW48-PK2S实验系统的使用方法: (2)用状态机实现序列检测器的设计,了解一般状态机的设计与应用 二.实验内容 1. 基本命题 利用Qua ...

  6. [stm32] 利用uc-gui封装画图和画线函数移植51上的模拟动画

    >_<:这里的动画是黄色矩形区域中一个模仿俯视图的起重机运作动画,一个是模仿主视图的吊钩的运动.通过改变初始Init函数中的数据b_x,b_y实现矩形区域的移动.当实时采集时要首先根据起重 ...

  7. Scala:条件表达式的好处

    条件表达式的好处之一是:让代码更简洁,例如在一个需要根据不同条件收集不同值的场景中,多数语言提供的代码如下: ; ) { tmp = xxx; } ) { tmp = yyy; } else { tm ...

  8. 微软MSDN订阅用户已可提前手工下载Windows 10安装包

    在Windows 10发布之夜,当全世界都在翘首以盼Windows 10免费发布推送的到来,MSDN订阅用户可以立马享受一项令人项目的特殊待遇:手工下载Windows 10完整安装包+免费使用的激活密 ...

  9. 带你看懂Dictionary的内部实现

    了解Dictionary的开发人员都了解,和List相比,字典添加会慢,但是查找会比较快,那么Dictionary是如何实现的呢? Dictionary的构造 下面的代码我看看Dictionary在构 ...

  10. C语言实现二叉树-03版

    我们亲爱的项目经理真是有创意,他说你给我写得二叉树挺好的: 功能还算可以:插入节点,能够删除节点: 可是有时候我们只是需要查找树的某个节点是否存在: 所以我希望你能够给我一个find功能: 还有就是, ...