1 /***********************************************************************
2 created: Thu Jan 8 2009
3 author: Paul D Turner
4 *************************************************************************/
5 /***************************************************************************
6 * Copyright (C) 2004 - 2009 Paul D Turner & The CEGUI Development Team
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be
17 * included in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 ***************************************************************************/
27 #include "CEGUI/RendererModules/OpenGLES/GeometryBuffer.h"
28 #include "CEGUI/RenderEffect.h"
29 #include "CEGUI/RendererModules/OpenGLES/Texture.h"
30 #include "CEGUI/Vertex.h"
31
32 // Start of CEGUI namespace section
33 namespace CEGUI
34 {
35 //----------------------------------------------------------------------------//
OpenGLESGeometryBuffer()36 OpenGLESGeometryBuffer::OpenGLESGeometryBuffer() :
37 d_activeTexture(0),
38 d_clipRect(0, 0, 0, 0),
39 d_clippingActive(true),
40 d_translation(0, 0, 0),
41 d_rotation(0, 0, 0),
42 d_pivot(0, 0, 0),
43 d_effect(0),
44 d_matrixValid(false)
45 {
46 //d_matrix does not need to be initialised here, we have d_matrixValid
47 //for(unsigned int i = 0; i < 16;++i)
48 // d_matrix[i]=0.0;
49 }
50
51 //----------------------------------------------------------------------------//
appendVertex(const Vertex & vertex)52 void OpenGLESGeometryBuffer::appendVertex(const Vertex& vertex)
53 {
54 appendGeometry(&vertex, 1);
55 }
56
57 //----------------------------------------------------------------------------//
draw() const58 void OpenGLESGeometryBuffer::draw() const
59 {
60 // setup clip region
61 GLint vp[4];
62 glGetIntegerv(GL_VIEWPORT, vp);
63 glScissor(static_cast<GLint>(d_clipRect.left()),
64 static_cast<GLint>(vp[3] - d_clipRect.bottom()),
65 static_cast<GLint>(d_clipRect.getWidth()),
66 static_cast<GLint>(d_clipRect.getHeight()));
67
68 // apply the transformations we need to use.
69 if (!d_matrixValid)
70 updateMatrix();
71
72 glMatrixMode(GL_MODELVIEW);
73 glLoadMatrixf(d_matrix);
74
75 const int pass_count = d_effect ? d_effect->getPassCount() : 1;
76 for (int pass = 0; pass < pass_count; ++pass)
77 {
78 // set up RenderEffect
79 if (d_effect)
80 d_effect->performPreRenderFunctions(pass);
81
82 // draw the batches
83 size_t pos = 0;
84 BatchList::const_iterator i = d_batches.begin();
85 for ( ; i != d_batches.end(); ++i)
86 {
87 glBindTexture(GL_TEXTURE_2D, (*i).first);
88 // set up pointers to the vertex element arrays
89 glTexCoordPointer(2, GL_FLOAT, sizeof(GLVertex),
90 &d_vertices[pos]);
91 glColorPointer(4, GL_FLOAT, sizeof(GLVertex),
92 &d_vertices[pos].colour[0]);
93 glVertexPointer(3, GL_FLOAT, sizeof(GLVertex),
94 &d_vertices[pos].position[0]);
95 // draw the geometry
96 glDrawArrays(GL_TRIANGLES, 0, (*i).second);
97 pos += (*i).second;
98 }
99 }
100
101 // clean up RenderEffect
102 if (d_effect)
103 d_effect->performPostRenderFunctions();
104 }
105
106 //----------------------------------------------------------------------------//
setTranslation(const Vector3f & v)107 void OpenGLESGeometryBuffer::setTranslation(const Vector3f& v)
108 {
109 d_translation = v;
110 d_matrixValid = false;
111 }
112
113 //----------------------------------------------------------------------------//
setRotation(const Quaternion & r)114 void OpenGLESGeometryBuffer::setRotation(const Quaternion& r)
115 {
116 d_rotation = r;
117 d_matrixValid = false;
118 }
119
120 //----------------------------------------------------------------------------//
setPivot(const Vector3f & p)121 void OpenGLESGeometryBuffer::setPivot(const Vector3f& p)
122 {
123 d_pivot = Vector3f(p.d_x, p.d_y, p.d_z);
124 d_matrixValid = false;
125 }
126
127 //----------------------------------------------------------------------------//
setClippingRegion(const Rectf & region)128 void OpenGLESGeometryBuffer::setClippingRegion(const Rectf& region)
129 {
130 d_clipRect = region;
131 }
132
133 //----------------------------------------------------------------------------//
appendGeometry(const Vertex * const vbuff,uint vertex_count)134 void OpenGLESGeometryBuffer::appendGeometry(const Vertex* const vbuff,
135 uint vertex_count)
136 {
137 performBatchManagement();
138
139 // update size of current batch
140 d_batches.back().second += vertex_count;
141
142 // buffer these vertices
143 GLVertex vd;
144 const Vertex* vs = vbuff;
145 for (uint i = 0; i < vertex_count; ++i, ++vs)
146 {
147 // copy vertex info the buffer, converting from CEGUI::Vertex to
148 // something directly usable by OpenGLES as needed.
149 vd.tex[0] = vs->tex_coords.d_x;
150 vd.tex[1] = vs->tex_coords.d_y;
151 vd.colour[0] = vs->colour_val.getRed();
152 vd.colour[1] = vs->colour_val.getGreen();
153 vd.colour[2] = vs->colour_val.getBlue();
154 vd.colour[3] = vs->colour_val.getAlpha();
155 vd.position[0] = vs->position.d_x;
156 vd.position[1] = vs->position.d_y;
157 vd.position[2] = vs->position.d_z;
158 d_vertices.push_back(vd);
159 }
160 }
161
162 //----------------------------------------------------------------------------//
setActiveTexture(Texture * texture)163 void OpenGLESGeometryBuffer::setActiveTexture(Texture* texture)
164 {
165 d_activeTexture = static_cast<OpenGLESTexture*>(texture);
166 }
167
168 //----------------------------------------------------------------------------//
reset()169 void OpenGLESGeometryBuffer::reset()
170 {
171 d_batches.clear();
172 d_vertices.clear();
173 d_activeTexture = 0;
174 }
175
176 //----------------------------------------------------------------------------//
getActiveTexture() const177 Texture* OpenGLESGeometryBuffer::getActiveTexture() const
178 {
179 return d_activeTexture;
180 }
181
182 //----------------------------------------------------------------------------//
getVertexCount() const183 uint OpenGLESGeometryBuffer::getVertexCount() const
184 {
185 return d_vertices.size();
186 }
187
188 //----------------------------------------------------------------------------//
getBatchCount() const189 uint OpenGLESGeometryBuffer::getBatchCount() const
190 {
191 return d_batches.size();
192 }
193
194 //----------------------------------------------------------------------------//
performBatchManagement()195 void OpenGLESGeometryBuffer::performBatchManagement()
196 {
197 const GLuint gltex = d_activeTexture ?
198 d_activeTexture->getOpenGLESTexture() : 0;
199
200 // create a new batch if there are no batches yet, or if the active texture
201 // differs from that used by the current batch.
202 if (d_batches.empty() || (gltex != d_batches.back().first))
203 d_batches.push_back(BatchInfo(gltex, 0));
204 }
205
206 //----------------------------------------------------------------------------//
setRenderEffect(RenderEffect * effect)207 void OpenGLESGeometryBuffer::setRenderEffect(RenderEffect* effect)
208 {
209 d_effect = effect;
210 }
211
212 //----------------------------------------------------------------------------//
getRenderEffect()213 RenderEffect* OpenGLESGeometryBuffer::getRenderEffect()
214 {
215 return d_effect;
216 }
217
218 //----------------------------------------------------------------------------//
getMatrix() const219 const float* OpenGLESGeometryBuffer::getMatrix() const
220 {
221 if (!d_matrixValid)
222 updateMatrix();
223
224 return d_matrix;
225 }
226
227 //----------------------------------------------------------------------------//
updateMatrix() const228 void OpenGLESGeometryBuffer::updateMatrix() const
229 {
230 glMatrixMode(GL_MODELVIEW);
231 glPushMatrix();
232
233 const Vector3f final_trans(d_translation.d_x + d_pivot.d_x,
234 d_translation.d_y + d_pivot.d_y,
235 d_translation.d_z + d_pivot.d_z);
236
237 glLoadIdentity();
238 glTranslatef(final_trans.d_x, final_trans.d_y, final_trans.d_z);
239
240 float rotation_matrix[16];
241 rotation_matrix[ 0] = 1.0f - 2.0f * (d_rotation.d_y * d_rotation.d_y + d_rotation.d_z * d_rotation.d_z);
242 rotation_matrix[ 1] = 2.0f * (d_rotation.d_x * d_rotation.d_y + d_rotation.d_z * d_rotation.d_w);
243 rotation_matrix[ 2] = 2.0f * (d_rotation.d_x * d_rotation.d_z - d_rotation.d_y * d_rotation.d_w);
244 rotation_matrix[ 3] = 0.0f;
245
246 rotation_matrix[ 4] = 2.0f * (d_rotation.d_x * d_rotation.d_y - d_rotation.d_z * d_rotation.d_w);
247 rotation_matrix[ 5] = 1.0f - 2.0f * (d_rotation.d_x * d_rotation.d_x + d_rotation.d_z * d_rotation.d_z);
248 rotation_matrix[ 6] = 2.0f * (d_rotation.d_z * d_rotation.d_y + d_rotation.d_x * d_rotation.d_w);
249 rotation_matrix[ 7] = 0.0f;
250
251 rotation_matrix[ 8] = 2.0f * (d_rotation.d_x * d_rotation.d_z + d_rotation.d_y * d_rotation.d_w);
252 rotation_matrix[ 9] = 2.0f * (d_rotation.d_y * d_rotation.d_z - d_rotation.d_x * d_rotation.d_w);
253 rotation_matrix[10] = 1.0f - 2.0f * (d_rotation.d_x * d_rotation.d_x + d_rotation.d_y * d_rotation.d_y);
254 rotation_matrix[11] = 0.0f;
255
256 rotation_matrix[12] = 0.0f;
257 rotation_matrix[13] = 0.0f;
258 rotation_matrix[14] = 0.0f;
259 rotation_matrix[15] = 1.0f;
260
261 glMultMatrixf(rotation_matrix);
262
263 glTranslatef(-d_pivot.d_x, -d_pivot.d_y, -d_pivot.d_z);
264
265 glGetFloatv(GL_MODELVIEW_MATRIX, d_matrix);
266 glPopMatrix();
267
268 d_matrixValid = true;
269 }
270
271 //----------------------------------------------------------------------------//
setClippingActive(const bool active)272 void OpenGLESGeometryBuffer::setClippingActive(const bool active)
273 {
274 d_clippingActive = active;
275 }
276
277 //----------------------------------------------------------------------------//
isClippingActive() const278 bool OpenGLESGeometryBuffer::isClippingActive() const
279 {
280 return d_clippingActive;
281 }
282 //----------------------------------------------------------------------------//
283
284 } // End of CEGUI namespace section
285