Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/kicklib2/src/external/ogreceguirenderer/OgreCEGUIRenderer.cpp @ 8283

Last change on this file since 8283 was 8283, checked in by rgrieder, 14 years ago

Merged revisions 7940-7974 from kicklib to kicklib2.

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