最近下了cocos2dx3.0版本的代码,在windows下学习了它如何绘制openGL的,看了下它的代码调用,在windows下应该是使用了glfw库来进行的openGL的绘制。这里就笔记下其部分代码调用。
备注:
作者学习cocos2dx时间不长,理解的也不是太深刻。3.0版本的就使用的更少了,可能有部分笔记是错误的,还请路过的大牛们帮忙指正一下。
AppDelegate.cpp:
部分代码修改如下:
bool AppDelegate::applicationDidFinishLaunching() { |
auto director = Director::getInstance(); |
auto glview = director->getOpenGLView(); |
glview = GLView::create( "HelloWorld" ); |
director->setOpenGLView(glview); |
#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 |
glview->setFrameSize(640,1136); |
glview->setFrameZoomFactor(0.6f); |
glview->setDesignResolutionSize(640,1136, ResolutionPolicy::SHOW_ALL); |
director->setAnimationInterval(1.0 / 60); |
auto scene = HelloWorld::createScene(); |
director->runWithScene(scene); |
分辨率适配图像如下:
当FrameSize为(640,1136),DesignResolutionSize为(640,1136,SHOW_ALL)时,如下图显示,大小正好:
当FrameSize为(800,1136),DesignResolutionSize为(640,1136,SHOW_ALL)时,如下图显示,宽了一部分,由于是【 SHOW_ALL 】模式,这是两边就有了黑边:
CCGLView.cpp:
部分代码注释如下,由于作者是在windows下阅读的代码,因此这里的CCGLView的路径为【 cocos2d\cocos\platform\desktop\CCGLView.cpp 】:
static void onGLFWError( int errorID, const char * errorDesc) |
_view->onGLFWError(errorID, errorDesc); |
static void onGLFWMouseCallBack(GLFWwindow* window, int button, int action, int modify) |
_view->onGLFWMouseCallBack(window, button, action, modify); |
static void onGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y) |
_view->onGLFWMouseMoveCallBack(window, x, y); |
static void onGLFWMouseScrollCallback(GLFWwindow* window, double x, double y) |
_view->onGLFWMouseScrollCallback(window, x, y); |
static void onGLFWKeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods) |
_view->onGLFWKeyCallback(window, key, scancode, action, mods); |
static void onGLFWCharCallback(GLFWwindow* window, unsigned int character) |
_view->onGLFWCharCallback(window, character); |
static void onGLFWWindowPosCallback(GLFWwindow* windows, int x, int y) |
_view->onGLFWWindowPosCallback(windows, x, y); |
static void onGLFWframebuffersize(GLFWwindow* window, int w, int h) |
_view->onGLFWframebuffersize(window, w, h); |
static void onGLFWWindowSizeFunCallback(GLFWwindow *window, int width, int height) |
_view->onGLFWWindowSizeFunCallback(window, width, height); |
static void setGLView(GLView* view) |
GLView* GLFWEventHandler::_view = nullptr; |
EventKeyboard::KeyCode keyCode; |
static std::unordered_map< int , EventKeyboard::KeyCode> g_keyCodeMap; |
static keyCodeItem g_keyCodeStructArray[] = { |
{ GLFW_KEY_UNKNOWN , EventKeyboard::KeyCode::KEY_NONE }, |
{ GLFW_KEY_SPACE , EventKeyboard::KeyCode::KEY_SPACE }, |
{ GLFW_KEY_MENU , EventKeyboard::KeyCode::KEY_MENU }, |
{ GLFW_KEY_LAST , EventKeyboard::KeyCode::KEY_NONE } |
, _isInRetinaMonitor( false ) |
, _isRetinaEnabled( false ) |
for (auto& item : g_keyCodeStructArray) |
g_keyCodeMap[item.glfwKeyCode] = item.keyCode; |
GLFWEventHandler::setGLView( this ); |
glfwSetErrorCallback(GLFWEventHandler::onGLFWError); |
CCLOGINFO( "deallocing GLView: %p" , this ); |
GLFWEventHandler::setGLView(nullptr); |
GLView* GLView::create( const std::string& viewName) |
if (ret && ret->initWithRect(viewName, Rect(0, 0, 960, 640), 1)) { |
GLView* GLView::createWithRect( const std::string& viewName, Rect rect, float frameZoomFactor) |
if (ret && ret->initWithRect(viewName, rect, frameZoomFactor)) { |
GLView* GLView::createWithFullScreen( const std::string& viewName) |
if (ret && ret->initWithFullScreen(viewName)) { |
GLView* GLView::createWithFullScreen( const std::string& viewName, const GLFWvidmode &videoMode, GLFWmonitor *monitor) |
if (ret && ret->initWithFullscreen(viewName, videoMode, monitor)) { |
bool GLView::initWithRect( const std::string& viewName, Rect rect, float frameZoomFactor) |
_frameZoomFactor = frameZoomFactor; |
glfwWindowHint(GLFW_RESIZABLE,GL_FALSE); |
_mainWindow = glfwCreateWindow(rect.size.width * _frameZoomFactor, |
rect.size.height * _frameZoomFactor, |
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); |
setFrameSize(rect.size.width, rect.size.height); |
const GLubyte* glVersion = glGetString(GL_VERSION); |
if ( atof (( const char *)glVersion) < 1.5 ) |
char strComplain[256] = {0}; |
"OpenGL 1.5 or higher is required (your version is %s). Please upgrade the driver of your video card." , |
MessageBox(strComplain, "OpenGL version too old" ); |
glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); |
bool GLView::initWithFullScreen( const std::string& viewName) |
_monitor = glfwGetPrimaryMonitor(); |
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) |
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); |
bool GLView::isOpenGLReady() |
return nullptr != _mainWindow; |
glfwSetWindowShouldClose(_mainWindow,1); |
void GLView::swapBuffers() |
glfwSwapBuffers(_mainWindow); |
bool GLView::windowShouldClose() |
return glfwWindowShouldClose(_mainWindow) ? true : false ; |
void GLView::pollEvents() |
void GLView::enableRetina( bool enabled) |
#if (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) |
_isRetinaEnabled = enabled; |
void GLView::setIMEKeyboardState( bool ) |
void GLView::setFrameZoomFactor( float zoomFactor) |
CCASSERT(zoomFactor > 0.0f, "zoomFactor must be larger than 0" ); |
if ( fabs (_frameZoomFactor - zoomFactor) < FLT_EPSILON) |
_frameZoomFactor = zoomFactor; |
float GLView::getFrameZoomFactor() |
void GLView::updateFrameSize() |
if (_screenSize.width > 0 && _screenSize.height > 0) |
glfwGetWindowSize(_mainWindow, &w, &h); |
int frameBufferW = 0, frameBufferH = 0; |
glfwGetFramebufferSize(_mainWindow, &frameBufferW, &frameBufferH); |
if (frameBufferW == 2 * w && frameBufferH == 2 * h) |
glfwSetWindowSize(_mainWindow, _screenSize.width/2 * _retinaFactor * _frameZoomFactor, _screenSize.height/2 * _retinaFactor * _frameZoomFactor); |
_isInRetinaMonitor = true ; |
glfwSetWindowSize(_mainWindow, _screenSize.width * _retinaFactor * _frameZoomFactor, _screenSize.height *_retinaFactor * _frameZoomFactor); |
_isInRetinaMonitor = false ; |
void GLView::setFrameSize( float width, float height) |
GLViewProtocol::setFrameSize(width, height); |
void GLView::setViewPortInPoints( float x , float y , float w , float h) |
glViewport((GLint)(x * _scaleX * _retinaFactor * _frameZoomFactor + _viewPortRect.origin.x * _retinaFactor * _frameZoomFactor), |
(GLint)(y * _scaleY * _retinaFactor * _frameZoomFactor + _viewPortRect.origin.y * _retinaFactor * _frameZoomFactor), |
(GLsizei)(w * _scaleX * _retinaFactor * _frameZoomFactor), |
(GLsizei)(h * _scaleY * _retinaFactor * _frameZoomFactor)); |
void GLView::setScissorInPoints( float x , float y , float w , float h) |
glScissor((GLint)(x * _scaleX * _retinaFactor * _frameZoomFactor + _viewPortRect.origin.x * _retinaFactor * _frameZoomFactor), |
(GLint)(y * _scaleY * _retinaFactor * _frameZoomFactor + _viewPortRect.origin.y * _retinaFactor * _frameZoomFactor), |
(GLsizei)(w * _scaleX * _retinaFactor * _frameZoomFactor), |
(GLsizei)(h * _scaleY * _retinaFactor * _frameZoomFactor)); |
void GLView::onGLFWError( int errorID, const char * errorDesc) |
CCLOGERROR( "GLFWError #%d Happen, %s\n" , errorID, errorDesc); |
void GLView::onGLFWMouseCallBack(GLFWwindow* window, int button, int action, int modify) |
if (GLFW_MOUSE_BUTTON_LEFT == button) |
if ( this ->getViewPortRect().equals(Rect::ZERO) || this ->getViewPortRect().containsPoint(Vec2(_mouseX,_mouseY))) |
this ->handleTouchesBegin(1, &id, &_mouseX, &_mouseY); |
else if (GLFW_RELEASE == action) |
this ->handleTouchesEnd(1, &id, &_mouseX, &_mouseY); |
EventMouse event(EventMouse::MouseEventType::MOUSE_DOWN); |
event.setCursorPosition(_mouseX, this ->getViewPortRect().size.height - _mouseY); |
event.setMouseButton(button); |
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event); |
else if (GLFW_RELEASE == action) |
EventMouse event(EventMouse::MouseEventType::MOUSE_UP); |
event.setCursorPosition(_mouseX, this ->getViewPortRect().size.height - _mouseY); |
event.setMouseButton(button); |
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event); |
void GLView::onGLFWMouseMoveCallBack(GLFWwindow* window, double x, double y) |
_mouseX /= this ->getFrameZoomFactor(); |
_mouseY /= this ->getFrameZoomFactor(); |
this ->handleTouchesMove(1, &id, &_mouseX, &_mouseY); |
EventMouse event(EventMouse::MouseEventType::MOUSE_MOVE); |
event.setCursorPosition(_mouseX, this ->getViewPortRect().size.height - _mouseY); |
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event); |
void GLView::onGLFWMouseScrollCallback(GLFWwindow* window, double x, double y) |
EventMouse event(EventMouse::MouseEventType::MOUSE_SCROLL); |
event.setScrollData(( float )x, -( float )y); |
event.setCursorPosition(_mouseX, this ->getViewPortRect().size.height - _mouseY); |
Director::getInstance()->getEventDispatcher()->dispatchEvent(&event); |
void GLView::onGLFWKeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods) |
if (GLFW_REPEAT != action) |
EventKeyboard event(g_keyCodeMap[key], GLFW_PRESS == action); |
auto dispatcher = Director::getInstance()->getEventDispatcher(); |
dispatcher->dispatchEvent(&event); |
void GLView::onGLFWCharCallback(GLFWwindow *window, unsigned int character) |
IMEDispatcher::sharedDispatcher()->dispatchInsertText(( const char *) &character, 1); |
void GLView::onGLFWWindowPosCallback(GLFWwindow *windows, int x, int y) |
Director::getInstance()->setViewport(); |
void GLView::onGLFWframebuffersize(GLFWwindow* window, int w, int h) |
float frameSizeW = _screenSize.width; |
float frameSizeH = _screenSize.height; |
float factorX = frameSizeW / w * _retinaFactor * _frameZoomFactor; |
float factorY = frameSizeH / h * _retinaFactor * _frameZoomFactor; |
if ( fabs (factorX - 0.5f) < FLT_EPSILON && fabs (factorY - 0.5f) < FLT_EPSILON ) |
_isInRetinaMonitor = true ; |
glfwSetWindowSize(window, static_cast < int >(frameSizeW * 0.5f * _retinaFactor * _frameZoomFactor) , static_cast < int >(frameSizeH * 0.5f * _retinaFactor * _frameZoomFactor)); |
else if ( fabs (factorX - 2.0f) < FLT_EPSILON && fabs (factorY - 2.0f) < FLT_EPSILON) |
_isInRetinaMonitor = false ; |
glfwSetWindowSize(window, static_cast < int >(frameSizeW * _retinaFactor * _frameZoomFactor), static_cast < int >(frameSizeH * _retinaFactor * _frameZoomFactor)); |
void GLView::onGLFWWindowSizeFunCallback(GLFWwindow *window, int width, int height) |
if (_resolutionPolicy != ResolutionPolicy::UNKNOWN) |
updateDesignResolutionSize(); |
Director::getInstance()->setViewport(); |
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) |
static bool glew_dynamic_binding() |
const char *gl_extensions = ( const char *)glGetString(GL_EXTENSIONS); |
if (glGenFramebuffers == NULL) |
log ( "OpenGL: glGenFramebuffers is NULL, try to detect an extension" ); |
if ( strstr (gl_extensions, "ARB_framebuffer_object" )) |
log ( "OpenGL: ARB_framebuffer_object is supported" ); |
glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) wglGetProcAddress( "glIsRenderbuffer" ); |
glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) wglGetProcAddress( "glGenerateMipmap" ); |
if ( strstr (gl_extensions, "EXT_framebuffer_object" )) |
log ( "OpenGL: EXT_framebuffer_object is supported" ); |
glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) wglGetProcAddress( "glIsRenderbufferEXT" ); |
glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) wglGetProcAddress( "glGenerateMipmapEXT" ); |
log ( "OpenGL: No framebuffers extension is supported" ); |
log ( "OpenGL: Any call to Fbo will crash!" ); |
#if (CC_TARGET_PLATFORM != CC_PLATFORM_MAC) |
GLenum GlewInitResult = glewInit(); |
if (GLEW_OK != GlewInitResult) |
MessageBox(( char *)glewGetErrorString(GlewInitResult), "OpenGL error" ); |
if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader) |
log ( "Not totally ready :(" ); |
if (glewIsSupported( "GL_VERSION_2_0" )) |
log ( "Ready for OpenGL 2.0" ); |
log ( "OpenGL 2.0 not supported" ); |
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) |
if (glew_dynamic_binding() == false ) |
MessageBox( "No OpenGL framebuffer support. Please upgrade the driver of your video card." , "OpenGL error" ); |
#endif // (CC_TARGET_PLATFORM != CC_PLATFORM_MAC) |
这里我们再看一下GLView的继承关系:
class CC_DLL GLView : public GLViewProtocol, public Ref |
这里【 Ref 】是用来管理引用计数的。
这里【 GLViewProtocol 】是一个基类,各个平台下会对其进行继承,继承之后的名称都为GLView。
这里就不对这两个类进行笔记了,以后再笔记吧。