source: OGRE/trunk/ogrenew/OgreMain/src/OgrePanelOverlayElement.cpp @ 657

Revision 657, 13.4 KB checked in by mattausch, 19 years ago (diff)

added ogre dependencies and patched ogre sources

Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright  2000-2005 The OGRE Team
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23-----------------------------------------------------------------------------
24*/
25#include "OgreStableHeaders.h"
26
27#include "OgrePanelOverlayElement.h"
28#include "OgreMaterial.h"
29#include "OgreTechnique.h"
30#include "OgrePass.h"
31#include "OgreStringConverter.h"
32#include "OgreHardwareBufferManager.h"
33#include "OgreRoot.h"
34#include "OgreRenderSystem.h"
35
36namespace Ogre {
37    //---------------------------------------------------------------------
38    String PanelOverlayElement::msTypeName = "Panel";
39    PanelOverlayElement::CmdTiling PanelOverlayElement::msCmdTiling;
40    PanelOverlayElement::CmdTransparent PanelOverlayElement::msCmdTransparent;
41    //---------------------------------------------------------------------
42    // vertex buffer bindings, set at compile time (we could look these up but no point)
43    #define POSITION_BINDING 0
44    #define TEXCOORD_BINDING 1
45
46    //---------------------------------------------------------------------
47    PanelOverlayElement::PanelOverlayElement(const String& name)
48        : OverlayContainer(name)
49    {
50        mTransparent = false;
51        // Init tiling
52        for (ushort i = 0; i < OGRE_MAX_TEXTURE_COORD_SETS; ++i)
53        {
54            mTileX[i] = 1.0f;
55            mTileY[i] = 1.0f;
56        }
57
58        // Defer creation of texcoord buffer until we know how big it needs to be
59        mNumTexCoordsInBuffer = 0;
60
61        // No normals or colours
62        if (createParamDictionary("PanelOverlayElement"))
63        {
64            addBaseParameters();
65        }
66
67    }
68    //---------------------------------------------------------------------
69    PanelOverlayElement::~PanelOverlayElement()
70    {
71        delete mRenderOp.vertexData;
72    }
73    //---------------------------------------------------------------------
74    void PanelOverlayElement::initialise(void)
75    {
76                bool init = !mInitialised;
77
78                OverlayContainer::initialise();
79                if (init)
80                {
81                        // Setup render op in advance
82                        mRenderOp.vertexData = new VertexData();
83                        // Vertex declaration: 1 position, add texcoords later depending on #layers
84                        // Create as separate buffers so we can lock & discard separately
85                        VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
86                        decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
87
88                        // Basic vertex data
89                        mRenderOp.vertexData->vertexStart = 0;
90                        mRenderOp.vertexData->vertexCount = 4;
91
92                        // Vertex buffer #1
93                        HardwareVertexBufferSharedPtr vbuf =
94                                HardwareBufferManager::getSingleton().createVertexBuffer(
95                                decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount,
96                                HardwareBuffer::HBU_STATIC_WRITE_ONLY// mostly static except during resizing
97                                );
98                        // Bind buffer
99                        mRenderOp.vertexData->vertexBufferBinding->setBinding(POSITION_BINDING, vbuf);
100
101                        // No indexes & issue as a strip
102                        mRenderOp.useIndexes = false;
103                        mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP;
104
105                        mInitialised = true;
106                }
107    }
108    //---------------------------------------------------------------------
109    void PanelOverlayElement::setTiling(Real x, Real y, ushort layer)
110    {
111        assert (layer < OGRE_MAX_TEXTURE_COORD_SETS);
112        assert (x != 0 && y != 0);
113
114        mTileX[layer] = x;
115        mTileY[layer] = y;
116
117        mGeomUVsOutOfDate = true;
118
119    }
120    //---------------------------------------------------------------------
121    Real PanelOverlayElement::getTileX(ushort layer) const
122    {
123        return mTileX[layer];
124    }
125    //---------------------------------------------------------------------
126    Real PanelOverlayElement::getTileY(ushort layer) const
127    {
128        return mTileY[layer];
129    }
130    //---------------------------------------------------------------------
131    void PanelOverlayElement::setTransparent(bool isTransparent)
132    {
133        mTransparent = isTransparent;
134    }
135    //---------------------------------------------------------------------
136    bool PanelOverlayElement::isTransparent(void) const
137    {
138        return mTransparent;
139    }
140    //---------------------------------------------------------------------
141    const String& PanelOverlayElement::getTypeName(void) const
142    {
143        return msTypeName;
144    }
145    //---------------------------------------------------------------------
146    void PanelOverlayElement::getRenderOperation(RenderOperation& op)
147    {
148        op = mRenderOp;
149    }
150    //---------------------------------------------------------------------
151    void PanelOverlayElement::setMaterialName(const String& matName)
152    {
153        OverlayContainer::setMaterialName(matName);
154    }
155    //---------------------------------------------------------------------
156    void PanelOverlayElement::_updateRenderQueue(RenderQueue* queue)
157    {
158        if (mVisible)
159        {
160
161            if (!mTransparent && !mpMaterial.isNull())
162            {
163                OverlayElement::_updateRenderQueue(queue);
164            }
165
166            // Also add children
167            ChildIterator it = getChildIterator();
168            while (it.hasMoreElements())
169            {
170                // Give children ZOrder 1 higher than this
171                it.getNext()->_updateRenderQueue(queue);
172            }
173        }
174    }
175    //---------------------------------------------------------------------
176    void PanelOverlayElement::updatePositionGeometry(void)
177    {
178                /*
179                        0-----2
180                        |    /|
181                        |  /  |
182                        |/    |
183                        1-----3
184                */
185                Real left, right, top, bottom;
186
187                /* Convert positions into -1, 1 coordinate space (homogenous clip space).
188                        - Left / right is simple range conversion
189                        - Top / bottom also need inverting since y is upside down - this means
190                        that top will end up greater than bottom and when computing texture
191                        coordinates, we have to flip the v-axis (ie. subtract the value from
192                        1.0 to get the actual correct value).
193                */
194                left = _getDerivedLeft() * 2 - 1;
195                right = left + (mWidth * 2);
196                top = -((_getDerivedTop() * 2) - 1);
197                bottom =  top -  (mHeight * 2);
198
199                HardwareVertexBufferSharedPtr vbuf =
200                        mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
201                float* pPos = static_cast<float*>(
202                        vbuf->lock(HardwareBuffer::HBL_DISCARD) );
203           
204                // Use the furthest away depth value, since materials should have depth-check off
205                // This initialised the depth buffer for any 3D objects in front
206                Real zValue = Root::getSingleton().getRenderSystem()->getMaximumDepthInputValue();
207                *pPos++ = left;
208                *pPos++ = top;
209                *pPos++ = zValue;
210
211                *pPos++ = left;
212                *pPos++ = bottom;
213                *pPos++ = zValue;
214
215                *pPos++ = right;
216                *pPos++ = top;
217                *pPos++ = zValue;
218
219                *pPos++ = right;
220                *pPos++ = bottom;
221                *pPos++ = zValue;
222           
223                vbuf->unlock();
224    }
225    //---------------------------------------------------------------------
226    void PanelOverlayElement::updateTextureGeometry(void)
227    {
228        // Generate for as many texture layers as there are in material
229        if (!mpMaterial.isNull() && mInitialised)
230        {
231            // Assume one technique and pass for the moment
232            size_t numLayers = mpMaterial->getTechnique(0)->getPass(0)->getNumTextureUnitStates();
233
234            VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
235            // Check the number of texcoords we have in our buffer now
236            if (mNumTexCoordsInBuffer > numLayers)
237            {
238                // remove extras
239                for (size_t i = mNumTexCoordsInBuffer; i > numLayers; --i)
240                {
241                    decl->removeElement(VES_TEXTURE_COORDINATES, i);
242                }
243            }
244            else if (mNumTexCoordsInBuffer < numLayers)
245            {
246                // Add extra texcoord elements
247                size_t offset = VertexElement::getTypeSize(VET_FLOAT2) * mNumTexCoordsInBuffer;
248                for (size_t i = mNumTexCoordsInBuffer; i < numLayers; ++i)
249                {
250                    decl->addElement(TEXCOORD_BINDING,
251                        offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
252                    offset += VertexElement::getTypeSize(VET_FLOAT2);
253                   
254                }
255            }
256
257            // if number of layers changed at all, we'll need to reallocate buffer
258            if (mNumTexCoordsInBuffer != numLayers)
259            {
260                // NB reference counting will take care of the old one if it exists
261                HardwareVertexBufferSharedPtr newbuf =
262                    HardwareBufferManager::getSingleton().createVertexBuffer(
263                    decl->getVertexSize(TEXCOORD_BINDING), mRenderOp.vertexData->vertexCount,
264                    HardwareBuffer::HBU_STATIC_WRITE_ONLY // mostly static except during resizing
265                    );
266                // Bind buffer, note this will unbind the old one and destroy the buffer it had
267                mRenderOp.vertexData->vertexBufferBinding->setBinding(TEXCOORD_BINDING, newbuf);
268                // Set num tex coords in use now
269                mNumTexCoordsInBuffer = numLayers;
270            }
271
272            // Get the tcoord buffer & lock
273                        if (mNumTexCoordsInBuffer)
274                        {
275                                HardwareVertexBufferSharedPtr vbuf =
276                                        mRenderOp.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING);
277                                float* pVBStart = static_cast<float*>(
278                                        vbuf->lock(HardwareBuffer::HBL_DISCARD) );
279
280                                size_t uvSize = VertexElement::getTypeSize(VET_FLOAT2) / sizeof(float);
281                                size_t vertexSize = decl->getVertexSize(TEXCOORD_BINDING) / sizeof(float);
282                                for (ushort i = 0; i < numLayers; ++i)
283                                {
284                                        // Calc upper tex coords
285                                        Real upperX = 1.0f * mTileX[i];
286                                        Real upperY = 1.0f * mTileY[i];
287                       
288                                        /*
289                                                0-----2
290                                                |    /|
291                                                |  /  |
292                                                |/    |
293                                                1-----3
294                                        */
295                                        // Find start offset for this set
296                                        float* pTex = pVBStart + (i * uvSize);
297
298                                        pTex[0] = 0.0f;
299                                        pTex[1] = 0.0f;
300
301                                        pTex += vertexSize; // jump by 1 vertex stride
302                                        pTex[0] = 0.0f;
303                                        pTex[1] = upperY;
304
305                                        pTex += vertexSize;
306                                        pTex[0] = upperX;
307                                        pTex[1] = 0.0f;
308
309                                        pTex += vertexSize;
310                                        pTex[0] = upperX;
311                                        pTex[1] = upperY;
312                                }
313                                vbuf->unlock();
314                        }
315        }
316    }
317    //-----------------------------------------------------------------------
318    void PanelOverlayElement::addBaseParameters(void)
319    {
320        OverlayContainer::addBaseParameters();
321        ParamDictionary* dict = getParamDictionary();
322
323        dict->addParameter(ParameterDef("tiling",
324            "The number of times to repeat the background texture."
325            , PT_STRING),
326            &msCmdTiling);
327
328        dict->addParameter(ParameterDef("transparent",
329            "Sets whether the panel is transparent, i.e. invisible itself "
330            "but it's contents are still displayed."
331            , PT_BOOL),
332            &msCmdTransparent);
333    }
334    //-----------------------------------------------------------------------
335    // Command objects
336    //-----------------------------------------------------------------------
337    String PanelOverlayElement::CmdTiling::doGet(const void* target) const
338    {
339        // NB only returns 1st layer tiling
340        String ret = "0 " + StringConverter::toString(
341            static_cast<const PanelOverlayElement*>(target)->getTileX() );
342        ret += " " + StringConverter::toString(
343            static_cast<const PanelOverlayElement*>(target)->getTileY() );
344        return ret;
345    }
346    void PanelOverlayElement::CmdTiling::doSet(void* target, const String& val)
347    {
348        // 3 params: <layer> <x_tile> <y_tile>
349        // Param count is validated higher up
350        std::vector<String> vec = StringUtil::split(val);
351        ushort layer = (ushort)StringConverter::parseUnsignedInt(vec[0]);
352        Real x_tile = StringConverter::parseReal(vec[1]);
353        Real y_tile = StringConverter::parseReal(vec[2]);
354
355        static_cast<PanelOverlayElement*>(target)->setTiling(x_tile, y_tile, layer);
356    }
357    //-----------------------------------------------------------------------
358    String PanelOverlayElement::CmdTransparent::doGet(const void* target) const
359    {
360        return StringConverter::toString(
361            static_cast<const PanelOverlayElement*>(target)->isTransparent() );
362    }
363    void PanelOverlayElement::CmdTransparent::doSet(void* target, const String& val)
364    {
365        static_cast<PanelOverlayElement*>(target)->setTransparent(
366            StringConverter::parseBool(val));
367    }
368
369
370}
371
372
373
Note: See TracBrowser for help on using the repository browser.