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-2013 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 #include "OgreSimpleRenderable.h"
32 #include "OgreHardwareBufferManager.h"
33 #include "OgreCamera.h"
34 
35 namespace Ogre {
36 #define POSITION_BINDING 0
37 #define NORMAL_BINDING 1
38 #define TEXCOORD_BINDING 2
39 
Rectangle2D(bool includeTextureCoords,Ogre::HardwareBuffer::Usage vBufUsage)40 	Rectangle2D::Rectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage)
41 	: SimpleRenderable()
42 	{
43 		_initRectangle2D(includeTextureCoords, vBufUsage);
44 	}
45 
Rectangle2D(const String & name,bool includeTextureCoords,Ogre::HardwareBuffer::Usage vBufUsage)46 	Rectangle2D::Rectangle2D(const String& name, bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage)
47 	: SimpleRenderable(name)
48 	{
49 		_initRectangle2D(includeTextureCoords, vBufUsage);
50 	}
51 
_initRectangle2D(bool includeTextureCoords,Ogre::HardwareBuffer::Usage vBufUsage)52 	void Rectangle2D::_initRectangle2D(bool includeTextureCoords, Ogre::HardwareBuffer::Usage vBufUsage)
53     {
54         // use identity projection and view matrices
55         mUseIdentityProjection = true;
56         mUseIdentityView = true;
57 
58         mRenderOp.vertexData = OGRE_NEW VertexData();
59 
60         mRenderOp.indexData = 0;
61         mRenderOp.vertexData->vertexCount = 4;
62         mRenderOp.vertexData->vertexStart = 0;
63         mRenderOp.operationType = RenderOperation::OT_TRIANGLE_STRIP;
64         mRenderOp.useIndexes = false;
65         mRenderOp.useGlobalInstancingVertexBufferIsAvailable = false;
66 
67         VertexDeclaration* decl = mRenderOp.vertexData->vertexDeclaration;
68         VertexBufferBinding* bind = mRenderOp.vertexData->vertexBufferBinding;
69 
70         decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
71 
72 
73         HardwareVertexBufferSharedPtr vbuf =
74             HardwareBufferManager::getSingleton().createVertexBuffer(
75             decl->getVertexSize(POSITION_BINDING),
76             mRenderOp.vertexData->vertexCount,
77             vBufUsage);
78 
79         // Bind buffer
80         bind->setBinding(POSITION_BINDING, vbuf);
81 
82 		decl->addElement(NORMAL_BINDING, 0, VET_FLOAT3, VES_NORMAL);
83 
84 		vbuf =
85 			HardwareBufferManager::getSingleton().createVertexBuffer(
86             decl->getVertexSize(NORMAL_BINDING),
87             mRenderOp.vertexData->vertexCount,
88             vBufUsage);
89 
90 		bind->setBinding(NORMAL_BINDING, vbuf);
91 
92 		float *pNorm = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
93 		*pNorm++ = 0.0f;
94 		*pNorm++ = 0.0f;
95 		*pNorm++ = 1.0f;
96 
97 		*pNorm++ = 0.0f;
98 		*pNorm++ = 0.0f;
99 		*pNorm++ = 1.0f;
100 
101 		*pNorm++ = 0.0f;
102 		*pNorm++ = 0.0f;
103 		*pNorm++ = 1.0f;
104 
105 		*pNorm++ = 0.0f;
106 		*pNorm++ = 0.0f;
107 		*pNorm++ = 1.0f;
108 
109 		vbuf->unlock();
110 
111         if (includeTextureCoords)
112         {
113             decl->addElement(TEXCOORD_BINDING, 0, VET_FLOAT2, VES_TEXTURE_COORDINATES);
114 
115 
116             HardwareVertexBufferSharedPtr tvbuf =
117                 HardwareBufferManager::getSingleton().createVertexBuffer(
118                 decl->getVertexSize(TEXCOORD_BINDING),
119                 mRenderOp.vertexData->vertexCount,
120                 vBufUsage);
121 
122             // Bind buffer
123             bind->setBinding(TEXCOORD_BINDING, tvbuf);
124 
125             // Set up basic tex coordinates
126             setDefaultUVs();
127         }
128 
129         // set basic white material
130         this->setMaterial("BaseWhiteNoLighting");
131     }
132 
~Rectangle2D()133     Rectangle2D::~Rectangle2D()
134     {
135         OGRE_DELETE mRenderOp.vertexData;
136     }
137 
setCorners(Real left,Real top,Real right,Real bottom,bool updateAABB)138     void Rectangle2D::setCorners(Real left, Real top, Real right, Real bottom, bool updateAABB)
139     {
140         HardwareVertexBufferSharedPtr vbuf =
141             mRenderOp.vertexData->vertexBufferBinding->getBuffer(POSITION_BINDING);
142         float* pFloat = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
143 
144         *pFloat++ = left;
145         *pFloat++ = top;
146         *pFloat++ = -1;
147 
148         *pFloat++ = left;
149         *pFloat++ = bottom;
150         *pFloat++ = -1;
151 
152         *pFloat++ = right;
153         *pFloat++ = top;
154         *pFloat++ = -1;
155 
156         *pFloat++ = right;
157         *pFloat++ = bottom;
158         *pFloat++ = -1;
159 
160         vbuf->unlock();
161 
162 		if(updateAABB)
163 		{
164 			mBox.setExtents(
165 				std::min(left, right), std::min(top, bottom), 0,
166 				std::max(left, right), std::max(top, bottom), 0);
167 		}
168     }
169 
setNormals(const Ogre::Vector3 & topLeft,const Ogre::Vector3 & bottomLeft,const Ogre::Vector3 & topRight,const Ogre::Vector3 & bottomRight)170 	void Rectangle2D::setNormals(const Ogre::Vector3 &topLeft, const Ogre::Vector3 &bottomLeft, const Ogre::Vector3 &topRight, const Ogre::Vector3 &bottomRight)
171 	{
172 		HardwareVertexBufferSharedPtr vbuf =
173             mRenderOp.vertexData->vertexBufferBinding->getBuffer(NORMAL_BINDING);
174         float* pFloat = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
175 
176         *pFloat++ = topLeft.x;
177         *pFloat++ = topLeft.y;
178         *pFloat++ = topLeft.z;
179 
180         *pFloat++ = bottomLeft.x;
181         *pFloat++ = bottomLeft.y;
182         *pFloat++ = bottomLeft.z;
183 
184         *pFloat++ = topRight.x;
185         *pFloat++ = topRight.y;
186         *pFloat++ = topRight.z;
187 
188         *pFloat++ = bottomRight.x;
189         *pFloat++ = bottomRight.y;
190         *pFloat++ = bottomRight.z;
191 
192         vbuf->unlock();
193 	}
194 
setUVs(const Ogre::Vector2 & topLeft,const Ogre::Vector2 & bottomLeft,const Ogre::Vector2 & topRight,const Ogre::Vector2 & bottomRight)195 	void Rectangle2D::setUVs( const Ogre::Vector2 &topLeft, const Ogre::Vector2 &bottomLeft,
196 								const Ogre::Vector2 &topRight, const Ogre::Vector2 &bottomRight)
197 	{
198 		if( mRenderOp.vertexData->vertexDeclaration->getElementCount() <= TEXCOORD_BINDING )
199 			return; //Vertex data wasn't built with UV buffer
200 
201 		HardwareVertexBufferSharedPtr vbuf =
202             mRenderOp.vertexData->vertexBufferBinding->getBuffer(TEXCOORD_BINDING);
203         float* pFloat = static_cast<float*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
204 
205         *pFloat++ = topLeft.x;
206         *pFloat++ = topLeft.y;
207 
208         *pFloat++ = bottomLeft.x;
209         *pFloat++ = bottomLeft.y;
210 
211         *pFloat++ = topRight.x;
212         *pFloat++ = topRight.y;
213 
214         *pFloat++ = bottomRight.x;
215         *pFloat++ = bottomRight.y;
216 
217         vbuf->unlock();
218 	}
219 
setDefaultUVs()220 	void Rectangle2D::setDefaultUVs()
221 	{
222 		setUVs( Vector2::ZERO, Vector2::UNIT_Y, Vector2::UNIT_X, Vector2::UNIT_SCALE );
223 	}
224 
225     // Override this method to prevent parent transforms (rotation,translation,scale)
getWorldTransforms(Matrix4 * xform) const226     void Rectangle2D::getWorldTransforms( Matrix4* xform ) const
227     {
228         // return identity matrix to prevent parent transforms
229         *xform = Matrix4::IDENTITY;
230     }
231 
232 
233 }
234 
235