source: OGRE/trunk/ogrenew/Samples/Common/CEGUIRenderer/src/OgreCEGUIRenderer.cpp @ 692

Revision 692, 27.8 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

Line 
1/************************************************************************
2        filename:       OgreCEGUIRenderer.cpp
3        created:        11/5/2004
4        author:         Paul D Turner
5       
6        purpose:        Implementation of Renderer class for Ogre engine
7*************************************************************************/
8/*************************************************************************
9    Crazy Eddie's GUI System (http://www.cegui.org.uk)
10    Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
11
12    This library is free software; you can redistribute it and/or
13    modify it under the terms of the GNU Lesser General Public
14    License as published by the Free Software Foundation; either
15    version 2.1 of the License, or (at your option) any later version.
16
17    This library is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    Lesser General Public License for more details.
21
22    You should have received a copy of the GNU Lesser General Public
23    License along with this library; if not, write to the Free Software
24    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
25*************************************************************************/
26
27#include <CEGUI/CEGUIImagesetManager.h>
28#include <CEGUI/CEGUIImageset.h>
29#include <CEGUI/CEGUIImage.h>
30#include <CEGUI/CEGUIExceptions.h>
31#include <CEGUI/CEGUISystem.h>
32
33#include "OgreCEGUIRenderer.h"
34#include "OgreCEGUITexture.h"
35#include "OgreCEGUIResourceProvider.h"
36
37#include <OgreRenderSystem.h>
38#include <OgreRoot.h>
39#include <OgreHardwareBufferManager.h>
40#include <OgreRenderWindow.h>
41
42// Start of CEGUI namespace section
43namespace CEGUI
44{
45/*************************************************************************
46        Constants definitions
47*************************************************************************/
48const size_t    OgreCEGUIRenderer::VERTEX_PER_QUAD                      = 6;
49const size_t    OgreCEGUIRenderer::VERTEX_PER_TRIANGLE          = 3;
50const size_t    OgreCEGUIRenderer::VERTEXBUFFER_INITIAL_CAPACITY        = 256;
51const size_t    OgreCEGUIRenderer::UNDERUSED_FRAME_THRESHOLD = 50000; // halfs buffer every 8 minutes on 100fps
52
53/*************************************************************************
54        Utility function to create a render operation and vertex buffer to render quads
55*************************************************************************/
56void createQuadRenderOp(Ogre::RenderOperation &d_render_op,
57    Ogre::HardwareVertexBufferSharedPtr &d_buffer, size_t nquads)
58{
59    using namespace Ogre;
60    // Create and initialise the Ogre specific parts required for use in rendering later.
61        d_render_op.vertexData = new VertexData;
62        d_render_op.vertexData->vertexStart = 0;
63
64        // setup vertex declaration for the vertex format we use
65        VertexDeclaration* vd = d_render_op.vertexData->vertexDeclaration;
66        size_t vd_offset = 0;
67        vd->addElement(0, vd_offset, VET_FLOAT3, VES_POSITION);
68        vd_offset += VertexElement::getTypeSize(VET_FLOAT3);
69        vd->addElement(0, vd_offset, VET_COLOUR, VES_DIFFUSE);
70        vd_offset += VertexElement::getTypeSize(VET_COLOUR);
71        vd->addElement(0, vd_offset, VET_FLOAT2, VES_TEXTURE_COORDINATES);
72
73        // create hardware vertex buffer
74        d_buffer = HardwareBufferManager::getSingleton().createVertexBuffer(vd->getVertexSize(0), nquads, 
75        HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false);
76
77        // bind vertex buffer
78        d_render_op.vertexData->vertexBufferBinding->setBinding(0, d_buffer);
79
80        // complete render operation basic initialisation
81        d_render_op.operationType = RenderOperation::OT_TRIANGLE_LIST;
82        d_render_op.useIndexes = false;
83}
84void destroyQuadRenderOp(Ogre::RenderOperation &d_render_op,
85    Ogre::HardwareVertexBufferSharedPtr &d_buffer)
86{
87    delete d_render_op.vertexData;
88    d_render_op.vertexData = 0;
89    d_buffer.setNull();
90}
91
92/*************************************************************************
93        Constructor
94*************************************************************************/
95OgreCEGUIRenderer::OgreCEGUIRenderer(Ogre::RenderWindow* window, Ogre::uint8 queue_id, bool post_queue, uint max_quads)
96{
97        constructor_impl(window, queue_id, post_queue, max_quads);
98}
99
100
101/*************************************************************************
102        Constructor (specifying scene manager)
103*************************************************************************/
104OgreCEGUIRenderer::OgreCEGUIRenderer(Ogre::RenderWindow* window, Ogre::uint8 queue_id, bool post_queue, uint max_quads, Ogre::SceneManager* scene_manager)
105{
106        constructor_impl(window, queue_id, post_queue, max_quads);
107
108        // hook into ogre rendering system
109        setTargetSceneManager(scene_manager);
110}
111
112
113/*************************************************************************
114        Destructor
115*************************************************************************/
116OgreCEGUIRenderer::~OgreCEGUIRenderer(void)
117{
118        setTargetSceneManager(NULL);
119
120        if (d_ourlistener)
121        {
122                delete d_ourlistener;
123        }
124
125        // cleanup vertex data we allocated in constructor
126        destroyQuadRenderOp(d_render_op, d_buffer);
127    destroyQuadRenderOp(d_direct_render_op, d_direct_buffer);
128
129        destroyAllTextures();
130}
131
132
133/*************************************************************************
134        add's a quad to the list to be rendered
135*************************************************************************/
136void OgreCEGUIRenderer::addQuad(const Rect& dest_rect, float z, const Texture* tex, const Rect& texture_rect, const ColourRect& colours, QuadSplitMode quad_split_mode)
137{
138        // if not queueing, render directly (as in, right now!). This is used for the mouse cursor.
139        if (!d_queueing)
140        {
141                renderQuadDirect(dest_rect, z, tex, texture_rect, colours, quad_split_mode);
142        }
143        else
144        {
145                d_sorted = false;
146                QuadInfo quad;
147               
148                // set quad position, flipping y co-ordinates, and applying appropriate texel origin offset
149                quad.position.d_left    = dest_rect.d_left;
150                quad.position.d_right   = dest_rect.d_right;
151                quad.position.d_top             = d_display_area.getHeight() - dest_rect.d_top;
152                quad.position.d_bottom  = d_display_area.getHeight() - dest_rect.d_bottom;
153                quad.position.offset(d_texelOffset);
154
155                // convert quad co-ordinates for a -1 to 1 co-ordinate system.
156                quad.position.d_left    /= (d_display_area.getWidth() * 0.5f);
157                quad.position.d_right   /= (d_display_area.getWidth() * 0.5f);
158                quad.position.d_top             /= (d_display_area.getHeight() * 0.5f);
159                quad.position.d_bottom  /= (d_display_area.getHeight() * 0.5f);
160                quad.position.offset(Point(-1.0f, -1.0f));
161
162                quad.z                          = -1 + z;
163                quad.texture            = ((OgreCEGUITexture*)tex)->getOgreTexture();
164                quad.texPosition        = texture_rect;
165
166                // covert colours for ogre, note that top / bottom are switched.
167                quad.topLeftCol         = colourToOgre(colours.d_bottom_left);
168                quad.topRightCol        = colourToOgre(colours.d_bottom_right);
169                quad.bottomLeftCol      = colourToOgre(colours.d_top_left);
170                quad.bottomRightCol     = colourToOgre(colours.d_top_right);
171               
172                // set quad split mode
173                quad.splitMode = quad_split_mode;
174
175                d_quadlist.insert(quad);
176        }
177}
178
179
180
181/*************************************************************************
182perform final rendering for all queued renderable quads.
183*************************************************************************/
184void OgreCEGUIRenderer::doRender(void)
185{
186    // Render if overlays enabled and the quad list is not empty
187        if (d_render_sys->_getViewport()->getOverlaysEnabled() && !d_quadlist.empty())
188        {
189        /// Quad list needs to be sorted and thus the vertex buffer rebuilt. If not, we can
190        /// reuse the vertex buffer resulting in a nice speed gain.
191        if(!d_sorted)
192        {
193            sortQuads();
194            /// Resize vertex buffer if it is too small
195            size_t size = d_buffer->getNumVertices();
196            size_t requestedSize = d_quadlist.size()*VERTEX_PER_QUAD;
197            if(size < requestedSize)
198            {
199                /// Double buffer size until smaller than requested size
200                while(size < requestedSize)
201                    size = size * 2;
202                /// Reallocate the buffer
203                destroyQuadRenderOp(d_render_op, d_buffer);
204                createQuadRenderOp(d_render_op, d_buffer, size);
205            }
206            else if(requestedSize < size/2 && d_underused_framecount >= UNDERUSED_FRAME_THRESHOLD)
207            {
208                /// Resize vertex buffer if it has been to big for too long
209                size = size / 2;
210                destroyQuadRenderOp(d_render_op, d_buffer);
211                createQuadRenderOp(d_render_op, d_buffer, size);
212                /// Reset underused framecount so it takes another UNDERUSED_FRAME_THRESHOLD to half again
213                d_underused_framecount = 0;
214            }
215            /// Fill the buffer
216            QuadVertex* buffmem;
217            buffmem = (QuadVertex*)d_buffer->lock(Ogre::HardwareVertexBuffer::HBL_DISCARD);
218            // iterate over each quad in the list
219            for (QuadList::iterator i = d_quadlist.begin(); i != d_quadlist.end(); ++i)
220            {
221                const QuadInfo& quad = (*i);
222                // setup Vertex 1...
223                buffmem->x = quad.position.d_left;
224                buffmem->y = quad.position.d_bottom;
225                buffmem->z = quad.z;
226                buffmem->diffuse = quad.topLeftCol;
227                buffmem->tu1 = quad.texPosition.d_left;
228                buffmem->tv1 = quad.texPosition.d_bottom;
229                ++buffmem;
230   
231                // setup Vertex 2...
232               
233                // top-left to bottom-right diagonal
234                if (quad.splitMode == TopLeftToBottomRight)
235                {
236                    buffmem->x = quad.position.d_right;
237                    buffmem->y = quad.position.d_bottom;
238                    buffmem->z = quad.z;
239                    buffmem->diffuse = quad.topRightCol;
240                    buffmem->tu1 = quad.texPosition.d_right;
241                    buffmem->tv1 = quad.texPosition.d_bottom;
242                }
243                // bottom-left to top-right diagonal
244                else
245                {
246                    buffmem->x = quad.position.d_right;
247                    buffmem->y = quad.position.d_top;
248                    buffmem->z = quad.z;
249                    buffmem->diffuse = quad.bottomRightCol;
250                    buffmem->tu1 = quad.texPosition.d_right;
251                    buffmem->tv1 = quad.texPosition.d_top;
252                }
253                ++buffmem;
254   
255                // setup Vertex 3...
256                buffmem->x = quad.position.d_left;
257                buffmem->y = quad.position.d_top;
258                buffmem->z = quad.z;
259                buffmem->diffuse = quad.bottomLeftCol;
260                buffmem->tu1 = quad.texPosition.d_left;
261                buffmem->tv1 = quad.texPosition.d_top;
262                ++buffmem;
263   
264                // setup Vertex 4...
265                buffmem->x = quad.position.d_right;
266                buffmem->y = quad.position.d_bottom;
267                buffmem->z = quad.z;
268                buffmem->diffuse = quad.topRightCol;
269                buffmem->tu1 = quad.texPosition.d_right;
270                buffmem->tv1 = quad.texPosition.d_bottom;
271                ++buffmem;
272   
273                // setup Vertex 5...
274                buffmem->x = quad.position.d_right;
275                buffmem->y = quad.position.d_top;
276                buffmem->z = quad.z;
277                buffmem->diffuse = quad.bottomRightCol;
278                buffmem->tu1 = quad.texPosition.d_right;
279                buffmem->tv1 = quad.texPosition.d_top;
280                ++buffmem;
281   
282                // setup Vertex 6...
283               
284                // top-left to bottom-right diagonal
285                if (quad.splitMode == TopLeftToBottomRight)
286                {
287                    buffmem->x = quad.position.d_left;
288                    buffmem->y = quad.position.d_top;
289                    buffmem->z = quad.z;
290                    buffmem->diffuse = quad.bottomLeftCol;
291                    buffmem->tu1 = quad.texPosition.d_left;
292                    buffmem->tv1 = quad.texPosition.d_top;
293                }
294                // bottom-left to top-right diagonal
295                else
296                {
297                    buffmem->x = quad.position.d_left;
298                    buffmem->y = quad.position.d_bottom;
299                    buffmem->z = quad.z;
300                    buffmem->diffuse = quad.topLeftCol;
301                    buffmem->tu1 = quad.texPosition.d_left;
302                    buffmem->tv1 = quad.texPosition.d_bottom;
303                }
304                ++buffmem;
305            }
306   
307            // ensure we leave the buffer in the unlocked state
308            d_buffer->unlock();
309        }
310       
311        /// Render the buffer
312                initRenderStates();
313        d_bufferPos = 0;
314
315        // Iterate over each quad in the list and render it
316        QuadList::iterator i = d_quadlist.begin();
317        while(i != d_quadlist.end())
318        {
319           
320            d_currTexture = i->texture;
321            d_render_op.vertexData->vertexStart = d_bufferPos;
322            for (; i != d_quadlist.end(); ++i)
323            {
324                const QuadInfo& quad = (*i);
325                if (d_currTexture != quad.texture)
326                    /// If it has a different texture, render this quad in next operation
327                            break;
328                d_bufferPos += VERTEX_PER_QUAD;
329            }
330            d_render_op.vertexData->vertexCount = d_bufferPos - d_render_op.vertexData->vertexStart;
331            /// Set texture, and do the render
332            d_render_sys->_setTexture(0, true, d_currTexture->getName());
333            d_render_sys->_render(d_render_op);
334        }
335
336        }
337    /// Count frames to check if utilization of vertex buffer was below half the capacity for 500,000 frames
338    if(d_bufferPos < d_buffer->getNumVertices()/2)
339       d_underused_framecount++;
340    else
341       d_underused_framecount = 0;
342}
343
344
345/*************************************************************************
346        clear the queue
347*************************************************************************/
348void OgreCEGUIRenderer::clearRenderList(void)
349{
350        d_sorted = true;
351        d_quadlist.clear();
352}
353
354
355/*************************************************************************
356        create an empty texture
357*************************************************************************/
358Texture* OgreCEGUIRenderer::createTexture(void)
359{
360        OgreCEGUITexture* tex = new OgreCEGUITexture(this);
361        d_texturelist.push_back(tex);
362        return tex;
363}
364
365
366/*************************************************************************
367        create a texture and load it with the specified file.
368*************************************************************************/
369Texture* OgreCEGUIRenderer::createTexture(const String& filename, const String& resourceGroup)
370{
371        OgreCEGUITexture* tex = (OgreCEGUITexture*)createTexture();
372        tex->loadFromFile(filename, resourceGroup);
373
374        return tex;
375}
376
377
378/*************************************************************************
379        create a texture and set it to the specified size
380*************************************************************************/
381Texture* OgreCEGUIRenderer::createTexture(float size)
382{
383        OgreCEGUITexture* tex = (OgreCEGUITexture*)createTexture();
384        tex->setOgreTextureSize((uint)size);
385
386        return tex;
387}
388
389
390/*************************************************************************
391        destroy the given texture
392*************************************************************************/
393void OgreCEGUIRenderer::destroyTexture(Texture* texture)
394{
395        if (texture != NULL)
396        {
397                OgreCEGUITexture* tex = (OgreCEGUITexture*)texture;
398
399                d_texturelist.remove(tex);
400                delete tex;
401        }
402}
403
404
405/*************************************************************************
406        destroy all textures still active
407*************************************************************************/
408void OgreCEGUIRenderer::destroyAllTextures(void)
409{
410        while (!d_texturelist.empty())
411        {
412                destroyTexture(*(d_texturelist.begin()));
413        }
414}
415
416
417/*************************************************************************
418        setup states etc       
419*************************************************************************/
420void OgreCEGUIRenderer::initRenderStates(void)
421{
422        using namespace Ogre;
423
424        // set-up matrices
425        d_render_sys->_setWorldMatrix(Matrix4::IDENTITY);
426        d_render_sys->_setViewMatrix(Matrix4::IDENTITY);
427        d_render_sys->_setProjectionMatrix(Matrix4::IDENTITY);
428
429        // initialise render settings
430        d_render_sys->setLightingEnabled(false);
431        d_render_sys->_setDepthBufferParams(false, false);
432        d_render_sys->_setCullingMode(CULL_NONE);
433        d_render_sys->_setFog(FOG_NONE);
434        d_render_sys->_setColourBufferWriteEnabled(true, true, true, true);
435        d_render_sys->unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
436        d_render_sys->unbindGpuProgram(GPT_VERTEX_PROGRAM);
437        d_render_sys->setShadingType(SO_GOURAUD);
438        d_render_sys->_setPolygonMode(PM_SOLID);
439
440        // initialise texture settings
441        d_render_sys->_setTextureCoordCalculation(0, TEXCALC_NONE);
442        d_render_sys->_setTextureCoordSet(0, 0);
443        d_render_sys->_setTextureUnitFiltering(0, FO_LINEAR, FO_LINEAR, FO_POINT);
444        d_render_sys->_setTextureAddressingMode(0, d_uvwAddressMode);
445        d_render_sys->_setTextureMatrix(0, Matrix4::IDENTITY);
446        d_render_sys->_setAlphaRejectSettings(CMPF_ALWAYS_PASS, 0);
447        d_render_sys->_setTextureBlendMode(0, d_colourBlendMode);
448        d_render_sys->_setTextureBlendMode(0, d_alphaBlendMode);
449        d_render_sys->_disableTextureUnitsFrom(1);
450
451        // enable alpha blending
452        d_render_sys->_setSceneBlending(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
453}
454
455
456 
457/*************************************************************************
458        sort quads list according to texture   
459*************************************************************************/
460void OgreCEGUIRenderer::sortQuads(void)
461{
462        if (!d_sorted)
463        {
464                d_sorted = true;
465        }
466
467}
468
469/*************************************************************************
470render a quad directly to the display
471*************************************************************************/
472void OgreCEGUIRenderer::renderQuadDirect(const Rect& dest_rect, float z, const Texture* tex, const Rect& texture_rect, const ColourRect& colours, QuadSplitMode quad_split_mode)
473{
474        if (d_render_sys->_getViewport()->getOverlaysEnabled())
475        {
476                z = -1 + z;
477
478                Rect final_rect;
479
480                // set quad position, flipping y co-ordinates, and applying appropriate texel origin offset
481                final_rect.d_left       = dest_rect.d_left;
482                final_rect.d_right      = dest_rect.d_right;
483                final_rect.d_top        = d_display_area.getHeight() - dest_rect.d_top;
484                final_rect.d_bottom     = d_display_area.getHeight() - dest_rect.d_bottom;
485                final_rect.offset(d_texelOffset);
486
487                // convert quad co-ordinates for a -1 to 1 co-ordinate system.
488                final_rect.d_left       /= (d_display_area.getWidth() * 0.5f);
489                final_rect.d_right      /= (d_display_area.getWidth() * 0.5f);
490                final_rect.d_top        /= (d_display_area.getHeight() * 0.5f);
491                final_rect.d_bottom     /= (d_display_area.getHeight() * 0.5f);
492                final_rect.offset(Point(-1.0f, -1.0f));
493
494                // convert colours for ogre, note that top / bottom are switched.
495        uint32 topLeftCol       = colourToOgre(colours.d_bottom_left);
496        uint32 topRightCol      = colourToOgre(colours.d_bottom_right);
497        uint32 bottomLeftCol    = colourToOgre(colours.d_top_left);
498        uint32 bottomRightCol= colourToOgre(colours.d_top_right);
499
500                QuadVertex*     buffmem = (QuadVertex*)d_direct_buffer->lock(Ogre::HardwareVertexBuffer::HBL_DISCARD);
501
502                // setup Vertex 1...
503                buffmem->x      = final_rect.d_left;
504                buffmem->y      = final_rect. d_bottom;
505                buffmem->z      = z;
506                buffmem->diffuse = topLeftCol;
507                buffmem->tu1    = texture_rect.d_left;
508                buffmem->tv1    = texture_rect.d_bottom;
509                ++buffmem;
510
511                // setup Vertex 2...
512               
513                // top-left to bottom-right diagonal
514                if (quad_split_mode == TopLeftToBottomRight)
515                {
516                        buffmem->x      = final_rect.d_right;
517                        buffmem->y = final_rect.d_bottom;
518                        buffmem->z      = z;
519                        buffmem->diffuse = topRightCol;
520                        buffmem->tu1    = texture_rect.d_right;
521                        buffmem->tv1    = texture_rect.d_bottom;
522                        ++buffmem;
523                }
524                // bottom-left to top-right diagonal
525                else
526                {
527                        buffmem->x      = final_rect.d_right;
528                        buffmem->y = final_rect.d_top;
529                        buffmem->z      = z;
530                        buffmem->diffuse = bottomRightCol;
531                        buffmem->tu1    = texture_rect.d_right;
532                        buffmem->tv1    = texture_rect.d_top;
533                        ++buffmem;
534                }
535
536                // setup Vertex 3...
537                buffmem->x      = final_rect.d_left;
538                buffmem->y      = final_rect.d_top;
539                buffmem->z      = z;
540                buffmem->diffuse = bottomLeftCol;
541                buffmem->tu1    = texture_rect.d_left;
542                buffmem->tv1    = texture_rect.d_top;
543                ++buffmem;
544
545                // setup Vertex 4...
546                buffmem->x      = final_rect.d_right;
547                buffmem->y      = final_rect.d_bottom;
548                buffmem->z      = z;
549                buffmem->diffuse = topRightCol;
550                buffmem->tu1    = texture_rect.d_right;
551                buffmem->tv1    = texture_rect.d_bottom;
552                ++buffmem;
553
554                // setup Vertex 5...
555                buffmem->x      = final_rect.d_right;
556                buffmem->y      = final_rect.d_top;
557                buffmem->z      = z;
558                buffmem->diffuse = bottomRightCol;
559                buffmem->tu1    = texture_rect.d_right;
560                buffmem->tv1    = texture_rect.d_top;
561                ++buffmem;
562
563                // setup Vertex 6...
564               
565                // top-left to bottom-right diagonal
566                if (quad_split_mode == TopLeftToBottomRight)
567                {
568                        buffmem->x      = final_rect.d_left;
569                        buffmem->y = final_rect.d_top;
570                        buffmem->z      = z;
571                        buffmem->diffuse = bottomLeftCol;
572                        buffmem->tu1    = texture_rect.d_left;
573                        buffmem->tv1    = texture_rect.d_top;
574                }
575                // bottom-left to top-right diagonal
576                else
577                {
578                        buffmem->x      = final_rect.d_left;
579                        buffmem->y = final_rect.d_bottom;
580                        buffmem->z      = z;
581                        buffmem->diffuse = topLeftCol;
582                        buffmem->tu1    = texture_rect.d_left;
583                        buffmem->tv1    = texture_rect.d_bottom;
584                }
585
586                d_direct_buffer->unlock();
587
588        //
589                // perform rendering...
590                //
591        initRenderStates();
592                d_render_sys->_setTexture(0, true, ((OgreCEGUITexture*)tex)->getOgreTexture()->getName());
593                d_direct_render_op.vertexData->vertexCount = VERTEX_PER_QUAD;
594                d_render_sys->_render(d_direct_render_op);
595        }
596
597}
598
599/*************************************************************************
600        convert ARGB colour value to whatever the Ogre render system is
601        expecting.     
602*************************************************************************/
603uint32 OgreCEGUIRenderer::colourToOgre(const colour& col) const
604{
605        Ogre::ColourValue cv(col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha());
606
607    uint32 final;
608        d_render_sys->convertColourValue(cv, &final);
609
610        return final;
611}
612
613
614/*************************************************************************
615        Set the scene manager to be used for rendering the GUI.
616*************************************************************************/
617void OgreCEGUIRenderer::setTargetSceneManager(Ogre::SceneManager* scene_manager)
618{
619        // unhook from current scene manager.
620        if (d_sceneMngr != NULL)
621        {
622                d_sceneMngr->removeRenderQueueListener(d_ourlistener);
623                d_sceneMngr = NULL;
624        }
625
626        // hook new scene manager if that is not NULL
627        if (scene_manager != NULL)
628        {
629                d_sceneMngr = scene_manager;
630                d_sceneMngr->addRenderQueueListener(d_ourlistener);
631        }
632
633}
634
635
636/*************************************************************************
637        Set the target render queue for GUI rendering. 
638*************************************************************************/
639void OgreCEGUIRenderer::setTargetRenderQueue(Ogre::uint8 queue_id, bool post_queue)
640{
641        d_queue_id              = queue_id;
642        d_post_queue    = post_queue;
643
644        if (d_ourlistener != NULL)
645        {
646                d_ourlistener->setTargetRenderQueue(queue_id);
647                d_ourlistener->setPostRenderQueue(post_queue);
648        }
649
650}
651
652
653/*************************************************************************
654        perform main work of the constructor
655*************************************************************************/
656void OgreCEGUIRenderer::constructor_impl(Ogre::RenderWindow* window, Ogre::uint8 queue_id, bool post_queue, uint max_quads)
657{
658        using namespace Ogre;
659
660        // initialise the renderer fields
661        d_queueing              = true;
662        d_queue_id              = queue_id;
663        d_currTexture.isNull();
664        d_post_queue    = post_queue;
665        d_sceneMngr             = NULL;
666        d_bufferPos             = 0;
667        d_sorted                = true;
668        d_ogre_root             = Root::getSingletonPtr();
669        d_render_sys    = d_ogre_root->getRenderSystem();
670    // set ID string
671    d_identifierString = "CEGUI::OgreRenderer - Official Ogre based renderer module for CEGUI";
672
673        // Create and initialise the Ogre specific parts required for use in rendering later.
674    // Main GUI
675    createQuadRenderOp(d_render_op, d_buffer, VERTEXBUFFER_INITIAL_CAPACITY);
676    d_underused_framecount = 0;
677
678    // Mouse cursor
679    createQuadRenderOp(d_direct_render_op, d_direct_buffer, VERTEX_PER_QUAD);
680
681        // Discover display settings and setup d_display_area
682        d_display_area.d_left   = 0;
683        d_display_area.d_top    = 0;
684        d_display_area.d_right  = window->getWidth();
685        d_display_area.d_bottom = window->getHeight();
686
687        // initialise required texel offset
688        d_texelOffset = Point((float)d_render_sys->getHorizontalTexelOffset(), -(float)d_render_sys->getVerticalTexelOffset());
689
690        // create listener which will handler the rendering side of things for us.
691        d_ourlistener = new CEGUIRQListener(this, queue_id, post_queue);
692
693        // Initialise blending modes to be used.
694        d_colourBlendMode.blendType     = Ogre::LBT_COLOUR;
695        d_colourBlendMode.source1       = Ogre::LBS_TEXTURE;
696        d_colourBlendMode.source2       = Ogre::LBS_DIFFUSE;
697        d_colourBlendMode.operation     = Ogre::LBX_MODULATE;
698
699        d_alphaBlendMode.blendType      = Ogre::LBT_ALPHA;
700        d_alphaBlendMode.source1        = Ogre::LBS_TEXTURE;
701        d_alphaBlendMode.source2        = Ogre::LBS_DIFFUSE;
702        d_alphaBlendMode.operation      = Ogre::LBX_MODULATE;
703
704        d_uvwAddressMode.u = Ogre::TextureUnitState::TAM_CLAMP;
705        d_uvwAddressMode.v = Ogre::TextureUnitState::TAM_CLAMP;
706        d_uvwAddressMode.w = Ogre::TextureUnitState::TAM_CLAMP;
707}
708
709
710/*************************************************************************
711        Create a texture from an existing Ogre::TexturePtr object       
712*************************************************************************/
713Texture* OgreCEGUIRenderer::createTexture(Ogre::TexturePtr& texture)
714{
715        OgreCEGUITexture* t = (OgreCEGUITexture*)createTexture();
716
717        if (!texture.isNull())
718        {
719                t->setOgreTexture(texture);
720        }
721
722        return t;
723
724}
725
726/*************************************************************************
727        Create a resource provider object
728*************************************************************************/
729ResourceProvider* OgreCEGUIRenderer::createResourceProvider(void)
730{
731    d_resourceProvider = new OgreCEGUIResourceProvider();
732    return d_resourceProvider;
733}
734
735/*************************************************************************
736Set the size of the display in pixels. 
737*************************************************************************/
738void OgreCEGUIRenderer::setDisplaySize(const Size& sz)
739{
740        if (d_display_area.getSize() != sz)
741        {
742                d_display_area.setSize(sz);
743
744                EventArgs args;
745                fireEvent(EventDisplaySizeChanged, args, EventNamespace);
746        }
747
748}
749
750/*************************************************************************
751        Callback from Ogre invoked before other stuff in our target queue
752        is rendered
753*************************************************************************/
754void CEGUIRQListener::renderQueueStarted(Ogre::uint8 id, const Ogre::String& invocation,
755                                                                                 bool& skipThisQueue)
756{
757        if ((!d_post_queue) && (d_queue_id == id))
758        {
759                CEGUI::System::getSingleton().renderGUI();
760        }
761
762}
763
764
765/*************************************************************************
766Callback from Ogre invoked after other stuff in our target queue
767is rendered
768*************************************************************************/
769void CEGUIRQListener::renderQueueEnded(Ogre::uint8 id, const Ogre::String& invocation, bool& repeatThisQueue)
770{
771        if ((d_post_queue) && (d_queue_id == id))
772        {
773                CEGUI::System::getSingleton().renderGUI();
774        }
775
776}
777
778} // End of  CEGUI namespace section
Note: See TracBrowser for help on using the repository browser.