自己动手写cocos2dx游戏引擎(四)——窗体GLView

时间:2022-04-08 12:11:08

上一节中我们获取到了Director对象。

通过这个对象我们可以获取到一个OpenGL的一个视图。

在定义GLview之前,我们需要定义一个常用几何头文件。

// Geometry.h

#ifndef __GEMMETRY_H__
#define __GEMMETRY_H__

class Size {
public:
Size() {}
Size(float width, float height) {
this->width = width;
this->height = height;
}

float width;
float height;
};

class Vec2 {
public:
Vec2() {}
Vec2(float x, float y) {
this->x = x;
this->y = y;
}
float x;
float y;
};

class Rect {
public:
Rect() {}
Rect(float x, float y, float width, float height) {
origin.x = x;
origin.y = y;

size.width = width;
size.height = height;
}
Vec2 origin;
Size size;
};

#endif
这个头文件中定义的Size和Vec2,都是为定义矩形Rect服务的,分别表示长宽和原点。

// GLView.h

#ifndef __GLVIEW_H__                                                                                                  
#define __GLVIEW_H__

#include "Geometry.h"

class GLView {
public:
virtual ~GLView() {}
virtual void setViewName(const std::string& viewname) {
_viewName = viewname;
}
virtual void setFrameSize(float width, float height) {
_designResolutionSize = _screenSize = Size(width, height);
}
protected:
std::string _viewName;
Size _designResolutionSize;
Size _screenSize;
};

#endif

在GLView中定义了三个属性,一个表示窗口的标题名称,两个尺寸都是窗口的大小,后面做屏幕大小适配的时候可以用到。

在APPDelegate中获取的并不是GLView的对象,而是它的子类对象GLViewImpl

#ifndef __GLVIEWIMPL_H__                                                                                              
#define __GLVIEWIMPL_H__

#include "GLView.h"

class GLViewImpl: public GLView {
public:
static GLViewImpl* createWithRect(const std::string& viewName, Rect rect);
bool initWithRect(const std::string& viewName, Rect rect);
};

GLViewImpl* GLViewImpl::createWithRect(const std::string& viewName, Rect rect) {
GLViewImpl* ret = new GLViewImpl;
if (ret && ret->initWithRect(viewName, rect)) {
// ret->autorelease;// 后面再看内存管理
return ret;
}
if (ret != NULL) {
delete ret;
ret = NULL;
}
return NULL;
}

bool GLViewImpl::initWithRect(const std::string& viewName, Rect rect) {
setViewName(viewName);
setFrameSize(rect.size.width, rect.size.height);
}

#endif

其中涉及到了一个自动释放的功能,是关于内存管理的,后面再看内存管理的内容。

然后在AppDelegate中调用时,判断当前窗口是否存在,不存在就创建一个:

#ifndef __APP_DELEGATE_H__
#define __APP_DELEGATE_H__

#include "Application.h"
#include "Director.h"
#include "GLView.h"
#include "GLViewImpl.h"
#include "Geometry.h"

#include <iostream>

class AppDelegate: private Application {
public:
virtual bool applicationDidFinishLaunching() {
Director* director = Director::getInstance();
GLView* glview = director->getOpenGLView();
if (!glview) {
glview = GLViewImpl::createWithRect("WinName", Rect(0, 0, 960, 640));
director->setOpenGLView(glview);
}
return true;
}
};

#endif


并在Director中将其设置为当前的视图窗口。

#ifndef __DIRECTOR_H__                                                                                                
#define __DIRECTOR_H__

#include "GLView.h"

class Director {
public:
Director() {
_openGLView = NULL;
}
virtual ~Director() {}
static Director* getInstance();
GLView* getOpenGLView() { return _openGLView; }
virtual bool init(){ return true; }
void setOpenGLView(GLView *openGLView) {
if (_openGLView != openGLView) {
if (_openGLView) {
// 释放已经存在的视图对象, 后面再看
}
_openGLView = openGLView;
}
}
private:
GLView *_openGLView;
};

class DisplayLinkDirector : public Director {
public:

};

static DisplayLinkDirector *s_SharedDirector = NULL;

Director* Director::getInstance()
{
if (!s_SharedDirector) {
s_SharedDirector = new DisplayLinkDirector;
s_SharedDirector->init();
}
return s_SharedDirector;
}

#endif

实际上到这一步就启动流程已经完成,如果在cocos2dx的项目中,就可以看到一个黑色的窗口,另外还有场景和消息循环没有加进来。


附代码:demo4