Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/orxonox/gui/OgreCEGUIRenderer.cpp @ 2736

Last change on this file since 2736 was 2087, checked in by landauf, 16 years ago

merged objecthierarchy branch back to trunk

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