Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/external/ogreceguirenderer/OgreCEGUIRenderer.cpp @ 10558

Last change on this file since 10558 was 8367, checked in by rgrieder, 13 years ago

by Adi: Fix for GCC 4.6. The actual problem is in CEGUIString.h, but we cannot really fix that ;)

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