Cocos2dx 把 glview 渲染到 Qt 控件上(Mac 环境)

本文原链接: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/5/Headers
qt/QtCore.framework/Versions/5/Headers
qt/QtGui.framework/Versions/5/Headers
qt/QtOpenGL.framework/Versions/5/Headers

 

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

 1 #ifndef WGLWIDGET_H
 2 #define WGLWIDGET_H
 3 
 4 #include <QWidget>
 5 #include <QtOpenGL>
 6 #include "EAGLView.h"
 7 
 8 class WGLWidget : public QWidget
 9 {
10 
11 public:
12     WGLWidget(QWidget *parent = 0);
13     ~WGLWidget();
14     
15 private:
16     EAGLView* _glView;
17     NSWindow* _NSWindow;
18     int glviewWidth;
19     int glviewHeight;
20     
21 protected:
22     
23     virtual void mouseDoubleClickEvent(QMouseEvent *event);
24     virtual void closeEvent(QCloseEvent *event);
25     virtual void resizeEvent(QResizeEvent *event);
26 
27 
28 };
29 
30 #endif // WGLWIDGET_H

 

 1 #include "wglwidget.h"
 2 #import "AppDelegate.h"
 3 
 4 
 5 static AppDelegate s_sharedApplication;
 6 
 7 WGLWidget::WGLWidget(QWidget *parent /* = 0 */): QWidget(parent)
 8 {
 9     this->glviewWidth = 480;
10     this->glviewHeight = 320;
11     
12     setMinimumSize(this->glviewWidth, this->glviewHeight);
13     setWindowTitle("HelloCpp");
14     setStyleSheet("background:green");
15     
16    
17     //以下设置参考自:AppController。mm
18     NSRect rect = NSMakeRect(0, 0, this->glviewWidth, this->glviewHeight);
19 
20     _NSWindow = [[NSWindow alloc] initWithContentRect:rect
21                                          styleMask:(NSBorderlessWindowMask )
22                                            backing:NSBackingStoreBuffered
23                                              defer:YES];
24     
25     [_NSWindow setBackgroundColor:[NSColor redColor]];
26     NSOpenGLPixelFormatAttribute attributes[] = {
27         NSOpenGLPFADoubleBuffer,
28         NSOpenGLPFADepthSize, 24,
29         NSOpenGLPFAStencilSize, 8,
30         0
31     };
32     
33     NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease];
34     
35     _glView = [[EAGLView alloc] initWithFrame:rect pixelFormat:pixelFormat];
36 
37     [_glView reshape];
38     
39     // set window parameters
40     [_NSWindow becomeFirstResponder];
41     [_NSWindow setContentView:_glView];
42     [_NSWindow setAcceptsMouseMovedEvents:NO];    
43 
44     
45 
46     //通过 EAGLView* 对象来创建 QWindow,然后根据 QWindow 对象来创建 QWidget
47     QWindow* _glWindow = QWindow::fromWinId((WId) _glView);
48     QWidget* _glWidget = QWidget::createWindowContainer(_glWindow, parent);
49 
50     _glWidget->setParent(this);
51     _glWidget->resize(this->glviewWidth, this->glviewHeight);
52    
53     
54     cocos2d::CCApplication::sharedApplication()->run();
55     
56 }
57 
58 WGLWidget::~WGLWidget()
59 {
60     
61 }
62 
63 
64 void WGLWidget::mouseDoubleClickEvent(QMouseEvent *event)
65 {
66     if(windowState() & Qt::WindowFullScreen)
67         showNormal();
68     else
69         showFullScreen();
70 }
71 
72 
73 
74 void WGLWidget::resizeEvent(QResizeEvent *event)
75 {
76     QSize size  = event->size();
77 //    printf("resizeEvent\n");
78 //    printf("width: %d   height: %d\n\n\n", size.width(), size.height());
79     
80     //重绘 NSWindow 和 GLView 窗口
81     NSRect rect = NSMakeRect(0, 0, size.width(), size.height());
82     [_NSWindow setFrame:rect display:YES animate:NO];
83     
84     cocos2d::CCEGLView* glView = cocos2d::CCEGLView::sharedOpenGLView();
85     glView->setFrameSize(size.width(), size.height());//
86     glView->setDesignResolutionSize(this->glviewWidth, this->glviewHeight, kResolutionShowAll);
87     
88 }
89 
90 
91 
92 void WGLWidget::closeEvent(QCloseEvent *event)
93 {
94     QWidget::closeEvent(event);
95 }

 

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

 1 //#import <Cocoa/Cocoa.h>
 2 #include <QApplication>
 3 #include "WGLWidget.h"
 4 
 5 int main(int argc, char *argv[])
 6 {
 7     QApplication app(argc, argv);
 8     
 9     WGLWidget mainWindow;
10     mainWindow.show();
11     app.installEventFilter(&mainWindow);
12     return app.exec();
13     
14     //return NSApplicationMain(argc, (const char **)argv);
15 }

 

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

 

posted @ 2015-04-14 10:23  仙外仙  阅读(2379)  评论(0编辑  收藏  举报