Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/kicklib/src/external/ogreceguirenderer/OgreCEGUIRenderer.cpp @ 8633

Last change on this file since 8633 was 7948, checked in by rgrieder, 14 years ago

Dropped support for OGRE v1.4 and removed the remaining workarounds.

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