1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #include "OgreStableHeaders.h"
29 #include "OgreRectangle2D.h"
30 
31 namespace Ogre {
32 #define POSITION_BINDING 0
33 #define NORMAL_BINDING 1
34 #define TEXCOORD_BINDING 2
35 
Rectangle2D(bool includeTextureCoords,Ogre::HardwareBuffer::Usage vBufUsage)36     Rectangle2D::Rectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage)
37     : SimpleRenderable()
38     {
39         _initRectangle2D(includeTextureCoords, vBufUsage);
40     }
41 
Rectangle2D(const String & name,bool includeTextureCoords,Ogre::HardwareBuffer::Usage vBufUsage)42     Rectangle2D::Rectangle2D(const String& name, bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage)
43     : SimpleRenderable(name)
44     {
45         _initRectangle2D(includeTextureCoords, vBufUsage);
46     }
47 
_initRectangle2D(bool includeTextureCoords,Ogre::HardwareBuffer::Usage vBufUsage)48     void Rectangle2D::_initRectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage)
49     {
50         // use identity projection and view matrices
51         mUseIdentityProjection = true;
52         mUseIdentityView = true;
53 
54         mRenderOp.vertexData = OGRE_NEW VertexData();
55 
56         mRenderOp.indexData = 0;
57         mRenderOp.vertexData->vertexCount = 4;
58         mRenderOp.vertexData->vertexStart = 0;
59         mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP;
60         mRenderOp.useIndexes = false;
61         mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false;
62 
63         VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
64         VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
65 
66         decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
67 
68 
69         HardwareVertexBufferSharedPtr vbuf =
70             HardwareBufferManager::getSingleton().createVertexBuffer(
71             decl->getVertexSize(POSITION_BINDING),
72             mRenderOp.vertexData->vertexCount,
73             vBufUsage);
74 
75         // Bind buffer
76         bind->setBinding(POSITION_BINDING, vbuf);
77 
78         decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL);
79 
80         vbuf =
81             HardwareBufferManager::getSingleton().createVertexBuffer(
82             decl->getVertexSize(NORMAL_BINDING),
83             mRenderOp.vertexData->vertexCount,
84             vBufUsage);
85 
86         bind->setBinding(NORMAL_BINDING, vbuf);
87 
88         HardwareBufferLockGuard vbufLock(vbuf, HardwareBuffer::HBL_DISCARD);
89         float *pNorm = static_cast<float*>(vbufLock.pData);
90         *pNorm++ = 0.0f;
91         *pNorm++ = 0.0f;
92         *pNorm++ = 1.0f;
93 
94         *pNorm++ = 0.0f;
95         *pNorm++ = 0.0f;
96         *pNorm++ = 1.0f;
97 
98         *pNorm++ = 0.0f;
99         *pNorm++ = 0.0f;
100         *pNorm++ = 1.0f;
101 
102         *pNorm++ = 0.0f;
103         *pNorm++ = 0.0f;
104         *pNorm++ = 1.0f;
105 
106         vbufLock.unlock();
107 
108         if (includeTextureCoords)
109         {
110             decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
111 
112 
113             HardwareVertexBufferSharedPtr tvbuf =
114                 HardwareBufferManager::getSingleton().createVertexBuffer(
115                 decl->getVertexSize(TEXCOORD_BINDING),
116                 mRenderOp.vertexData->vertexCount,
117                 vBufUsage);
118 
119             // Bind buffer
120             bind->setBinding(TEXCOORD_BINDING, tvbuf);
121 
122             // Set up basic tex coordinates
123             setDefaultUVs();
124         }
125 
126         // set basic white material
127         mMaterial = MaterialManager::getSingleton().getDefaultMaterial(false);
128         mMaterial->load();
129     }
130 
~Rectangle2D()131     Rectangle2D::~Rectangle2D()
132     {
133         OGRE_DELETE mRenderOp.vertexData;
134     }
135 
setCorners(Real left,Real top,Real right,Real bottom,bool updateAABB)136     void Rectangle2D::setCorners(Real left, Real top, Real right, Real bottom, bool updateAABB)
137     {
138         HardwareVertexBufferSharedPtr vbuf =
139             mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
140         HardwareBufferLockGuard vbufLock(vbuf, HardwareBuffer::HBL_DISCARD);
141         float* pFloat = static_cast<float*>(vbufLock.pData);
142 
143         *pFloat++ = left;
144         *pFloat++ = top;
145         *pFloat++ = -1;
146 
147         *pFloat++ = left;
148         *pFloat++ = bottom;
149         *pFloat++ = -1;
150 
151         *pFloat++ = right;
152         *pFloat++ = top;
153         *pFloat++ = -1;
154 
155         *pFloat++ = right;
156         *pFloat++ = bottom;
157         *pFloat++ = -1;
158 
159         if(updateAABB)
160         {
161             mBox.setExtents(
162                 std::min(left, right), std::min(top, bottom), 0,
163                 std::max(left, right), std::max(top, bottom), 0);
164         }
165     }
166 
setNormals(const Ogre::Vector3 & topLeft,const Ogre::Vector3 & bottomLeft,const Ogre::Vector3 & topRight,const Ogre::Vector3 & bottomRight)167     void Rectangle2D::setNormals(const Ogre::Vector3 &topLeft, const Ogre::Vector3 &bottomLeft, const Ogre::Vector3 &topRight, const Ogre::Vector3 &bottomRight)
168     {
169         HardwareVertexBufferSharedPtr vbuf =
170             mRenderOp.vertexData->vertexBufferBinding->getBuffer(NORMAL_BINDING);
171         HardwareBufferLockGuard vbufLock(vbuf, HardwareBuffer::HBL_DISCARD);
172         float* pFloat = static_cast<float*>(vbufLock.pData);
173 
174         *pFloat++ = topLeft.x;
175         *pFloat++ = topLeft.y;
176         *pFloat++ = topLeft.z;
177 
178         *pFloat++ = bottomLeft.x;
179         *pFloat++ = bottomLeft.y;
180         *pFloat++ = bottomLeft.z;
181 
182         *pFloat++ = topRight.x;
183         *pFloat++ = topRight.y;
184         *pFloat++ = topRight.z;
185 
186         *pFloat++ = bottomRight.x;
187         *pFloat++ = bottomRight.y;
188         *pFloat++ = bottomRight.z;
189     }
190 
setUVs(const Ogre::Vector2 & topLeft,const Ogre::Vector2 & bottomLeft,const Ogre::Vector2 & topRight,const Ogre::Vector2 & bottomRight)191     void Rectangle2D::setUVs( const Ogre::Vector2 &topLeft, const Ogre::Vector2 &bottomLeft,
192                                 const Ogre::Vector2 &topRight, const Ogre::Vector2 &bottomRight)
193     {
194         OgreAssert(mRenderOp.vertexData->vertexDeclaration->getElementCount() > TEXCOORD_BINDING,
195                    "Vertex data wasn't built with UV buffer");
196 
197         HardwareVertexBufferSharedPtr vbuf =
198             mRenderOp.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING);
199         HardwareBufferLockGuard vbufLock(vbuf, HardwareBuffer::HBL_DISCARD);
200         float* pFloat = static_cast<float*>(vbufLock.pData);
201 
202         *pFloat++ = topLeft.x;
203         *pFloat++ = topLeft.y;
204 
205         *pFloat++ = bottomLeft.x;
206         *pFloat++ = bottomLeft.y;
207 
208         *pFloat++ = topRight.x;
209         *pFloat++ = topRight.y;
210 
211         *pFloat++ = bottomRight.x;
212         *pFloat++ = bottomRight.y;
213     }
214 
setDefaultUVs()215     void Rectangle2D::setDefaultUVs()
216     {
217         setUVs( Vector2::ZERO, Vector2::UNIT_Y, Vector2::UNIT_X, Vector2::UNIT_SCALE );
218     }
219 
220     // Override this method to prevent parent transforms (rotation,translation,scale)
getWorldTransforms(Matrix4 * xform) const221     void Rectangle2D::getWorldTransforms( Matrix4* xform ) const
222     {
223         // return identity matrix to prevent parent transforms
224         *xform = Matrix4::IDENTITY;
225     }
226 
227 
228 }
229 
230