zoukankan      html  css  js  c++  java
  • 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
    ");
    78 //    printf(" %d   height: %d
    
    
    ", 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

  • 相关阅读:
    2015 ccpc 南阳国赛
    CF 812
    多校 2009 7
    2015 长春
    多校 2009 4
    selenium 对https网站(加密证书)进行自动化测试
    selenium配置
    2016.05.17开通自己的博客
    pod存在,但是deployment和statefulset不存在
    Eclipse设置代码格式化使用空格代替TAB
  • 原文地址:https://www.cnblogs.com/zouzf/p/4423256.html
Copyright © 2011-2022 走看看