Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

merged input branch into gui test branch (was about time)
svn save (it's still a mess and CMLs haven't been updated)
I'll have to create a special project to create the tolua_bind files for tolua itself anyway..

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