本文原链接: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. 从“程序员转行卖烧饼”想到IT人创业

    我的一个朋友最近总在跟我念叨着“我不想做开发了,整天累死累活写程序,也攒不下几个钱.我想辞职搞点啥!” 我问他:“你想搞点啥?”. 他说:“搞啥都比做开发强,做个网站赚广告费,接私活……实在不行我去卖 ...

  2. ASP.NET MVC5 与EF6学习系列

    最近学习使用MVC5和EF6,博客园搜索了一番,写下这篇文章记录,以便学习使用. 一.ASP.NET MVC5 网站开发 @洞庭夕照写的博客系列 ASP.NET MVC5 网站开发实践 - 概述 AS ...

  3. 微软BI 之SSIS 系列 - 使用 Script Component Destination 和 ADO.NET 解析不规则文件并插入数据

    开篇介绍 这一篇文章是 微软BI 之SSIS 系列 - 带有 Header 和 Trailer 的不规则的平面文件输出处理技巧 的续篇,在上篇文章中介绍到了对于这种不规则文件输出的处理方式.比如下图中 ...

  4. .Net下 自动执行MSI和EXE文件

    MSI是安装文件,需要系统自带的msiexec.exe来执行 var tempDir = @"D:\UploadFiles\SCADASetupWix.msi"; var star ...

  5. 扯扯Java中Finalization的意义

    这是Stack Overflow上关于Finalizetion意义的两段讨论,这两个观点是互为补充的. 观点1: 垃圾回收器(The garbage collector)自动在后台运行(虽然它也可以被 ...

  6. 设置jenkins代理

    http://stackoverflow.com/documentation/jenkins/919/introduction-to-jenkins Natively, Jenkins runs on ...

  7. 安装 Dubbo 注册中心(Zookeeper-3.4.6)--单节点

    1.建议使用dubbo-2.3.3以上版本的使用zookeeper注册中心客户端2.Zookeeper是Apache Hadoop的子项目,强度相对较好,建议生产环境使用该注册中心.3.Dubbo未对 ...

  8. 彻底掌握this,call,apply

    说起js里面比较头疼的知识点,this的指向,call与apply的理解这三者肯定算的上前几,好的js开发者这是必须迈过的槛.今天就总结下这三者紧密相连的关系. 首先推荐理解call的用法 Funct ...

  9. 大数据并行计算利器之MPI/OpenMP

    大数据集群计算利器之MPI/OpenMP ---以连通域标记算法并行化为例 1 背景 图像连通域标记算法是从一幅栅格图像(通常为二值图像)中,将互相邻接(4邻接或8邻接)的具有非背景值的像素集合提取出 ...

  10. PHP的错误报错级别设置原理简析

    原理简析 摘录php.ini文件的默认配置(php5.4): ; Common Values: ; E_ALL (Show all errors, warnings and notices inclu ...