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

Revision 692, 15.2 KB checked in by mattausch, 18 years ago (diff)

adding ogre 1.2 and dependencies

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    PanelOverlayElement::CmdUVCoords PanelOverlayElement::msCmdUVCoords;
42    //---------------------------------------------------------------------
43    // vertex buffer bindings, set at compile time (we could look these up but no point)
44    #define POSITION_BINDING 0
45    #define TEXCOORD_BINDING 1
46
47    //---------------------------------------------------------------------
48    PanelOverlayElement::PanelOverlayElement(const String& name)
49        : OverlayContainer(name)
50        , mTransparent(false)
51        // Defer creation of texcoord buffer until we know how big it needs to be
52        , mNumTexCoordsInBuffer(0)
53        , mU1(0.0)
54        , mV1(0.0)
55        , mU2(1.0)
56        , mV2(1.0)
57
58    {
59        // Init tiling
60        for (ushort i = 0; i < OGRE_MAX_TEXTURE_COORD_SETS; ++i)
61        {
62            mTileX[i] = 1.0f;
63            mTileY[i] = 1.0f;
64        }
65
66        // No normals or colours
67        if (createParamDictionary("PanelOverlayElement"))
68        {
69            addBaseParameters();
70        }
71
72    }
73    //---------------------------------------------------------------------
74    PanelOverlayElement::~PanelOverlayElement()
75    {
76        delete mRenderOp.vertexData;
77    }
78    //---------------------------------------------------------------------
79    void PanelOverlayElement::initialise(void)
80    {
81                bool init = !mInitialised;
82
83                OverlayContainer::initialise();
84                if (init)
85                {
86                        // Setup render op in advance
87                        mRenderOp.vertexData = new VertexData();
88                        // Vertex declaration: 1 position, add texcoords later depending on #layers
89                        // Create as separate buffers so we can lock & discard separately
90                        VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
91                        decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
92
93                        // Basic vertex data
94                        mRenderOp.vertexData->vertexStart = 0;
95                        mRenderOp.vertexData->vertexCount = 4;
96
97                        // Vertex buffer #1
98                        HardwareVertexBufferSharedPtr vbuf =
99                                HardwareBufferManager::getSingleton().createVertexBuffer(
100                                decl->getVertexSize(POSITION_BINDING), mRenderOp.vertexData->vertexCount,
101                                HardwareBuffer::HBU_STATIC_WRITE_ONLY// mostly static except during resizing
102                                );
103                        // Bind buffer
104                        mRenderOp.vertexData->vertexBufferBinding->setBinding(POSITION_BINDING, vbuf);
105
106                        // No indexes & issue as a strip
107                        mRenderOp.useIndexes = false;
108                        mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP;
109
110                        mInitialised = true;
111                }
112    }
113    //---------------------------------------------------------------------
114    void PanelOverlayElement::setTiling(Real x, Real y, ushort layer)
115    {
116        assert (layer < OGRE_MAX_TEXTURE_COORD_SETS);
117        assert (x != 0 && y != 0);
118
119        mTileX[layer] = x;
120        mTileY[layer] = y;
121
122        mGeomUVsOutOfDate = true;
123
124    }
125    //---------------------------------------------------------------------
126    Real PanelOverlayElement::getTileX(ushort layer) const
127    {
128        return mTileX[layer];
129    }
130    //---------------------------------------------------------------------
131    Real PanelOverlayElement::getTileY(ushort layer) const
132    {
133        return mTileY[layer];
134    }
135    //---------------------------------------------------------------------
136    void PanelOverlayElement::setTransparent(bool isTransparent)
137    {
138        mTransparent = isTransparent;
139    }
140    //---------------------------------------------------------------------
141    bool PanelOverlayElement::isTransparent(void) const
142    {
143        return mTransparent;
144    }
145    //---------------------------------------------------------------------
146    void PanelOverlayElement::setUV(Real u1, Real v1, Real u2, Real v2)
147    {
148                mU1 = u1;
149                mU2 = u2;
150                mV1 = v1;
151                mV2 = v2;
152                mGeomUVsOutOfDate = true;
153    }
154    void PanelOverlayElement::getUV(Real& u1, Real& v1, Real& u2, Real& v2) const
155    {
156                u1 = mU1;
157                u2 = mU2;
158                v1 = mV1;
159                v2 = mV2;
160    }
161    //---------------------------------------------------------------------
162    const String& PanelOverlayElement::getTypeName(void) const
163    {
164        return msTypeName;
165    }
166    //---------------------------------------------------------------------
167    void PanelOverlayElement::getRenderOperation(RenderOperation& op)
168    {
169        op = mRenderOp;
170    }
171    //---------------------------------------------------------------------
172    void PanelOverlayElement::setMaterialName(const String& matName)
173    {
174        OverlayContainer::setMaterialName(matName);
175    }
176    //---------------------------------------------------------------------
177    void PanelOverlayElement::_updateRenderQueue(RenderQueue* queue)
178    {
179        if (mVisible)
180        {
181
182            if (!mTransparent && !mpMaterial.isNull())
183            {
184                OverlayElement::_updateRenderQueue(queue);
185            }
186
187            // Also add children
188            ChildIterator it = getChildIterator();
189            while (it.hasMoreElements())
190            {
191                // Give children ZOrder 1 higher than this
192                it.getNext()->_updateRenderQueue(queue);
193            }
194        }
195    }
196    //---------------------------------------------------------------------
197    void PanelOverlayElement::updatePositionGeometry(void)
198    {
199                /*
200                        0-----2
201                        |    /|
202                        |  /  |
203                        |/    |
204                        1-----3
205                */
206                Real left, right, top, bottom;
207
208                /* Convert positions into -1, 1 coordinate space (homogenous clip space).
209                        - Left / right is simple range conversion
210                        - Top / bottom also need inverting since y is upside down - this means
211                        that top will end up greater than bottom and when computing texture
212                        coordinates, we have to flip the v-axis (ie. subtract the value from
213                        1.0 to get the actual correct value).
214                */
215                left = _getDerivedLeft() * 2 - 1;
216                right = left + (mWidth * 2);
217                top = -((_getDerivedTop() * 2) - 1);
218                bottom =  top -  (mHeight * 2);
219
220                HardwareVertexBufferSharedPtr vbuf =
221                        mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
222                float* pPos = static_cast<float*>(
223                        vbuf->lock(HardwareBuffer::HBL_DISCARD) );
224
225                // Use the furthest away depth value, since materials should have depth-check off
226                // This initialised the depth buffer for any 3D objects in front
227                Real zValue = Root::getSingleton().getRenderSystem()->getMaximumDepthInputValue();
228                *pPos++ = left;
229                *pPos++ = top;
230                *pPos++ = zValue;
231
232                *pPos++ = left;
233                *pPos++ = bottom;
234                *pPos++ = zValue;
235
236                *pPos++ = right;
237                *pPos++ = top;
238                *pPos++ = zValue;
239
240                *pPos++ = right;
241                *pPos++ = bottom;
242                *pPos++ = zValue;
243
244                vbuf->unlock();
245    }
246    //---------------------------------------------------------------------
247    void PanelOverlayElement::updateTextureGeometry(void)
248    {
249        // Generate for as many texture layers as there are in material
250        if (!mpMaterial.isNull() && mInitialised)
251        {
252            // Assume one technique and pass for the moment
253            size_t numLayers = mpMaterial->getTechnique(0)->getPass(0)->getNumTextureUnitStates();
254
255            VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
256            // Check the number of texcoords we have in our buffer now
257            if (mNumTexCoordsInBuffer > numLayers)
258            {
259                // remove extras
260                for (size_t i = mNumTexCoordsInBuffer; i > numLayers; --i)
261                {
262                    decl->removeElement(VES_TEXTURE_COORDINATES, i);
263                }
264            }
265            else if (mNumTexCoordsInBuffer < numLayers)
266            {
267                // Add extra texcoord elements
268                size_t offset = VertexElement::getTypeSize(VET_FLOAT2) * mNumTexCoordsInBuffer;
269                for (size_t i = mNumTexCoordsInBuffer; i < numLayers; ++i)
270                {
271                    decl->addElement(TEXCOORD_BINDING,
272                        offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, i);
273                    offset += VertexElement::getTypeSize(VET_FLOAT2);
274
275                }
276            }
277
278            // if number of layers changed at all, we'll need to reallocate buffer
279            if (mNumTexCoordsInBuffer != numLayers)
280            {
281                // NB reference counting will take care of the old one if it exists
282                HardwareVertexBufferSharedPtr newbuf =
283                    HardwareBufferManager::getSingleton().createVertexBuffer(
284                    decl->getVertexSize(TEXCOORD_BINDING), mRenderOp.vertexData->vertexCount,
285                    HardwareBuffer::HBU_STATIC_WRITE_ONLY // mostly static except during resizing
286                    );
287                // Bind buffer, note this will unbind the old one and destroy the buffer it had
288                mRenderOp.vertexData->vertexBufferBinding->setBinding(TEXCOORD_BINDING, newbuf);
289                // Set num tex coords in use now
290                mNumTexCoordsInBuffer = numLayers;
291            }
292
293            // Get the tcoord buffer & lock
294                        if (mNumTexCoordsInBuffer)
295                        {
296                                HardwareVertexBufferSharedPtr vbuf =
297                                        mRenderOp.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING);
298                                float* pVBStart = static_cast<float*>(
299                                        vbuf->lock(HardwareBuffer::HBL_DISCARD) );
300
301                                size_t uvSize = VertexElement::getTypeSize(VET_FLOAT2) / sizeof(float);
302                                size_t vertexSize = decl->getVertexSize(TEXCOORD_BINDING) / sizeof(float);
303                                for (ushort i = 0; i < numLayers; ++i)
304                                {
305                                    // Calc upper tex coords
306                    Real upperX = mU2 * mTileX[i];
307                    Real upperY = mV2 * mTileY[i];
308
309
310                                    /*
311                                            0-----2
312                                            |    /|
313                                            |  /  |
314                                            |/    |
315                                            1-----3
316                                    */
317                                    // Find start offset for this set
318                                    float* pTex = pVBStart + (i * uvSize);
319
320                    pTex[0] = mU1;
321                    pTex[1] = mV1;
322
323                    pTex += vertexSize; // jump by 1 vertex stride
324                    pTex[0] = mU1;
325                    pTex[1] = upperY;
326
327                    pTex += vertexSize;
328                    pTex[0] = upperX;
329                    pTex[1] = mV1;
330
331                    pTex += vertexSize;
332                    pTex[0] = upperX;
333                    pTex[1] = upperY;
334                                }
335                                vbuf->unlock();
336                        }
337        }
338    }
339    //-----------------------------------------------------------------------
340    void PanelOverlayElement::addBaseParameters(void)
341    {
342        OverlayContainer::addBaseParameters();
343        ParamDictionary* dict = getParamDictionary();
344
345        dict->addParameter(ParameterDef("uv_coords",
346           "The texture coordinates for the texture. 1 set of uv values."
347           , PT_STRING),
348           &msCmdUVCoords);
349
350        dict->addParameter(ParameterDef("tiling",
351            "The number of times to repeat the background texture."
352            , PT_STRING),
353            &msCmdTiling);
354
355        dict->addParameter(ParameterDef("transparent",
356            "Sets whether the panel is transparent, i.e. invisible itself "
357            "but it's contents are still displayed."
358            , PT_BOOL),
359            &msCmdTransparent);
360    }
361    //-----------------------------------------------------------------------
362    // Command objects
363    //-----------------------------------------------------------------------
364    String PanelOverlayElement::CmdTiling::doGet(const void* target) const
365    {
366        // NB only returns 1st layer tiling
367        String ret = "0 " + StringConverter::toString(
368            static_cast<const PanelOverlayElement*>(target)->getTileX() );
369        ret += " " + StringConverter::toString(
370            static_cast<const PanelOverlayElement*>(target)->getTileY() );
371        return ret;
372    }
373    void PanelOverlayElement::CmdTiling::doSet(void* target, const String& val)
374    {
375        // 3 params: <layer> <x_tile> <y_tile>
376        // Param count is validated higher up
377        std::vector<String> vec = StringUtil::split(val);
378        ushort layer = (ushort)StringConverter::parseUnsignedInt(vec[0]);
379        Real x_tile = StringConverter::parseReal(vec[1]);
380        Real y_tile = StringConverter::parseReal(vec[2]);
381
382        static_cast<PanelOverlayElement*>(target)->setTiling(x_tile, y_tile, layer);
383    }
384    //-----------------------------------------------------------------------
385    String PanelOverlayElement::CmdTransparent::doGet(const void* target) const
386    {
387        return StringConverter::toString(
388            static_cast<const PanelOverlayElement*>(target)->isTransparent() );
389    }
390    void PanelOverlayElement::CmdTransparent::doSet(void* target, const String& val)
391    {
392        static_cast<PanelOverlayElement*>(target)->setTransparent(
393            StringConverter::parseBool(val));
394    }
395    //-----------------------------------------------------------------------
396    String PanelOverlayElement::CmdUVCoords::doGet(const void* target) const
397    {
398        Real u1, v1, u2, v2;
399
400        static_cast<const PanelOverlayElement*>(target)->getUV(u1, v1, u2, v2);
401        String ret = " " + StringConverter::toString(u1) + " "
402             + StringConverter::toString(v1) + " " + StringConverter::toString(u2) + " "
403             + StringConverter::toString(v2);
404
405        return ret;
406    }
407    void PanelOverlayElement::CmdUVCoords::doSet(void* target, const String& val)
408    {
409        std::vector<String> vec = StringUtil::split(val);
410
411        static_cast<PanelOverlayElement*>(target)->setUV(
412            StringConverter::parseReal(vec[0]),
413            StringConverter::parseReal(vec[1]),
414            StringConverter::parseReal(vec[2]),
415            StringConverter::parseReal(vec[3])
416            );
417    }
418
419}
420
421
422
Note: See TracBrowser for help on using the repository browser.