本文原链接: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. Android编译错误, Ignoring InnerClasses attribute for an anonymous inner class

    今天在做android项目时,加入第三方包,一编译就报错.错误如下:[2012-01-13 14:51:25 - xxx] Dx warning: Ignoring InnerClasses attr ...

  2. 冲刺阶段 day5

    day5 项目进展 今天我们组的成员聚在一起进行了讨论,首先我们继续编写了学生管理这部分的代码,然后负责数据库的同学完成了数据库的部分,最后进行了学生管理这部分的代码复审 存在问题 因为代码不是一天之 ...

  3. 新手容易混乱的String+和StringBuffer,以及Java的方法参数传递方式。

    之前在交流群里和猿友们讨论string+和stringbuffer哪个速度快以及Java的方法参数传递的问题,引起了群里猿友的小讨论.最终LZ得出的结果是string+没有stringbuffer快, ...

  4. libevent (二) 接收TCP连接

    libevent 接收TCP连接 Evconnlistener 机制为您提供了侦听和接受传入的 TCP 连接的方法.下面的函数全部包含在`<event2/listener.h>`中. ev ...

  5. javascript 中关于对象转换数字值的一些特点

    下面是摘至<Javascript 高级程序设计第三版>里的一段话 是关于对象转换数字值的一些规则 "在应用于对象时,先调用对象的valueOf()方法以取得一个可供操作的值.然后 ...

  6. atitit.提升软件开发的效率and 质量的那些强大概念and方法总结

    atitit.提升软件开发的效率and 质量的那些强大概念and方法总结 1. 主流编程中三个最糟糕的问题 1 1.1. 从理解问题后到实现的时间很长 1 1.2. 理解和维护代码  2 1.3. 学 ...

  7. atitit.404错误的排查流程总结

    atitit.404错误的排查流程总结 #----------jsp  head  errorPage="" del zeu ok le. #------resin 服务器配置问题 ...

  8. paip。java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型

    paip.java 高级特性 类默认方法,匿名方法+多方法连续调用, 常量类型 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http ...

  9. paip.执行shell cmd 命令uapi java php python总结

    paip.执行shell cmd 命令uapi java php python总结 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:h ...

  10. Windows 10 Java环境变量配置

    Win10下 Java环境变量配置 首先,你应该已经安装了 Java 的 JDK 了(如果没有安装JDK,请跳转到此网址:http://www.oracle.com/technetwork/java/ ...