Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7078 was 5781, checked in by rgrieder, 15 years ago

Reverted trunk again. We might want to find a way to delete these revisions again (x3n's changes are still available as diff in the commit mails).

  • Property svn:eol-style set to native
File size: 27.3 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#if OGRE_VERSION >= 0x010600
458        d_render_sys->_setAlphaRejectSettings(CMPF_ALWAYS_PASS, 0, false);
459#else
[2602]460        d_render_sys->_setAlphaRejectSettings(CMPF_ALWAYS_PASS, 0);
[2757]461#endif
[2602]462        d_render_sys->_setTextureBlendMode(0, d_colourBlendMode);
463        d_render_sys->_setTextureBlendMode(0, d_alphaBlendMode);
464        d_render_sys->_disableTextureUnitsFrom(1);
[1638]465
[2602]466        // enable alpha blending
467        d_render_sys->_setSceneBlending(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
[1638]468}
469
470
[2791]471 
[1638]472/*************************************************************************
[2791]473        sort quads list according to texture   
[1638]474*************************************************************************/
475void OgreCEGUIRenderer::sortQuads(void)
476{
[2602]477        if (!d_sorted)
478        {
479                d_sorted = true;
480        }
[1638]481
482}
483
484/*************************************************************************
485render a quad directly to the display
486*************************************************************************/
487void OgreCEGUIRenderer::renderQuadDirect(const Rect& dest_rect, float z, const Texture* tex, const Rect& texture_rect, const ColourRect& colours, QuadSplitMode quad_split_mode)
488{
[2602]489        if (d_render_sys->_getViewport()->getOverlaysEnabled())
490        {
491                z = -1 + z;
[1638]492
[2602]493                Rect final_rect;
[1638]494
[2602]495                // set quad position, flipping y co-ordinates, and applying appropriate texel origin offset
496                final_rect.d_left       = dest_rect.d_left;
497                final_rect.d_right      = dest_rect.d_right;
498                final_rect.d_top        = d_display_area.getHeight() - dest_rect.d_top;
499                final_rect.d_bottom     = d_display_area.getHeight() - dest_rect.d_bottom;
500                final_rect.offset(d_texelOffset);
[1638]501
[2602]502                // convert quad co-ordinates for a -1 to 1 co-ordinate system.
503                final_rect.d_left       /= (d_display_area.getWidth() * 0.5f);
504                final_rect.d_right      /= (d_display_area.getWidth() * 0.5f);
505                final_rect.d_top        /= (d_display_area.getHeight() * 0.5f);
506                final_rect.d_bottom     /= (d_display_area.getHeight() * 0.5f);
507                final_rect.offset(Point(-1.0f, -1.0f));
[1638]508
[2602]509                // convert colours for ogre, note that top / bottom are switched.
[1638]510        uint32 topLeftCol       = colourToOgre(colours.d_bottom_left);
511        uint32 topRightCol      = colourToOgre(colours.d_bottom_right);
512        uint32 bottomLeftCol    = colourToOgre(colours.d_top_left);
513        uint32 bottomRightCol= colourToOgre(colours.d_top_right);
514
[2602]515                QuadVertex*     buffmem = (QuadVertex*)d_direct_buffer->lock(Ogre::HardwareVertexBuffer::HBL_DISCARD);
[1638]516
[2602]517                // setup Vertex 1...
518                buffmem->x      = final_rect.d_left;
519                buffmem->y      = final_rect. d_bottom;
520                buffmem->z      = z;
521                buffmem->diffuse = topLeftCol;
522                buffmem->tu1    = texture_rect.d_left;
523                buffmem->tv1    = texture_rect.d_bottom;
524                ++buffmem;
[1638]525
[2602]526                // setup Vertex 2...
[2791]527               
[2602]528                // top-left to bottom-right diagonal
529                if (quad_split_mode == TopLeftToBottomRight)
530                {
531                        buffmem->x      = final_rect.d_right;
532                        buffmem->y = final_rect.d_bottom;
533                        buffmem->z      = z;
534                        buffmem->diffuse = topRightCol;
535                        buffmem->tu1    = texture_rect.d_right;
536                        buffmem->tv1    = texture_rect.d_bottom;
537                        ++buffmem;
538                }
539                // bottom-left to top-right diagonal
540                else
541                {
542                        buffmem->x      = final_rect.d_right;
543                        buffmem->y = final_rect.d_top;
544                        buffmem->z      = z;
545                        buffmem->diffuse = bottomRightCol;
546                        buffmem->tu1    = texture_rect.d_right;
547                        buffmem->tv1    = texture_rect.d_top;
548                        ++buffmem;
549                }
[1638]550
[2602]551                // setup Vertex 3...
552                buffmem->x      = final_rect.d_left;
553                buffmem->y      = final_rect.d_top;
554                buffmem->z      = z;
555                buffmem->diffuse = bottomLeftCol;
556                buffmem->tu1    = texture_rect.d_left;
557                buffmem->tv1    = texture_rect.d_top;
558                ++buffmem;
[1638]559
[2602]560                // setup Vertex 4...
561                buffmem->x      = final_rect.d_right;
562                buffmem->y      = final_rect.d_bottom;
563                buffmem->z      = z;
564                buffmem->diffuse = topRightCol;
565                buffmem->tu1    = texture_rect.d_right;
566                buffmem->tv1    = texture_rect.d_bottom;
567                ++buffmem;
[1638]568
[2602]569                // setup Vertex 5...
570                buffmem->x      = final_rect.d_right;
571                buffmem->y      = final_rect.d_top;
572                buffmem->z      = z;
573                buffmem->diffuse = bottomRightCol;
574                buffmem->tu1    = texture_rect.d_right;
575                buffmem->tv1    = texture_rect.d_top;
576                ++buffmem;
[1638]577
[2602]578                // setup Vertex 6...
[2791]579               
[2602]580                // top-left to bottom-right diagonal
581                if (quad_split_mode == TopLeftToBottomRight)
582                {
583                        buffmem->x      = final_rect.d_left;
584                        buffmem->y = final_rect.d_top;
585                        buffmem->z      = z;
586                        buffmem->diffuse = bottomLeftCol;
587                        buffmem->tu1    = texture_rect.d_left;
588                        buffmem->tv1    = texture_rect.d_top;
589                }
590                // bottom-left to top-right diagonal
591                else
592                {
593                        buffmem->x      = final_rect.d_left;
594                        buffmem->y = final_rect.d_bottom;
595                        buffmem->z      = z;
596                        buffmem->diffuse = topLeftCol;
597                        buffmem->tu1    = texture_rect.d_left;
598                        buffmem->tv1    = texture_rect.d_bottom;
599                }
[1638]600
[2602]601                d_direct_buffer->unlock();
[1638]602
603        //
[2602]604                // perform rendering...
605                //
606                d_render_sys->_setTexture(0, true, ((OgreCEGUITexture*)tex)->getOgreTexture()->getName());
607                initRenderStates();
608                d_direct_render_op.vertexData->vertexCount = VERTEX_PER_QUAD;
609                d_render_sys->_render(d_direct_render_op);
610        }
[1638]611
612}
613
614/*************************************************************************
[2602]615        convert ARGB colour value to whatever the Ogre render system is
[2791]616        expecting.     
[1638]617*************************************************************************/
618uint32 OgreCEGUIRenderer::colourToOgre(const colour& col) const
619{
[2602]620        Ogre::ColourValue cv(col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha());
[1638]621
622    uint32 final;
[2602]623        d_render_sys->convertColourValue(cv, &final);
[1638]624
[2602]625        return final;
[1638]626}
627
628
629/*************************************************************************
[2791]630        Set the scene manager to be used for rendering the GUI.
[1638]631*************************************************************************/
632void OgreCEGUIRenderer::setTargetSceneManager(Ogre::SceneManager* scene_manager)
633{
[2602]634        // unhook from current scene manager.
635        if (d_sceneMngr != NULL)
636        {
637                d_sceneMngr->removeRenderQueueListener(d_ourlistener);
638                d_sceneMngr = NULL;
639        }
[1638]640
[2602]641        // hook new scene manager if that is not NULL
642        if (scene_manager != NULL)
643        {
644                d_sceneMngr = scene_manager;
645                d_sceneMngr->addRenderQueueListener(d_ourlistener);
646        }
[1638]647
648}
649
650
651/*************************************************************************
[2791]652        Set the target render queue for GUI rendering. 
[1638]653*************************************************************************/
654void OgreCEGUIRenderer::setTargetRenderQueue(Ogre::uint8 queue_id, bool post_queue)
655{
[2602]656        d_queue_id              = queue_id;
657        d_post_queue    = post_queue;
[1638]658
[2602]659        if (d_ourlistener != NULL)
660        {
661                d_ourlistener->setTargetRenderQueue(queue_id);
662                d_ourlistener->setPostRenderQueue(post_queue);
663        }
[1638]664
665}
666
667
668/*************************************************************************
[2602]669        perform main work of the constructor
[1638]670*************************************************************************/
671void OgreCEGUIRenderer::constructor_impl(Ogre::RenderWindow* window, Ogre::uint8 queue_id, bool post_queue, uint max_quads)
672{
[2602]673        using namespace Ogre;
[1638]674
[2602]675        // initialise the renderer fields
676        d_queueing              = true;
677        d_queue_id              = queue_id;
678        d_currTexture.isNull();
679        d_post_queue    = post_queue;
680        d_sceneMngr             = NULL;
681        d_bufferPos             = 0;
682        d_sorted                = true;
683        d_ogre_root             = Root::getSingletonPtr();
684        d_render_sys    = d_ogre_root->getRenderSystem();
[1638]685    // set ID string
686    d_identifierString = "CEGUI::OgreRenderer - Official Ogre based renderer module for CEGUI";
687
[2602]688        // Create and initialise the Ogre specific parts required for use in rendering later.
[1638]689    // Main GUI
690    createQuadRenderOp(d_render_op, d_buffer, VERTEXBUFFER_INITIAL_CAPACITY);
691    d_underused_framecount = 0;
692
693    // Mouse cursor
694    createQuadRenderOp(d_direct_render_op, d_direct_buffer, VERTEX_PER_QUAD);
695
[2602]696        // Discover display settings and setup d_display_area
697        d_display_area.d_left   = 0;
698        d_display_area.d_top    = 0;
699        d_display_area.d_right  = window->getWidth();
700        d_display_area.d_bottom = window->getHeight();
[1638]701
[2602]702        // initialise required texel offset
703        d_texelOffset = Point((float)d_render_sys->getHorizontalTexelOffset(), -(float)d_render_sys->getVerticalTexelOffset());
[1638]704
[2602]705        // create listener which will handler the rendering side of things for us.
706        d_ourlistener = new CEGUIRQListener(this, queue_id, post_queue);
[1638]707
[2602]708        // Initialise blending modes to be used.
709        d_colourBlendMode.blendType     = Ogre::LBT_COLOUR;
710        d_colourBlendMode.source1       = Ogre::LBS_TEXTURE;
711        d_colourBlendMode.source2       = Ogre::LBS_DIFFUSE;
712        d_colourBlendMode.operation     = Ogre::LBX_MODULATE;
[1638]713
[2602]714        d_alphaBlendMode.blendType      = Ogre::LBT_ALPHA;
715        d_alphaBlendMode.source1        = Ogre::LBS_TEXTURE;
716        d_alphaBlendMode.source2        = Ogre::LBS_DIFFUSE;
717        d_alphaBlendMode.operation      = Ogre::LBX_MODULATE;
[1638]718
[2602]719        d_uvwAddressMode.u = Ogre::TextureUnitState::TAM_CLAMP;
720        d_uvwAddressMode.v = Ogre::TextureUnitState::TAM_CLAMP;
721        d_uvwAddressMode.w = Ogre::TextureUnitState::TAM_CLAMP;
[1638]722}
723
724
725/*************************************************************************
[2791]726        Create a texture from an existing Ogre::TexturePtr object       
[1638]727*************************************************************************/
728Texture* OgreCEGUIRenderer::createTexture(Ogre::TexturePtr& texture)
729{
[2602]730        OgreCEGUITexture* t = (OgreCEGUITexture*)createTexture();
[1638]731
[2602]732        if (!texture.isNull())
733        {
734                t->setOgreTexture(texture);
735        }
[1638]736
[2602]737        return t;
[1638]738
739}
740
741/*************************************************************************
[2602]742        Create a resource provider object
[1638]743*************************************************************************/
744ResourceProvider* OgreCEGUIRenderer::createResourceProvider(void)
745{
746    d_resourceProvider = new OgreCEGUIResourceProvider();
747    return d_resourceProvider;
748}
749
750/*************************************************************************
[2791]751Set the size of the display in pixels. 
[1638]752*************************************************************************/
753void OgreCEGUIRenderer::setDisplaySize(const Size& sz)
754{
[2602]755        if (d_display_area.getSize() != sz)
756        {
757                d_display_area.setSize(sz);
[1638]758
[2602]759                EventArgs args;
760                fireEvent(EventDisplaySizeChanged, args, EventNamespace);
761        }
[1638]762
763}
764
765/*************************************************************************
[2602]766        Callback from Ogre invoked before other stuff in our target queue
767        is rendered
[1638]768*************************************************************************/
[2791]769void CEGUIRQListener::renderQueueStarted(Ogre::uint8 id, const Ogre::String& invocation, 
[2602]770                                                                                 bool& skipThisQueue)
[1638]771{
[2602]772        if ((!d_post_queue) && (d_queue_id == id))
773        {
774                CEGUI::System::getSingleton().renderGUI();
775        }
[1638]776
777}
778
779
780/*************************************************************************
781Callback from Ogre invoked after other stuff in our target queue
782is rendered
783*************************************************************************/
784void CEGUIRQListener::renderQueueEnded(Ogre::uint8 id, const Ogre::String& invocation, bool& repeatThisQueue)
785{
[2602]786        if ((d_post_queue) && (d_queue_id == id))
787        {
788                CEGUI::System::getSingleton().renderGUI();
789        }
[1638]790
791}
792
793} // End of  CEGUI namespace section
Note: See TracBrowser for help on using the repository browser.