Angel 3.2
A 2D Game Prototyping Engine
GwenRenderer.cpp
1 
2 // Copyright (C) 2008-2013, Shane Liesegang
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of the copyright holder nor the names of any
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 // POSSIBILITY OF SUCH DAMAGE.
29 
30 #include "stdafx.h"
31 #include "../UI/GwenRenderer.h"
32 
33 #include "Gwen/Utility.h"
34 #include "Gwen/Font.h"
35 #include "Gwen/Texture.h"
36 #include "Gwen/WindowProvider.h"
37 
38 #include "../Infrastructure/Textures.h"
39 #include "../Infrastructure/TextRendering.h"
40 #include "../Infrastructure/Camera.h"
41 #include "../Infrastructure/Log.h"
42 #include "../Util/MathUtil.h"
43 #include "../Util/DrawUtil.h"
44 
45 
46 
47 GwenRenderer::GwenRenderer(const String& texturePath)
48 {
49  _vertNum = 0;
50 
51  for (int i=0; i < s_maxVerts; i++)
52  {
53  _vertices[ i ].z = 0.5f;
54  }
55 
56  _windowWidth = _windowHeight = 0;
57 
58  GetRawImageData(texturePath, _skinTexture);
59 }
60 
61 GwenRenderer::~GwenRenderer()
62 {
63 
64 }
65 
66 
67 void GwenRenderer::FinishInit()
68 {
69  _skinTexture.clear(); // just saving memory
70 }
71 
72 void GwenRenderer::Begin()
73 {
74  glAlphaFunc( GL_GREATER, 1.0f );
75 
76  _windowWidth = theCamera.GetWindowWidth();
77  _windowHeight = theCamera.GetWindowHeight();
78 
79  //set up projection
80  glMatrixMode(GL_PROJECTION);
81  glPushMatrix();
82  glLoadIdentity();
83  gluOrtho2D(0, _windowWidth, _windowHeight, 0);
84 
85  //set up modelview
86  glMatrixMode(GL_MODELVIEW);
87  glPushMatrix();
88  glLoadIdentity();
89 }
90 
91 void GwenRenderer::End()
92 {
93  Flush();
94  glAlphaFunc(GL_ALWAYS, 0.0f);
95 
96  glDisableClientState( GL_COLOR_ARRAY );
97  glDisable(GL_TEXTURE_2D);
98 
99  glMatrixMode(GL_MODELVIEW);
100  glPopMatrix();
101  glMatrixMode(GL_PROJECTION);
102  glPopMatrix();
103 }
104 
105 void GwenRenderer::Flush()
106 {
107  if ( _vertNum == 0 )
108  {
109  return;
110  }
111 
112  glVertexPointer( 3, GL_FLOAT, sizeof(Vertex), (void*) &_vertices[0].x );
113  glEnableClientState( GL_VERTEX_ARRAY );
114 
115  glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof(Vertex), (void*)&_vertices[0].r );
116  glEnableClientState( GL_COLOR_ARRAY );
117 
118  glTexCoordPointer( 2, GL_FLOAT, sizeof(Vertex), (void*) &_vertices[0].u );
119  glEnableClientState( GL_TEXTURE_COORD_ARRAY );
120 
121  glDrawArrays( GL_TRIANGLES, 0, (GLsizei) _vertNum );
122 
123  _vertNum = 0;
124 }
125 
126 void GwenRenderer::AddVertex(int x, int y, float u, float v)
127 {
128  if ( _vertNum >= s_maxVerts - 1 )
129  {
130  Flush();
131  }
132 
133  _vertices[ _vertNum ].x = (float)x;
134  _vertices[ _vertNum ].y = (float)y;
135  _vertices[ _vertNum ].u = u;
136  _vertices[ _vertNum ].v = v;
137 
138  _vertices[ _vertNum ].r = _color.r;
139  _vertices[ _vertNum ].g = _color.g;
140  _vertices[ _vertNum ].b = _color.b;
141  _vertices[ _vertNum ].a = _color.a;
142 
143  _vertNum++;
144 }
145 
146 void GwenRenderer::SetDrawColor( Gwen::Color color )
147 {
148  glColor4ub(color.r, color.g, color.b, color.a);
149  //glColor4ubv( (GLubyte*)&color );
150  _color = color;
151 }
152 
153 void GwenRenderer::DrawFilledRect( Gwen::Rect rect )
154 {
155  GLboolean texturesOn;
156 
157  glGetBooleanv(GL_TEXTURE_2D, &texturesOn);
158  if ( texturesOn )
159  {
160  Flush();
161  glDisable(GL_TEXTURE_2D);
162  }
163 
164  Translate( rect );
165 
166  AddVertex( rect.x, rect.y + rect.h );
167  AddVertex( rect.x+rect.w, rect.y );
168  AddVertex( rect.x, rect.y );
169 
170  AddVertex( rect.x, rect.y + rect.h );
171  AddVertex( rect.x+rect.w, rect.y+rect.h );
172  AddVertex( rect.x+rect.w, rect.y );
173 }
174 
175 void GwenRenderer::DrawTexturedRect( Gwen::Texture* texture, Gwen::Rect targetRect, float u1, float v1, float u2, float v2)
176 {
177  GLuint* tex = (GLuint*)texture->data;
178 
179  if (!tex)
180  {
181  return DrawMissingImage(targetRect);
182  }
183 
184  v1 = 1.0f - v1;
185  v2 = 1.0f - v2;
186 
187  Translate(targetRect);
188 
189  glEnable(GL_TEXTURE_2D);
190  glBindTexture(GL_TEXTURE_2D, *tex);
191 
192  AddVertex( targetRect.x, targetRect.y + targetRect.h, u1, v2 );
193  AddVertex( targetRect.x+targetRect.w, targetRect.y, u2, v1 );
194  AddVertex( targetRect.x, targetRect.y, u1, v1 );
195 
196  AddVertex( targetRect.x, targetRect.y + targetRect.h, u1, v2 );
197  AddVertex( targetRect.x+targetRect.w, targetRect.y+targetRect.h, u2, v2 );
198  AddVertex( targetRect.x+targetRect.w, targetRect.y, u2, v1 );
199 }
200 
201 void GwenRenderer::StartClip()
202 {
203  Flush();
204  Gwen::Rect rect = ClipRegion();
205 
206  // OpenGL's coords are from the bottom left
207  // so we need to translate them here.
208  {
209  GLint view[4];
210  glGetIntegerv( GL_VIEWPORT, &view[0] );
211  rect.y = view[3] - (rect.y + rect.h);
212  }
213 
214  glScissor( rect.x * Scale(), rect.y * Scale(), rect.w * Scale(), rect.h * Scale() );
215  glEnable( GL_SCISSOR_TEST );
216 }
217 
218 void GwenRenderer::EndClip()
219 {
220  Flush();
221  glDisable( GL_SCISSOR_TEST );
222 }
223 
224 void GwenRenderer::LoadTexture( Gwen::Texture* texture )
225 {
226  const int texID = GetTextureReference(texture->name.Get());
227  if (texID < 0)
228  {
229  texture->failed = true;
230  texture->data = 0;
231  }
232  else
233  {
234  texture->failed = false;
235  texture->data = new GLuint;
236  *((GLuint*)texture->data) = texID;
237  const Vec2i dimensions = GetTextureSize(texture->name.Get());
238  texture->width = dimensions.X;
239  texture->height = dimensions.Y;
240  }
241 }
242 
243 void GwenRenderer::FreeTexture( Gwen::Texture* texture )
244 {
245  PurgeTexture(texture->name.Get());
246  GLuint* tex = (GLuint*)texture->data;
247  if (tex)
248  {
249  delete tex;
250  texture->data = NULL;
251  }
252 }
253 
254 //void GwenRenderer::DrawMissingImage( Gwen::Rect targetRect )
255 //{
256 //
257 //}
258 
259 Gwen::Color GwenRenderer::PixelColour( Gwen::Texture* texture, unsigned int x, unsigned int y, const Gwen::Color& col_default)
260 {
261  if (texture == NULL)
262  {
263  return col_default;
264  }
265 
266  unsigned int offset = ((texture->height - y) * texture->width) + x;
267  if (offset >= _skinTexture.size())
268  {
269  return col_default;
270  }
271 
272  Gwen::Color c;
273  c.r = int(_skinTexture[offset].R * 255.0f);
274  c.g = int(_skinTexture[offset].G * 255.0f);
275  c.b = int(_skinTexture[offset].B * 255.0f);
276  c.a = int(_skinTexture[offset].A * 255.0f);
277 
278  return c;
279 }
280 
281 //Gwen::Renderer::ICacheToTexture* GwenRenderer::GetCTT()
282 //{
283 // return NULL;
284 //}
285 
286 void GwenRenderer::LoadFont( Gwen::Font* font )
287 {
288  font->realsize = font->size * Scale();
289  String fontName = Gwen::Utility::UnicodeToString(font->facename);
290  _unicodeCache[font->facename] = fontName;
291  if (!IsFontRegistered(fontName))
292  {
293  if (RegisterFont(fontName, font->realsize, fontName))
294  {
295  font->data = (void*)1;
296  }
297  else
298  {
299  font->data = NULL;
300  }
301  }
302 }
303 
304 void GwenRenderer::FreeFont( Gwen::Font* font )
305 {
306  std::map<Gwen::UnicodeString, String>::iterator it = _unicodeCache.find(font->facename);
307  if (it != _unicodeCache.end())
308  {
309  UnRegisterFont(it->second);
310  }
311 }
312 
313 void GwenRenderer::RenderText( Gwen::Font* font, Gwen::Point pos, const Gwen::UnicodeString& text )
314 {
315  Flush();
316  Translate(pos.x, pos.y);
317 
318  String fontConv = Gwen::Utility::UnicodeToString(font->facename);
319  pos.y += GetTextAscenderHeight(fontConv);
320 
321  glColor4ub(_color.r, _color.g, _color.b, _color.a);
322  //glColor4ubv( (GLubyte*)&_color );
323 
324  glMatrixMode(GL_PROJECTION);
325  glLoadIdentity();
326  gluOrtho2D(0, _windowWidth, 0, _windowHeight);
327 
328  DrawGameTextRaw(Gwen::Utility::UnicodeToString(text), fontConv, pos.x, pos.y);
329 
330  glMatrixMode(GL_PROJECTION);
331  glLoadIdentity();
332  gluOrtho2D(0, _windowWidth, _windowHeight, 0);
333  glMatrixMode(GL_MODELVIEW);
334 
335 }
336 
337 Gwen::Point GwenRenderer::MeasureText( Gwen::Font* font, const Gwen::UnicodeString& text )
338 {
339  if (font->data == NULL)
340  {
341  LoadFont(font);
342  }
343  Vector2 extents = GetTextExtents(Gwen::Utility::UnicodeToString(text), Gwen::Utility::UnicodeToString(font->facename));
344  #if ANGEL_MOBILE
345  extents.Y = extents.Y * 2.0f;
346  #endif
347  return Gwen::Point(MathUtil::RoundToInt(extents.X), MathUtil::RoundToInt(extents.Y));
348 }
349