Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/orxonox_tutorial/src/orxonox/gui/OgreCEGUIRenderer.cpp @ 1831

Last change on this file since 1831 was 1755, checked in by rgrieder, 16 years ago

merged gui back to trunk.
update the media repository!

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