之前写过一篇将cocos2dx-2.x版本集成到MFC的文章,现在到了cocos2dx-3.x版本,之前的方法已经行不通了,最近有点时间,研究了一下,算是做出来点样子,下面写一下步骤,算是做个笔记。
我采用的方案步骤很多,改动量也比较大, 对于那些期望只修改几行就能达到目的的人来说,让你们失望了-_-,但本着学习的目的,改的越多不就意味着你学的越多么:)
首先要改的不是cocos2dx,而是GLFW。原因是因为cocos2dx-3.x底层渲染是基于GLFW的,但GLFW是不支持渲染到控件的,所以要改一下它。
下载GLFW源码,地址:http://www.glfw.org/download.html
解压后用CMake生成win32工程,然后用vs打开,整个工程是这样的:
我们要修改的就是glfw这个项目。
在glfw3.h中增加函数声明
GLFWAPI GLFWwindow* glfwCreateWindowEx(void* winHwnd, int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share);
然后在window.c中实现此函数
GLFWAPI GLFWwindow* glfwCreateWindowEx(void* winHwnd, int width, int height, const char* title, GLFWmonitor* monitor, GLFWwindow* share)
{
_GLFWfbconfig fbconfig;
_GLFWctxconfig ctxconfig;
_GLFWwndconfig wndconfig;
_GLFWwindow* window;
_GLFWwindow* previous;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (width <= 0 || height <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid window size");
return NULL;
}
fbconfig = _glfw.hints.framebuffer;
ctxconfig = _glfw.hints.context;
wndconfig = _glfw.hints.window;
wndconfig.width = width;
wndconfig.height = height;
wndconfig.title = title;
wndconfig.monitor = (_GLFWmonitor*)monitor;
ctxconfig.share = (_GLFWwindow*)share;
if (wndconfig.monitor)
{
wndconfig.resizable = GL_FALSE;
wndconfig.visible = GL_TRUE;
wndconfig.focused = GL_TRUE;
}
// Check the OpenGL bits of the window config
if (!_glfwIsValidContextConfig(&ctxconfig))
return NULL;
window = calloc(1, sizeof(_GLFWwindow));
window->next = _glfw.windowListHead;
_glfw.windowListHead = window;
window->videoMode.width = width;
window->videoMode.height = height;
window->videoMode.redBits = fbconfig.redBits;
window->videoMode.greenBits = fbconfig.greenBits;
window->videoMode.blueBits = fbconfig.blueBits;
window->videoMode.refreshRate = _glfw.hints.refreshRate;
window->monitor = wndconfig.monitor;
window->resizable = wndconfig.resizable;
window->decorated = wndconfig.decorated;
window->autoIconify = wndconfig.autoIconify;
window->floating = wndconfig.floating;
window->cursorMode = GLFW_CURSOR_NORMAL;
// Save the currently current context so it can be restored later
previous = _glfwPlatformGetCurrentContext();
// Open the actual window and create its context
if (!_glfwPlatformCreateWindowEx(winHwnd, window, &wndconfig, &ctxconfig, &fbconfig))
{
glfwDestroyWindow((GLFWwindow*)window);
_glfwPlatformMakeContextCurrent(previous);
return NULL;
}
_glfwPlatformMakeContextCurrent(window);
// Retrieve the actual (as opposed to requested) context attributes
if (!_glfwRefreshContextAttribs(&ctxconfig))
{
glfwDestroyWindow((GLFWwindow*)window);
_glfwPlatformMakeContextCurrent(previous);
return NULL;
}
// Verify the context against the requested parameters
if (!_glfwIsValidContext(&ctxconfig))
{
glfwDestroyWindow((GLFWwindow*)window);
_glfwPlatformMakeContextCurrent(previous);
return NULL;
}
// Clearing the front buffer to black to avoid garbage pixels left over
// from previous uses of our bit of VRAM
glClear(GL_COLOR_BUFFER_BIT);
_glfwPlatformSwapBuffers(window);
// Restore the previously current context (or NULL)
_glfwPlatformMakeContextCurrent(previous);
if (wndconfig.monitor)
{
int width, height;
_glfwPlatformGetWindowSize(window, &width, &height);
window->cursorPosX = width / 2;
window->cursorPosY = height / 2;
_glfwPlatformSetCursorP