Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/ogreceguirenderer/OgreCEGUIRenderer.cpp @ 4372

Last change on this file since 4372 was 2791, checked in by rgrieder, 16 years ago

Please never commit any changes to the external libraries! It doesn't make updating easier…

  • Property svn:eol-style set to native
File size: 27.3 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#if OGRE_VERSION >= 0x010600
458        d_render_sys->_setAlphaRejectSettings(CMPF_ALWAYS_PASS, 0, false);
459#else
460        d_render_sys->_setAlphaRejectSettings(CMPF_ALWAYS_PASS, 0);
461#endif
462        d_render_sys->_setTextureBlendMode(0, d_colourBlendMode);
463        d_render_sys->_setTextureBlendMode(0, d_alphaBlendMode);
464        d_render_sys->_disableTextureUnitsFrom(1);
465
466        // enable alpha blending
467        d_render_sys->_setSceneBlending(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
468}
469
470
471 
472/*************************************************************************
473        sort quads list according to texture   
474*************************************************************************/
475void OgreCEGUIRenderer::sortQuads(void)
476{
477        if (!d_sorted)
478        {
479                d_sorted = true;
480        }
481
482}
483
484/*************************************************************************
485render a quad directly to the display
486*************************************************************************/
487void OgreCEGUIRenderer::renderQuadDirect(const Rect& dest_rect, float z, const Texture* tex, const Rect& texture_rect, const ColourRect& colours, QuadSplitMode quad_split_mode)
488{
489        if (d_render_sys->_getViewport()->getOverlaysEnabled())
490        {
491                z = -1 + z;
492
493                Rect final_rect;
494
495                // set quad position, flipping y co-ordinates, and applying appropriate texel origin offset
496                final_rect.d_left       = dest_rect.d_left;
497                final_rect.d_right      = dest_rect.d_right;
498                final_rect.d_top        = d_display_area.getHeight() - dest_rect.d_top;
499                final_rect.d_bottom     = d_display_area.getHeight() - dest_rect.d_bottom;
500                final_rect.offset(d_texelOffset);
501
502                // convert quad co-ordinates for a -1 to 1 co-ordinate system.
503                final_rect.d_left       /= (d_display_area.getWidth() * 0.5f);
504                final_rect.d_right      /= (d_display_area.getWidth() * 0.5f);
505                final_rect.d_top        /= (d_display_area.getHeight() * 0.5f);
506                final_rect.d_bottom     /= (d_display_area.getHeight() * 0.5f);
507                final_rect.offset(Point(-1.0f, -1.0f));
508
509                // convert colours for ogre, note that top / bottom are switched.
510        uint32 topLeftCol       = colourToOgre(colours.d_bottom_left);
511        uint32 topRightCol      = colourToOgre(colours.d_bottom_right);
512        uint32 bottomLeftCol    = colourToOgre(colours.d_top_left);
513        uint32 bottomRightCol= colourToOgre(colours.d_top_right);
514
515                QuadVertex*     buffmem = (QuadVertex*)d_direct_buffer->lock(Ogre::HardwareVertexBuffer::HBL_DISCARD);
516
517                // setup Vertex 1...
518                buffmem->x      = final_rect.d_left;
519                buffmem->y      = final_rect. d_bottom;
520                buffmem->z      = z;
521                buffmem->diffuse = topLeftCol;
522                buffmem->tu1    = texture_rect.d_left;
523                buffmem->tv1    = texture_rect.d_bottom;
524                ++buffmem;
525
526                // setup Vertex 2...
527               
528                // top-left to bottom-right diagonal
529                if (quad_split_mode == TopLeftToBottomRight)
530                {
531                        buffmem->x      = final_rect.d_right;
532                        buffmem->y = final_rect.d_bottom;
533                        buffmem->z      = z;
534                        buffmem->diffuse = topRightCol;
535                        buffmem->tu1    = texture_rect.d_right;
536                        buffmem->tv1    = texture_rect.d_bottom;
537                        ++buffmem;
538                }
539                // bottom-left to top-right diagonal
540                else
541                {
542                        buffmem->x      = final_rect.d_right;
543                        buffmem->y = final_rect.d_top;
544                        buffmem->z      = z;
545                        buffmem->diffuse = bottomRightCol;
546                        buffmem->tu1    = texture_rect.d_right;
547                        buffmem->tv1    = texture_rect.d_top;
548                        ++buffmem;
549                }
550
551                // setup Vertex 3...
552                buffmem->x      = final_rect.d_left;
553                buffmem->y      = final_rect.d_top;
554                buffmem->z      = z;
555                buffmem->diffuse = bottomLeftCol;
556                buffmem->tu1    = texture_rect.d_left;
557                buffmem->tv1    = texture_rect.d_top;
558                ++buffmem;
559
560                // setup Vertex 4...
561                buffmem->x      = final_rect.d_right;
562                buffmem->y      = final_rect.d_bottom;
563                buffmem->z      = z;
564                buffmem->diffuse = topRightCol;
565                buffmem->tu1    = texture_rect.d_right;
566                buffmem->tv1    = texture_rect.d_bottom;
567                ++buffmem;
568
569                // setup Vertex 5...
570                buffmem->x      = final_rect.d_right;
571                buffmem->y      = final_rect.d_top;
572                buffmem->z      = z;
573                buffmem->diffuse = bottomRightCol;
574                buffmem->tu1    = texture_rect.d_right;
575                buffmem->tv1    = texture_rect.d_top;
576                ++buffmem;
577
578                // setup Vertex 6...
579               
580                // top-left to bottom-right diagonal
581                if (quad_split_mode == TopLeftToBottomRight)
582                {
583                        buffmem->x      = final_rect.d_left;
584                        buffmem->y = final_rect.d_top;
585                        buffmem->z      = z;
586                        buffmem->diffuse = bottomLeftCol;
587                        buffmem->tu1    = texture_rect.d_left;
588                        buffmem->tv1    = texture_rect.d_top;
589                }
590                // bottom-left to top-right diagonal
591                else
592                {
593                        buffmem->x      = final_rect.d_left;
594                        buffmem->y = final_rect.d_bottom;
595                        buffmem->z      = z;
596                        buffmem->diffuse = topLeftCol;
597                        buffmem->tu1    = texture_rect.d_left;
598                        buffmem->tv1    = texture_rect.d_bottom;
599                }
600
601                d_direct_buffer->unlock();
602
603        //
604                // perform rendering...
605                //
606                d_render_sys->_setTexture(0, true, ((OgreCEGUITexture*)tex)->getOgreTexture()->getName());
607                initRenderStates();
608                d_direct_render_op.vertexData->vertexCount = VERTEX_PER_QUAD;
609                d_render_sys->_render(d_direct_render_op);
610        }
611
612}
613
614/*************************************************************************
615        convert ARGB colour value to whatever the Ogre render system is
616        expecting.     
617*************************************************************************/
618uint32 OgreCEGUIRenderer::colourToOgre(const colour& col) const
619{
620        Ogre::ColourValue cv(col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha());
621
622    uint32 final;
623        d_render_sys->convertColourValue(cv, &final);
624
625        return final;
626}
627
628
629/*************************************************************************
630        Set the scene manager to be used for rendering the GUI.
631*************************************************************************/
632void OgreCEGUIRenderer::setTargetSceneManager(Ogre::SceneManager* scene_manager)
633{
634        // unhook from current scene manager.
635        if (d_sceneMngr != NULL)
636        {
637                d_sceneMngr->removeRenderQueueListener(d_ourlistener);
638                d_sceneMngr = NULL;
639        }
640
641        // hook new scene manager if that is not NULL
642        if (scene_manager != NULL)
643        {
644                d_sceneMngr = scene_manager;
645                d_sceneMngr->addRenderQueueListener(d_ourlistener);
646        }
647
648}
649
650
651/*************************************************************************
652        Set the target render queue for GUI rendering. 
653*************************************************************************/
654void OgreCEGUIRenderer::setTargetRenderQueue(Ogre::uint8 queue_id, bool post_queue)
655{
656        d_queue_id              = queue_id;
657        d_post_queue    = post_queue;
658
659        if (d_ourlistener != NULL)
660        {
661                d_ourlistener->setTargetRenderQueue(queue_id);
662                d_ourlistener->setPostRenderQueue(post_queue);
663        }
664
665}
666
667
668/*************************************************************************
669        perform main work of the constructor
670*************************************************************************/
671void OgreCEGUIRenderer::constructor_impl(Ogre::RenderWindow* window, Ogre::uint8 queue_id, bool post_queue, uint max_quads)
672{
673        using namespace Ogre;
674
675        // initialise the renderer fields
676        d_queueing              = true;
677        d_queue_id              = queue_id;
678        d_currTexture.isNull();
679        d_post_queue    = post_queue;
680        d_sceneMngr             = NULL;
681        d_bufferPos             = 0;
682        d_sorted                = true;
683        d_ogre_root             = Root::getSingletonPtr();
684        d_render_sys    = d_ogre_root->getRenderSystem();
685    // set ID string
686    d_identifierString = "CEGUI::OgreRenderer - Official Ogre based renderer module for CEGUI";
687
688        // Create and initialise the Ogre specific parts required for use in rendering later.
689    // Main GUI
690    createQuadRenderOp(d_render_op, d_buffer, VERTEXBUFFER_INITIAL_CAPACITY);
691    d_underused_framecount = 0;
692
693    // Mouse cursor
694    createQuadRenderOp(d_direct_render_op, d_direct_buffer, VERTEX_PER_QUAD);
695
696        // Discover display settings and setup d_display_area
697        d_display_area.d_left   = 0;
698        d_display_area.d_top    = 0;
699        d_display_area.d_right  = window->getWidth();
700        d_display_area.d_bottom = window->getHeight();
701
702        // initialise required texel offset
703        d_texelOffset = Point((float)d_render_sys->getHorizontalTexelOffset(), -(float)d_render_sys->getVerticalTexelOffset());
704
705        // create listener which will handler the rendering side of things for us.
706        d_ourlistener = new CEGUIRQListener(this, queue_id, post_queue);
707
708        // Initialise blending modes to be used.
709        d_colourBlendMode.blendType     = Ogre::LBT_COLOUR;
710        d_colourBlendMode.source1       = Ogre::LBS_TEXTURE;
711        d_colourBlendMode.source2       = Ogre::LBS_DIFFUSE;
712        d_colourBlendMode.operation     = Ogre::LBX_MODULATE;
713
714        d_alphaBlendMode.blendType      = Ogre::LBT_ALPHA;
715        d_alphaBlendMode.source1        = Ogre::LBS_TEXTURE;
716        d_alphaBlendMode.source2        = Ogre::LBS_DIFFUSE;
717        d_alphaBlendMode.operation      = Ogre::LBX_MODULATE;
718
719        d_uvwAddressMode.u = Ogre::TextureUnitState::TAM_CLAMP;
720        d_uvwAddressMode.v = Ogre::TextureUnitState::TAM_CLAMP;
721        d_uvwAddressMode.w = Ogre::TextureUnitState::TAM_CLAMP;
722}
723
724
725/*************************************************************************
726        Create a texture from an existing Ogre::TexturePtr object       
727*************************************************************************/
728Texture* OgreCEGUIRenderer::createTexture(Ogre::TexturePtr& texture)
729{
730        OgreCEGUITexture* t = (OgreCEGUITexture*)createTexture();
731
732        if (!texture.isNull())
733        {
734                t->setOgreTexture(texture);
735        }
736
737        return t;
738
739}
740
741/*************************************************************************
742        Create a resource provider object
743*************************************************************************/
744ResourceProvider* OgreCEGUIRenderer::createResourceProvider(void)
745{
746    d_resourceProvider = new OgreCEGUIResourceProvider();
747    return d_resourceProvider;
748}
749
750/*************************************************************************
751Set the size of the display in pixels. 
752*************************************************************************/
753void OgreCEGUIRenderer::setDisplaySize(const Size& sz)
754{
755        if (d_display_area.getSize() != sz)
756        {
757                d_display_area.setSize(sz);
758
759                EventArgs args;
760                fireEvent(EventDisplaySizeChanged, args, EventNamespace);
761        }
762
763}
764
765/*************************************************************************
766        Callback from Ogre invoked before other stuff in our target queue
767        is rendered
768*************************************************************************/
769void CEGUIRQListener::renderQueueStarted(Ogre::uint8 id, const Ogre::String& invocation, 
770                                                                                 bool& skipThisQueue)
771{
772        if ((!d_post_queue) && (d_queue_id == id))
773        {
774                CEGUI::System::getSingleton().renderGUI();
775        }
776
777}
778
779
780/*************************************************************************
781Callback from Ogre invoked after other stuff in our target queue
782is rendered
783*************************************************************************/
784void CEGUIRQListener::renderQueueEnded(Ogre::uint8 id, const Ogre::String& invocation, bool& repeatThisQueue)
785{
786        if ((d_post_queue) && (d_queue_id == id))
787        {
788                CEGUI::System::getSingleton().renderGUI();
789        }
790
791}
792
793} // End of  CEGUI namespace section
Note: See TracBrowser for help on using the repository browser.