MyGui笔记(4)渲染过程
2013-10-18 00:30
344 查看
前篇:《MyGui笔记(3)控件对齐方式和所在层》
本篇:记录下渲染的过程。
环境:MyGui3.2.0(OpenGL平台)
MyGui的渲染过程比较复杂,这里仅记录一下一些要点,如有错误的地方,还请指出。在第一篇有提到在BaseManager::run函数里面进行每一帧的绘制,调用的是drawOneFrame()方法,这个方法代码如下:
调用的是OpenGLRenderManager的drawOneFrame()方法,代码如下:
在这里进行每一帧事件的触发,和每一帧的渲染,渲染调用其onRenderToTarget方法,代码如下:
可以看到在这里调用的是LayerManager层管理器来进行绘制,具体代码如下:
对mLayerNodes里的所有层依次进行调用渲染,故定义在MyGUI_Layers.xml文件最上面的层,将会最先开始渲染,顺序如Wallpaper→Back→Overlapped→……。具体的渲染方法是根据不同的层类型来进行的,代码分别如下:
在这里可以看到SharedLayer只进行了一次渲染,而OverlappedLayer对附加的根控件节点依次进行渲染,最终调用的都是LayerNode::renderToTarget方法,代码如下:
渲染调用的方法为RenderItem::renderToTarget,代码如下:
注释是俄语的,谷歌翻译成汉语,可能会有错误,还请指出。最后的渲染即调用OpenGLRenderManager::doRender方法,代码如下:
更多资料:
1.纯手绘的MyGUI类图、渲染流程图 http://blog.csdn.net/liigo/article/details/7078533
2.LayerManager http://blog.csdn.net/geometry_/article/details/7324348
3.mygui跟踪 http://www.cppblog.com/flipcode/archive/2011/06/24/149388.aspx
本篇:记录下渲染的过程。
环境:MyGui3.2.0(OpenGL平台)
MyGui的渲染过程比较复杂,这里仅记录一下一些要点,如有错误的地方,还请指出。在第一篇有提到在BaseManager::run函数里面进行每一帧的绘制,调用的是drawOneFrame()方法,这个方法代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | void BaseManager::drawOneFrame() { // First we clear the screen and depth buffer // 首先清除屏幕和深度缓冲 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Then we reset the modelview matrix // 然后重置模型视图矩阵 glLoadIdentity(); if (mPlatform) mPlatform->getRenderManagerPtr()->drawOneFrame(); SwapBuffers(hDC); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | void OpenGLRenderManager::drawOneFrame() { Gui* gui = Gui::getInstancePtr(); if (gui == nullptr) return; static Timer timer; static unsigned long last_time = timer.getMilliseconds(); unsigned long now_time = timer.getMilliseconds(); unsigned long time = now_time - last_time; onFrameEvent((float)((double)(time) / (double)1000)); last_time = now_time; begin(); onRenderToTarget(this, mUpdate); end(); mUpdate = false; } |
1 2 3 4 5 6 | void RenderManager::onRenderToTarget(IRenderTarget* _target, bool _update) { LayerManager* layers = LayerManager::getInstancePtr(); if (layers != nullptr) layers->renderToTarget(_target, _update); } |
1 2 3 4 5 6 7 | void LayerManager::renderToTarget(IRenderTarget* _target, bool _update) { for (VectorLayer::iterator iter = mLayerNodes.begin(); iter != mLayerNodes.end(); ++iter) { (*iter)->renderToTarget(_target, _update); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | void SharedLayer::renderToTarget(IRenderTarget* _target, bool _update) { if (mChildItem != nullptr) mChildItem->renderToTarget(_target, _update); mOutOfDate = false; } void OverlappedLayer::renderToTarget(IRenderTarget* _target, bool _update) { for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter) (*iter)->renderToTarget(_target, _update); mOutOfDate = false; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | void LayerNode::renderToTarget(IRenderTarget* _target, bool _update) { mDepth = _target->getInfo().maximumDepth; // 检查压缩空隙 bool need_compression = false; for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter) { if ((*iter)->getCompression()) { need_compression = true; break; } } if (need_compression) updateCompression(); // 首先渲染 for (VectorRenderItem::iterator iter = mFirstRenderItems.begin(); iter != mFirstRenderItems.end(); ++iter) (*iter)->renderToTarget(_target, _update); for (VectorRenderItem::iterator iter = mSecondRenderItems.begin(); iter != mSecondRenderItems.end(); ++iter) (*iter)->renderToTarget(_target, _update); // 现在绘制子节点 for (VectorILayerNode::iterator iter = mChildItems.begin(); iter != mChildItems.end(); ++iter) (*iter)->renderToTarget(_target, _update); mOutOfDate = false; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | void RenderItem::renderToTarget(IRenderTarget* _target, bool _update) { if (mTexture == nullptr) return; mRenderTarget = _target; mCurrentUpdate = _update; if (mOutOfDate || _update) { mCountVertex = 0; Vertex* buffer = mVertexBuffer->lock(); if (buffer != nullptr) { for (VectorDrawItem::iterator iter = mDrawItems.begin(); iter != mDrawItems.end(); ++iter) { // 在调用之前记住缓冲区的位置 mCurrentVertex = buffer; mLastVertexCount = 0; (*iter).first->doRender(); // 数量惊人的顶点绘制 MYGUI_DEBUG_ASSERT(mLastVertexCount <= (*iter).second, "It is too much vertexes"); buffer += mLastVertexCount; mCountVertex += mLastVertexCount; } mVertexBuffer->unlock(); } mOutOfDate = false; } // 虽然0不是批次显示,但它仍然不会产生状态和操作 if (0 != mCountVertex) { #if MYGUI_DEBUG_MODE == 1 if (!RenderManager::getInstance().checkTexture(mTexture)) { mTexture = nullptr; MYGUI_EXCEPT("texture pointer is not valid, texture name '" << mTextureName << "'"); return; } #endif //直接渲染 if (mManualRender) { for (VectorDrawItem::iterator iter = mDrawItems.begin(); iter != mDrawItems.end(); ++iter) (*iter).first->doManualRender(mVertexBuffer, mTexture, mCountVertex); } else { _target->doRender(mVertexBuffer, mTexture, mCountVertex); } } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | void OpenGLRenderManager::doRender(IVertexBuffer* _buffer, ITexture* _texture, size_t _count) { OpenGLVertexBuffer* buffer = static_cast<OpenGLVertexBuffer*>(_buffer); unsigned int buffer_id = buffer->getBufferID(); MYGUI_PLATFORM_ASSERT(buffer_id, "Vertex buffer is not created"); unsigned int texture_id = 0; if (_texture) { OpenGLTexture* texture = static_cast<OpenGLTexture*>(_texture); texture_id = texture->getTextureID(); //MYGUI_PLATFORM_ASSERT(texture_id, "Texture is not created"); } glBindTexture(GL_TEXTURE_2D, texture_id); glBindBuffer(GL_ARRAY_BUFFER, buffer_id); // enable vertex arrays glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); // before draw, specify vertex and index arrays with their offsets size_t offset = 0; glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)offset); offset += (sizeof(float) * 3); glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), (void*)offset); offset += (4); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)offset); glDrawArrays(GL_TRIANGLES, 0, _count); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindTexture(GL_TEXTURE_2D, 0); } |
1.纯手绘的MyGUI类图、渲染流程图 http://blog.csdn.net/liigo/article/details/7078533
2.LayerManager http://blog.csdn.net/geometry_/article/details/7324348
3.mygui跟踪 http://www.cppblog.com/flipcode/archive/2011/06/24/149388.aspx
相关文章推荐
- 帧渲染系统过程笔记
- cocos2d-x 3.6版本学习笔记-渲染过程
- 虚幻4 D3D渲染过程的笔记:04
- 帧渲染系统过程笔记
- OpenGL学习笔记(二):OpenGL语法、渲染管线以及具体实现过程详解
- iOS开发笔记--iOS 事件处理机制与图像渲染过程
- iOS开发笔记--iOS 事件处理机制与图像渲染过程
- 笔记:vc6.0添加自定义用户消息的基本过程(转)
- 栈溢出笔记1.1 函数调用过程
- 团购市场分析:24券 团购数据处理过程【笔记】
- 浏览器解析渲染的过程
- Oracle PLSQL笔记(过程的创建和及调用)
- Shell学习过程中的笔记
- android studio使用过程中遇到的问题(笔记)
- Hadoop 学习笔记四--JobTracker 的执行过程
- [学习笔记]KMP匹配算法及next推导过程
- 存储过程的笔记
- 韩顺平php视频笔记35 php运行过程
- iOS 学习笔记 - App 的启动过程(无Storyboard)
- 软件开发过程学习笔记(四)之详细设计说明书模板