CCGLView.cpp: 部分代码注释如下,由于作者是在windows下阅读的代码,因此这里的CCGLView的路径为【 cocos2d\cocos\platform\desktop\CCGLView.cpp 】: // GLFWEventHandler /* 定义了一个管理GL回调函数的结构
CCGLView.cpp:
部分代码注释如下,由于作者是在windows下阅读的代码,因此这里的CCGLView的路径为【 cocos2d\cocos\platform\desktop\CCGLView.cpp 】:
// GLFWEventHandler
/*
定义了一个管理GL回调函数的结构体,里面所有的函数都是静态的,由于是结构体,因此也全部都是默认public的,
这样便于管理,即这里的所有的函数都是用来处理openGL的回调的。
同时,这里所有的函数都没有实际的处理逻辑,全部是调用的GLView的函数,通过这种方式就可以通过编译时的函数指针检查
*/
class
GLFWEventHandler
{
public
:
static
void
onGLFWError(
int
errorID,
const
char
* errorDesc)
{
if
(_view)
_view->onGLFWError(errorID, errorDesc);
}
static
void
onGLFWMouseCallBack(GLFWwindow* window,
int
button,
int
action,
int
modify)
{
if
(_view)
_view->onGLFWMouseCallBack(window, button, action, modify);
}
static
void
onGLFWMouseMoveCallBack(GLFWwindow* window,
double
x,
double
y)
{
if
(_view)
_view->onGLFWMouseMoveCallBack(window, x, y);
}
static
void
onGLFWMouseScrollCallback(GLFWwindow* window,
double
x,
double
y)
{
if
(_view)
_view->onGLFWMouseScrollCallback(window, x, y);
}
static
void
onGLFWKeyCallback(GLFWwindow* window,
int
key,
int
scancode,
int
action,
int
mods)
{
if
(_view)
_view->onGLFWKeyCallback(window, key, scancode, action, mods);
}
static
void
onGLFWCharCallback(GLFWwindow* window, unsigned
int
character)
{
if
(_view)
_view->onGLFWCharCallback(window, character);
}
static
void
onGLFWWindowPosCallback(GLFWwindow* windows,
int
x,
int
y)
{
if
(_view)
_view->onGLFWWindowPosCallback(windows, x, y);
}
static
void
onGLFWframebuffersize(GLFWwindow* window,
int
w,
int
h)
{
if
(_view)
_view->onGLFWframebuffersize(window, w, h);
}
static
void
onGLFWWindowSizeFunCallback(GLFWwindow *window,
int
width,
int
height)
{
if
(_view)
_view->onGLFWWindowSizeFunCallback(window, width, height);
}
/*
通过这个函数和下面的静态私有变量,来给结构体中的_view赋值。
*/
static
void
setGLView(GLView* view)
{
_view = view;
}
private
:
static
GLView* _view;
};
//结构体静态变量初始化
GLView* GLFWEventHandler::_view = nullptr;
////////////////////////////////////////////////////
struct
keyCodeItem
{
int
glfwKeyCode;
EventKeyboard::KeyCode keyCode;
};
static
std::unordered_map<
int
, EventKeyboard::KeyCode> g_keyCodeMap;
static
keyCodeItem g_keyCodeStructArray[] = {
/* The unknown key */
{ GLFW_KEY_UNKNOWN , EventKeyboard::KeyCode::KEY_NONE },
/* Printable keys */
{ GLFW_KEY_SPACE , EventKeyboard::KeyCode::KEY_SPACE },
。。。。。
。。。。。
{ GLFW_KEY_MENU , EventKeyboard::KeyCode::KEY_MENU },
{ GLFW_KEY_LAST , EventKeyboard::KeyCode::KEY_NONE }
};
//////////////////////////////////////////////////////////////////////////
// implement GLView
//////////////////////////////////////////////////////////////////////////
/* 默认构造函数 */
GLView::GLView()
: _captured(
false
)
, _supportTouch(
false
)
, _isInRetinaMonitor(
false
)
, _isRetinaEnabled(
false
)
, _retinaFactor(1)
, _frameZoomFactor(1.0f)
, _mainWindow(nullptr)
, _monitor(nullptr)
//monitor默认是nullptr
, _mouseX(0.0f)
, _mouseY(0.0f)
{
_viewName =
"cocos2dx"
;
//先暂时命名GL窗口为cocos2dx
g_keyCodeMap.clear();
//将键盘码映射到map中
for
(auto& item : g_keyCodeStructArray)
{
g_keyCodeMap[item.glfwKeyCode] = item.keyCode;
}
//设置好回调函数的调用实例
GLFWEventHandler::setGLView(
this
);
//注册回调函数
glfwSetErrorCallback(GLFWEventHandler::onGLFWError);
//初始化GLFW
glfwInit();
}
//析构函数
GLView::~GLView()
{
CCLOGINFO(
"deallocing GLView: %p"
,
this
);
//日志
GLFWEventHandler::setGLView(nullptr);
//干掉回调函数响应
glfwTerminate();
//关闭GLFW
}
//create函数,默认大小为960X640
GLView* GLView::create(
const
std::string& viewName)
{
auto ret =
new
GLView;
if
(ret && ret->initWithRect(viewName, Rect(0, 0, 960, 640), 1)) {
ret->autorelease();
return
ret;
}
return
nullptr;
}
//create函数
GLView* GLView::createWithRect(
const
std::string& viewName, Rect rect,
float
frameZoomFactor)
{
auto ret =
new
GLView;
if
(ret && ret->initWithRect(viewName, rect, frameZoomFactor)) {
ret->autorelease();
return
ret;
}
return
nullptr;
}
//create函数 全屏大小
GLView* GLView::createWithFullScreen(
const
std::string& viewName)
{
auto ret =
new
GLView();
if
(ret && ret->initWithFullScreen(viewName)) {
ret->autorelease();
return
ret;
}
return
nullptr;
}
//create函数 全屏大小
GLView* GLView::createWithFullScreen(
const
std::string& viewName,
const
GLFWvidmode &videoMode, GLFWmonitor *monitor)
{
auto ret =
new
GLView();
if
(ret && ret->initWithFullscreen(viewName, videoMode, monitor)) {
ret->autorelease();
return
ret;
}
return
nullptr;
}
//初始化函数
bool
GLView::initWithRect(
const
std::string& viewName, Rect rect,
float
frameZoomFactor)
{
//更新下_viewName变量
setViewName(viewName);
//更新下缩放整体缩放系数
_frameZoomFactor = frameZoomFactor;
//在调用 glfwCreateWindow 前更新glfw的属性
glfwWindowHint(GLFW_RESIZABLE,GL_FALSE);
//调用 glfwCreateWindow,创建窗口
_mainWindow = glfwCreateWindow(rect.size.width * _frameZoomFactor,
rect.size.height * _frameZoomFactor,
_viewName.c_str(),
_monitor,
nullptr);
//切换为当前上下文
glfwMakeContextCurrent(_mainWindow);
//将当前上下文的回调函数全部注册好
glfwSetMouseButtonCallback(_mainWindow, GLFWEventHandler::onGLFWMouseCallBack);
glfwSetCursorPosCallback(_mainWindow, GLFWEventHandler::onGLFWMouseMoveCallBack);
glfwSetScrollCallback(_mainWindow, GLFWEventHandler::onGLFWMouseScrollCallback);
glfwSetCharCallback(_mainWindow, GLFWEventHandler::onGLFWCharCallback);
glfwSetKeyCallback(_mainWindow, GLFWEventHandler::onGLFWKeyCallback);
glfwSetWindowPosCallback(_mainWindow, GLFWEventHandler::onGLFWWindowPosCallback);
glfwSetFramebufferSizeCallback(_mainWindow, GLFWEventHandler::onGLFWframebuffersize);
glfwSetWindowSizeCallback(_mainWindow, GLFWEventHandler::onGLFWWindowSizeFunCallback);
//更新FrameSize大小,这里的FrameSize其实就是windows下游戏窗口的大小
setFrameSize(rect.size.width, rect.size.height);
//检查版本号码
// check OpenGL version at first
const
GLubyte* glVersion = glGetString(GL_VERSION);
if
(
atof
((
const
char
*)glVersion) < 1.5 )
{
char
strComplain[256] = {0};
sprintf
(strComplain,
"OpenGL 1.5 or higher is required (your version is %s). Please upgrade the driver of your video card."
,
glVersion);
MessageBox(strComplain,
"OpenGL version too old"
);
return
false
;
}
//初始化Glew
initGlew();
//允许设置点的大小
// Enable point size by default.
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);
return
true
;
}
bool
GLView::initWithFullScreen(
const
std::string& viewName)
{
//首先获取当前的主显示器
//Create fullscreen window on primary monitor at its current video mode.
_monitor = glfwGetPrimaryMonitor();
if
(nullptr == _monitor)
return
false
;
//然后根据当前的主显示器,获取当前显示器的宽 高 颜色位宽 等信息
const
GLFWvidmode* videoMode = glfwGetVideoMode(_monitor);
//根据显示器的宽高初始化
return
initWithRect(viewName, Rect(0, 0, videoMode->width, videoMode->height), 1.0f);
}
bool
GLView::initWithFullscreen(
const
std::string &viewname,
const
GLFWvidmode &videoMode, GLFWmonitor *monitor)
{
//Create fullscreen on specified monitor at the specified video mode.
_monitor = monitor;
if
(nullptr == _monitor)
return
false
;
//These are soft contraints. If the video mode is retrieved at runtime, the resulting window and context should match these exactly. If invalid attribs are passed (eg. from an outdated cache), window creation will NOT fail but the actual window/context may differ.
glfwWindowHint(GLFW_REFRESH_RATE, videoMode.refreshRate);
glfwWindowHint(GLFW_RED_BITS, videoMode.redBits);
glfwWindowHint(GLFW_BLUE_BITS, videoMode.blueBits);
glfwWindowHint(GLFW_GREEN_BITS, videoMode.greenBits);
return
initWithRect(viewname, Rect(0, 0, videoMode.width, videoMode.height), 1.0f);
}
//检查GLEW是否就绪,通过判断窗口是否创建好