GLView是cocos2d-x基于OpenGL ES的调用封装UI库。
OpenGL本身是跨平台的计算机图形实现API,在每个平台的具体实现是不一样。所以每次使用之前先要初始化,去设置平台相关的信息。下面以win32的平台实现去分析:首先进入win32程序实现的入口文件:
bool AppDelegate::applicationDidFinishLaunching() { // initialize director auto director = Director::getInstance(); auto glview = director->getOpenGLView(); if(!glview) { glview = GLView::create("My Game"); //创建GL对象 director->setOpenGLView(glview); } // turn on display FPS director->setDisplayStats(true); // set FPS. the default value is 1.0/60 if you don't call this director->setAnimationInterval(1.0 / 60); // create a scene. it's an autorelease object auto scene = HelloWorld::createScene(); // run director->runWithScene(scene); return true; }
GLView* GLView::create(const std::string& viewName) { auto ret = new GLView; if(ret && ret->initWithRect(viewName, Rect(0, 0, 960, 640), 1)) {//3.2之后,win32的窗口应该实在这里改,Android和其他平台也有类似的文件文件 ret->autorelease(); return ret; } return nullptr; }
bool GLView::initWithRect(const std::string& viewName, Rect rect, float frameZoomFactor) { setViewName(viewName);//窗口名字 _frameZoomFactor = frameZoomFactor;//基础深度值,即Z轴 glfwWindowHint(GLFW_RESIZABLE,GL_FALSE); //这句我也没看懂,求教
<span style="font-family: Arial, Helvetica, sans-serif;">/*</span>win32注册窗口,这个就是真正的窗口,为什么之前说cocos2d的程序是单窗口单线程,这里是就明白了,我们只使用单例Director,永远只管理一个窗口<pre name="code" class="cpp">_mainWindow <span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">*/</span>
_mainWindow = glfwCreateWindow(rect.size.width * _frameZoomFactor, rect.size.height * _frameZoomFactor, _viewName.c_str(), _monitor, nullptr); glfwMakeContextCurrent(_mainWindow);//设置为当前画布(Contex也有翻译为上下文、文本) glfwSetMouseButtonCallback(_mainWindow, GLFWEventHandler::onGLFWMouseCallBack);//鼠标的相关事件监听,在移动平台则应该是Touch began end 、focus(切换屏幕或应用会触发) glfwSetCursorPosCallback(_mainWindow, GLFWEventHandler::onGLFWMouseMoveCallBack);//拖动回调注册 glfwSetScrollCallback(_mainWindow, GLFWEventHandler::onGLFWMouseScrollCallback);//滚屏事件注册,平时我们拖动TableView时就是由这个进行直接回调 glfwSetCharCallback(_mainWindow, GLFWEventHandler::onGLFWCharCallback);//字符输入事件回调
</pre><pre code_snippet_id="498510" snippet_file_name="blog_20141027_8_222555" name="code" class="cpp"><pre name="code" class="cpp">/*
The key functions deal with physical keys, with layout independent * [key tokens](@ref keys) named after their values in the standard US keyboard * layout. If you want to input text, use the * [character callback](@ref glfwSetCharCallback) instead. glfwSetWindowPosCallback(_mainWindow, GLFWEventHandler::onGLFWWindowPosCallback); glfwSetFramebufferSizeCallback(_mainWindow, GLFWEventHandler::onGLFWframebuffersize); glfwSetWindowSizeCallback(_mainWindow, GLFWEventHandler::onGLFWWindowSizeFunCallback); setFrameSize(rect.size.width, rect.size.height);
*/
/*以上是原Api声明,实际意思:所有的物理键盘按键操作都会由这个触发,但是虚拟键盘的实现我还不清楚,应该是通过前面的MouseButton来之后调用CharCallback实现*/glfwSetKeyCallback(_mainWindow, GLFWEventHandler::onGLFWKeyCallback);
</pre><pre code_snippet_id="498510" snippet_file_name="blog_20141027_13_8640418" name="code" class="cpp">glfwSetWindowPosCallback(_mainWindow, GLFWEventHandler::onGLFWWindowPosCallback); //屏幕拖动事件回调,在wp8和相关平台实现才需要 glfwSetFramebufferSizeCallback(_mainWindow, GLFWEventHandler::onGLFWframebuffersize);//帧缓存大小设置?谁知道细节 glfwSetWindowSizeCallback(_mainWindow, GLFWEventHandler::onGLFWWindowSizeFunCallback); //窗口大小的设置目前在移动设备上是没有这个相关接口,win32和mac才有
</pre><pre code_snippet_id="498510" snippet_file_name="blog_20141027_15_8563971" name="code" class="cpp"> // check OpenGL version at first const GLubyte* glVersion = glGetString(GL_VERSION); if ( utils::atof((const char*)glVersion) < 1.5 ) //opengl1.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; } initGlew(); // Enable point size by default. glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); return true; }
跳转
// helper bool GLView::initGlew() { #if (CC_TARGET_PLATFORM != CC_PLATFORM_MAC) GLenum GlewInitResult = glewInit();//OpenGL库固定初始化函数。 if (GLEW_OK != GlewInitResult) { MessageBox((char *)glewGetErrorString(GlewInitResult), "OpenGL error"); return false; } if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader) { log("Ready for GLSL"); } else { log("Not totally ready :("); } if (glewIsSupported("GL_VERSION_2_0")) { log("Ready for OpenGL 2.0"); } else { log("OpenGL 2.0 not supported"); } #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) if(glew_dynamic_binding() == false) //OpenGL是一个单独的状态机,需要使用window OpenGL的api去完成硬件绑定。用设计模式的思想可以当做OpenGL是个策略模式中的策略,而window OpenGL则是提供策略支持具体实现。<span style="font-family: Arial, Helvetica, sans-serif;">window OpenGL</span><span style="font-family: Arial, Helvetica, sans-serif;">同时的代理(window os才是真正去管理硬件的总代理) wgl的细节我也不熟,就此搁置</span> { MessageBox("No OpenGL framebuffer support. Please upgrade the driver of your video card.", "OpenGL error"); return false; } #endif #endif // (CC_TARGET_PLATFORM != CC_PLATFORM_MAC) return true; }
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) static bool glew_dynamic_binding() { const char *gl_extensions = (const char*)glGetString(GL_EXTENSIONS); // If the current opengl driver doesn't have framebuffers methods, check if an extension exists if (glGenFramebuffers == nullptr) { log("OpenGL: glGenFramebuffers is nullptr, try to detect an extension"); if (strstr(gl_extensions, "ARB_framebuffer_object")) { log("OpenGL: ARB_framebuffer_object is supported"); glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) wglGetProcAddress("glIsRenderbuffer"); glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) wglGetProcAddress("glBindRenderbuffer"); glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) wglGetProcAddress("glDeleteRenderbuffers"); glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) wglGetProcAddress("glGenRenderbuffers"); glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) wglGetProcAddress("glRenderbufferStorage"); glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) wglGetProcAddress("glGetRenderbufferParameteriv"); glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) wglGetProcAddress("glIsFramebuffer"); glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) wglGetProcAddress("glBindFramebuffer"); glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) wglGetProcAddress("glDeleteFramebuffers"); glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) wglGetProcAddress("glGenFramebuffers"); glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) wglGetProcAddress("glCheckFramebufferStatus"); glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) wglGetProcAddress("glFramebufferTexture1D"); glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) wglGetProcAddress("glFramebufferTexture2D"); glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) wglGetProcAddress("glFramebufferTexture3D"); glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) wglGetProcAddress("glFramebufferRenderbuffer"); glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) wglGetProcAddress("glGetFramebufferAttachmentParameteriv"); glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) wglGetProcAddress("glGenerateMipmap"); } else if (strstr(gl_extensions, "EXT_framebuffer_object")) { log("OpenGL: EXT_framebuffer_object is supported"); glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) wglGetProcAddress("glIsRenderbufferEXT"); glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) wglGetProcAddress("glBindRenderbufferEXT"); glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) wglGetProcAddress("glDeleteRenderbuffersEXT"); glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) wglGetProcAddress("glGenRenderbuffersEXT"); glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) wglGetProcAddress("glRenderbufferStorageEXT"); glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) wglGetProcAddress("glGetRenderbufferParameterivEXT"); glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) wglGetProcAddress("glIsFramebufferEXT"); glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) wglGetProcAddress("glBindFramebufferEXT"); glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) wglGetProcAddress("glDeleteFramebuffersEXT"); glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) wglGetProcAddress("glGenFramebuffersEXT"); glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) wglGetProcAddress("glCheckFramebufferStatusEXT"); glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) wglGetProcAddress("glFramebufferTexture1DEXT"); glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) wglGetProcAddress("glFramebufferTexture2DEXT"); glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) wglGetProcAddress("glFramebufferTexture3DEXT"); glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) wglGetProcAddress("glFramebufferRenderbufferEXT"); glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) wglGetProcAddress("glGetFramebufferAttachmentParameterivEXT"); glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) wglGetProcAddress("glGenerateMipmapEXT"); } else { log("OpenGL: No framebuffers extension is supported"); log("OpenGL: Any call to Fbo will crash!"); return false; } } return true; } #endif
原文地址:http://blog.csdn.net/jingzhewangzi/article/details/40509593