Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

# OgrePanelGuiElement.cpp

Go to the documentation of this file.

    00001 /*
    00002 -----------------------------------------------------------------------------
    00003 This source file is part of OGRE
    00004     (Object-oriented Graphics Rendering Engine)
    00005 For the latest info, see http://www.ogre3d.org/
    00006
    00007 Copyright © 2000-2002 The OGRE Team
    00008 Also see acknowledgements in Readme.html
    00009
    00010 This program is free software; you can redistribute it and/or modify it under
    00011 the terms of the GNU Lesser General Public License as published by the Free Software
    00012 Foundation; either version 2 of the License, or (at your option) any later
    00013 version.
    00014
    00015 This program is distributed in the hope that it will be useful, but WITHOUT
    00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00018
    00019 You should have received a copy of the GNU Lesser General Public License along with
    00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
    00022 http://www.gnu.org/copyleft/lesser.txt.
    00023 -----------------------------------------------------------------------------
    00024 */
    00025
    00026 #include "OgrePanelGuiElement.h"
    00027 #include "OgreMaterial.h"
    00028 #include "OgreTechnique.h"
    00029 #include "OgrePass.h"
    00030 #include "OgreStringConverter.h"
    00031 #include "OgreHardwareBufferManager.h"
    00032 #include "OgreRoot.h"
    00033 #include "OgreRenderSystem.h"
    00034
    00035 namespace Ogre {
    00036     //---------------------------------------------------------------------
    00037     String PanelGuiElement::msTypeName = "Panel";
    00038     PanelGuiElement::CmdTiling PanelGuiElement::msCmdTiling;
    00039     PanelGuiElement::CmdTransparent PanelGuiElement::msCmdTransparent;
    00040     //---------------------------------------------------------------------
    00041     // vertex buffer bindings, set at compile time (we could look these up but no point)
    00042     #define POSITION_BINDING 0
    00043     #define TEXCOORD_BINDING 1
    00044
    00045     //---------------------------------------------------------------------
    00046     PanelGuiElement::PanelGuiElement(const String& name)
    00047         : GuiContainer(name)
    00048     {
    00049         mTransparent = false;
    00050         // Init tiling
    00051         for (ushort i = 0; i < OGRE_MAX_TEXTURE_COORD_SETS; ++i)
    00052         {
    00053             mTileX[i] = 1.0f;
    00054             mTileY[i] = 1.0f;
    00055         }
    00056
    00057         // Defer creation of texcoord buffer until we know how big it needs to be
    00058         mNumTexCoordsInBuffer = 0;
    00059
    00060         // No normals or colours
    00061         if (createParamDictionary("PanelGuiElement"))
    00062         {
    00063             addBaseParameters();
    00064         }
    00065
    00066     }
    00067     //---------------------------------------------------------------------
    00068     PanelGuiElement::~PanelGuiElement()
    00069     {
    00070         delete mRenderOp.vertexData;
    00071     }
    00072     //---------------------------------------------------------------------
    00073     void PanelGuiElement::initialise(void)
    00074     {
    00075         // Setup render op in advance
    00076         mRenderOp.vertexData = new VertexData();
    00077         // Vertex declaration: 1 position, add texcoords later depending on #layers
    00078         // Create as separate buffers so we can lock & discard separately
    00079         VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
    00080         decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
    00081
    00082         // Basic vertex data
    00083         mRenderOp.vertexData->vertexStart = 0;
    00084         mRenderOp.vertexData->vertexCount = 4;
    00085
    00086         // Vertex buffer #1
    00087         HardwareVertexBufferSharedPtr vbuf =
    00088             HardwareBufferManager::getSingleton().createVertexBuffer(
    00089             decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount,
    00090             HardwareBuffer::HBU_STATIC_WRITE_ONLY// mostly static except during resizing
    00091             );
    00092         // Bind buffer
    00093         mRenderOp.vertexData->vertexBufferBinding->setBinding(POSITION_BINDING, vbuf);
    00094
    00095         // No indexes & issue as a strip
    00096         mRenderOp.useIndexes = false;
    00097         mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP;
    00098     }
    00099     //---------------------------------------------------------------------
    00100     void PanelGuiElement::setTiling(Real x, Real y, ushort layer)
    00101     {
    00102         assert (layer < OGRE_MAX_TEXTURE_COORD_SETS);
    00103         assert (x != 0 && y != 0);
    00104
    00105         mTileX[layer] = x;
    00106         mTileY[layer] = y;
    00107
    00108         updateTextureGeometry();
    00109
    00110     }
    00111     //---------------------------------------------------------------------
    00112     Real PanelGuiElement::getTileX(ushort layer) const
    00113     {
    00114         return mTileX[layer];
    00115     }
    00116     //---------------------------------------------------------------------
    00117     Real PanelGuiElement::getTileY(ushort layer) const
    00118     {
    00119         return mTileY[layer];
    00120     }
    00121     //---------------------------------------------------------------------
    00122     void PanelGuiElement::setTransparent(bool isTransparent)
    00123     {
    00124         mTransparent = isTransparent;
    00125     }
    00126     //---------------------------------------------------------------------
    00127     bool PanelGuiElement::isTransparent(void) const
    00128     {
    00129         return mTransparent;
    00130     }
    00131     //---------------------------------------------------------------------
    00132     const String& PanelGuiElement::getTypeName(void) const
    00133     {
    00134         return msTypeName;
    00135     }
    00136     //---------------------------------------------------------------------
    00137     void PanelGuiElement::getRenderOperation(RenderOperation& op)
    00138     {
    00139         op = mRenderOp;
    00140     }
    00141     //---------------------------------------------------------------------
    00142     void PanelGuiElement::setMaterialName(const String& matName)
    00143     {
    00144         GuiContainer::setMaterialName(matName);
    00145         updateTextureGeometry();
    00146     }
    00147     //---------------------------------------------------------------------
    00148     void PanelGuiElement::_updateRenderQueue(RenderQueue* queue)
    00149     {
    00150         if (mVisible)
    00151         {
    00152
    00153             if (!mTransparent && mpMaterial)
    00154             {
    00155                 GuiElement::_updateRenderQueue(queue);
    00156             }
    00157
    00158             // Also add children
    00159             ChildIterator it = getChildIterator();
    00160             while (it.hasMoreElements())
    00161             {
    00162                 // Give children ZOrder 1 higher than this
    00163                 it.getNext()->_updateRenderQueue(queue);
    00164             }
    00165         }
    00166     }
    00167     //---------------------------------------------------------------------
    00168     void PanelGuiElement::updatePositionGeometry(void)
    00169     {
    00170         /*
    00171             0-----2
    00172             |    /|
    00173             |  /  |
    00174             |/    |
    00175             1-----3
    00176         */
    00177         Real left, right, top, bottom;
    00178
    00179         /* Convert positions into -1, 1 coordinate space (homogenous clip space).
    00180             - Left / right is simple range conversion
    00181             - Top / bottom also need inverting since y is upside down - this means
    00182               that top will end up greater than bottom and when computing texture
    00183               coordinates, we have to flip the v-axis (ie. subtract the value from
    00184               1.0 to get the actual correct value).
    00185         */
    00186         left = _getDerivedLeft() * 2 - 1;
    00187         right = left + (mWidth * 2);
    00188         top = -((_getDerivedTop() * 2) - 1);
    00189         bottom =  top -  (mHeight * 2);
    00190
    00191         HardwareVertexBufferSharedPtr vbuf =
    00192             mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
    00193         Real* pPos = static_cast<Real*>(
    00194             vbuf->lock(HardwareBuffer::HBL_DISCARD) );
    00195         // Use the furthest away depth value, since materials should have depth-check off
    00196         // This initialised the depth buffer for any 3D objects in front
    00197         Real zValue = Root::getSingleton().getRenderSystem()->getMaximumDepthInputValue();
    00198
    00199         *pPos++ = left;
    00200         *pPos++ = top;
    00201         *pPos++ = zValue;
    00202
    00203         *pPos++ = left;
    00204         *pPos++ = bottom;
    00205         *pPos++ = zValue;
    00206
    00207         *pPos++ = right;
    00208         *pPos++ = top;
    00209         *pPos++ = zValue;
    00210
    00211         *pPos++ = right;
    00212         *pPos++ = bottom;
    00213         *pPos++ = zValue;
    00214
    00215         vbuf->unlock();
    00216     }
    00217     //---------------------------------------------------------------------
    00218     void PanelGuiElement::updateTextureGeometry(void)
    00219     {
    00220         // Generate for as many texture layers as there are in material
    00221         if (mpMaterial)
    00222         {
    00223             // Assume one technique and pass for the moment
    00224             size_t numLayers = mpMaterial->getTechnique(0)->getPass(0)->getNumTextureUnitStates();
    00225
    00226             VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
    00227             // Check the number of texcoords we have in our buffer now
    00228             if (mNumTexCoordsInBuffer > numLayers)
    00229             {
    00230                 // remove extras
    00231                 for (size_t i = mNumTexCoordsInBuffer; i > numLayers; --i)
    00232                 {
    00233                     decl->removeElement(VES_TEXTURE_COORDINATES, i);
    00234                 }
    00235             }
    00236             else if (mNumTexCoordsInBuffer < numLayers)
    00237             {
    00238                 // Add extra texcoord elements
    00239                 size_t offset = VertexElement::getTypeSize(VET_FLOAT2) * mNumTexCoordsInBuffer;
    00240                 for (size_t i = mNumTexCoordsInBuffer; i < numLayers; ++i)
    00241                 {
    00242                     decl->addElement(TEXCOORD_BINDING,
    00243                         offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
    00244                     offset += VertexElement::getTypeSize(VET_FLOAT2);
    00245
    00246                 }
    00247             }
    00248
    00249             // if number of layers changed at all, we'll need to reallocate buffer
    00250             if (mNumTexCoordsInBuffer != numLayers)
    00251             {
    00252                 // NB reference counting will take care of the old one if it exists
    00253                 HardwareVertexBufferSharedPtr newbuf =
    00254                     HardwareBufferManager::getSingleton().createVertexBuffer(
    00255                     decl->getVertexSize(TEXCOORD_BINDING), mRenderOp.vertexData->vertexCount,
    00256                     HardwareBuffer::HBU_STATIC_WRITE_ONLY // mostly static except during resizing
    00257                     );
    00258                 // Bind buffer, note this will unbind the old one and destroy the buffer it had
    00259                 mRenderOp.vertexData->vertexBufferBinding->setBinding(TEXCOORD_BINDING, newbuf);
    00260                 // Set num tex coords in use now
    00261                 mNumTexCoordsInBuffer = numLayers;
    00262             }
    00263
    00264             // Get the tcoord buffer & lock
    00265             HardwareVertexBufferSharedPtr vbuf =
    00266                 mRenderOp.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING);
    00267             Real* pVBStart = static_cast<Real*>(
    00268                 vbuf->lock(HardwareBuffer::HBL_DISCARD) );
    00269
    00270             size_t uvSize = VertexElement::getTypeSize(VET_FLOAT2) / sizeof(Real);
    00271             size_t vertexSize = decl->getVertexSize(TEXCOORD_BINDING) / sizeof(Real);
    00272             for (ushort i = 0; i < numLayers; ++i)
    00273             {
    00274                 // Calc upper tex coords
    00275                 Real upperX = 1.0f * mTileX[i];
    00276                 Real upperY = 1.0f * mTileY[i];
    00277
    00278                 /*
    00279                     0-----2
    00280                     |    /|
    00281                     |  /  |
    00282                     |/    |
    00283                     1-----3
    00284                 */
    00285                 // Find start offset for this set
    00286                 Real* pTex = pVBStart + (i * uvSize);
    00287
    00288                 pTex[0] = 0.0f;
    00289                 pTex[1] = 0.0f;
    00290
    00291                 pTex += vertexSize; // jump by 1 vertex stride
    00292                 pTex[0] = 0.0f;
    00293                 pTex[1] = upperY;
    00294
    00295                 pTex += vertexSize;
    00296                 pTex[0] = upperX;
    00297                 pTex[1] = 0.0f;
    00298
    00299                 pTex += vertexSize;
    00300                 pTex[0] = upperX;
    00301                 pTex[1] = upperY;
    00302             }
    00303             vbuf->unlock();
    00304         }
    00305     }
    00306     //-----------------------------------------------------------------------
    00307     void PanelGuiElement::addBaseParameters(void)
    00308     {
    00309         GuiContainer::addBaseParameters();
    00310         ParamDictionary* dict = getParamDictionary();
    00311
    00312         dict->addParameter(ParameterDef("tiling",
    00313             "The number of times to repeat the background texture."
    00314             , PT_STRING),
    00315             &msCmdTiling);
    00316
    00317         dict->addParameter(ParameterDef("transparent",
    00318             "Sets whether the panel is transparent, i.e. invisible itself "
    00319             "but it's contents are still displayed."
    00320             , PT_BOOL),
    00321             &msCmdTransparent);
    00322     }
    00323     //-----------------------------------------------------------------------
    00324     // Command objects
    00325     //-----------------------------------------------------------------------
    00326     String PanelGuiElement::CmdTiling::doGet(const void* target) const
    00327     {
    00328         // NB only returns 1st layer tiling
    00329         String ret = "0 " + StringConverter::toString(
    00330             static_cast<const PanelGuiElement*>(target)->getTileX() );
    00331         ret += " " + StringConverter::toString(
    00332             static_cast<const PanelGuiElement*>(target)->getTileY() );
    00333         return ret;
    00334     }
    00335     void PanelGuiElement::CmdTiling::doSet(void* target, const String& val)
    00336     {
    00337         // 3 params: <layer> <x_tile> <y_tile>
    00338         // Param count is validated higher up
    00339         std::vector<String> vec = StringUtil::split(val);
    00340         ushort layer = (ushort)StringConverter::parseUnsignedInt(vec[0]);
    00341         Real x_tile = StringConverter::parseReal(vec[1]);
    00342         Real y_tile = StringConverter::parseReal(vec[2]);
    00343
    00344         static_cast<PanelGuiElement*>(target)->setTiling(x_tile, y_tile, layer);
    00345     }
    00346     //-----------------------------------------------------------------------
    00347     String PanelGuiElement::CmdTransparent::doGet(const void* target) const
    00348     {
    00349         return StringConverter::toString(
    00350             static_cast<const PanelGuiElement*>(target)->isTransparent() );
    00351     }
    00352     void PanelGuiElement::CmdTransparent::doSet(void* target, const String& val)
    00353     {
    00354         static_cast<PanelGuiElement*>(target)->setTransparent(
    00355             StringConverter::parseBool(val));
    00356     }
    00357
    00358
    00359 }
    00360
    00361
    00362

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:37 2004