1
2 #ifndef __GWEN_OPENGL3_CORE_RENDERER_H
3 #define __GWEN_OPENGL3_CORE_RENDERER_H
4
5 #include "Gwen/Gwen.h"
6 #include "Gwen/BaseRender.h"
7 #include "GLPrimitiveRenderer.h"
8 #include "../OpenGLWindow/OpenGLInclude.h"
9
10 struct sth_stash;
11 #include "fontstash.h"
12 #include "Gwen/Texture.h"
13
14 #include "TwFonts.h"
15 static float extraSpacing = 0.; //6f;
16 #include <assert.h>
17 #include <math.h>
18
19 template <class T>
MyClamp(T & a,const T & lb,const T & ub)20 inline void MyClamp(T& a, const T& lb, const T& ub)
21 {
22 if (a < lb)
23 {
24 a = lb;
25 }
26 else if (ub < a)
27 {
28 a = ub;
29 }
30 }
31
BindFont(const CTexFont * _Font)32 static GLuint BindFont(const CTexFont* _Font)
33 {
34 GLuint TexID = 0;
35 glGenTextures(1, &TexID);
36 glBindTexture(GL_TEXTURE_2D, TexID);
37 glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE);
38 glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
39 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
40 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
41 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
42 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
43 glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, _Font->m_TexWidth, _Font->m_TexHeight, 0, GL_RED, GL_UNSIGNED_BYTE, _Font->m_TexBytes);
44 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
45 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
46 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
47 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
48 glBindTexture(GL_TEXTURE_2D, 0);
49
50 return TexID;
51 }
52
53 struct MyTextureLoader
54 {
~MyTextureLoaderMyTextureLoader55 virtual ~MyTextureLoader()
56 {
57 }
58 virtual void LoadTexture(Gwen::Texture* pTexture) = 0;
59 virtual void FreeTexture(Gwen::Texture* pTexture) = 0;
60 };
61
62 class GwenOpenGL3CoreRenderer : public Gwen::Renderer::Base
63 {
64 GLPrimitiveRenderer* m_primitiveRenderer;
65 float m_currentColor[4];
66 float m_yOffset;
67 sth_stash* m_font;
68 float m_screenWidth;
69 float m_screenHeight;
70 float m_fontScaling;
71 float m_retinaScale;
72 bool m_useTrueTypeFont;
73 const CTexFont* m_currentFont;
74
75 GLuint m_fontTextureId;
76 MyTextureLoader* m_textureLoader;
77
78 public:
79 GwenOpenGL3CoreRenderer(GLPrimitiveRenderer* primRender, sth_stash* font, float screenWidth, float screenHeight, float retinaScale, MyTextureLoader* loader = 0)
m_primitiveRenderer(primRender)80 : m_primitiveRenderer(primRender),
81 m_font(font),
82 m_screenWidth(screenWidth),
83 m_screenHeight(screenHeight),
84 m_retinaScale(retinaScale),
85 m_useTrueTypeFont(false),
86 m_textureLoader(loader)
87 {
88 ///only enable true type fonts on Macbook Retina, it looks gorgeous
89 if (retinaScale == 2.0f)
90 {
91 m_useTrueTypeFont = true;
92 }
93 m_currentColor[0] = 1;
94 m_currentColor[1] = 1;
95 m_currentColor[2] = 1;
96 m_currentColor[3] = 1;
97
98 m_fontScaling = 16.f * m_retinaScale;
99
100 TwGenerateDefaultFonts();
101
102 m_currentFont = g_DefaultNormalFont;
103 //m_currentFont = g_DefaultNormalFontAA;
104
105 //m_currentFont = g_DefaultLargeFont;
106 m_fontTextureId = BindFont(m_currentFont);
107 }
108
~GwenOpenGL3CoreRenderer()109 virtual ~GwenOpenGL3CoreRenderer()
110 {
111 TwDeleteDefaultFonts();
112 }
Resize(int width,int height)113 virtual void Resize(int width, int height)
114 {
115 m_screenWidth = width;
116 m_screenHeight = height;
117 }
118
Begin()119 virtual void Begin()
120 {
121 m_yOffset = 0;
122 glEnable(GL_BLEND);
123 assert(glGetError() == GL_NO_ERROR);
124
125 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
126
127 assert(glGetError() == GL_NO_ERROR);
128
129 assert(glGetError() == GL_NO_ERROR);
130
131 glDisable(GL_DEPTH_TEST);
132 assert(glGetError() == GL_NO_ERROR);
133 //glColor4ub(255,0,0,255);
134
135 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
136
137 // saveOpenGLState(width,height);//m_glutScreenWidth,m_glutScreenHeight);
138
139 assert(glGetError() == GL_NO_ERROR);
140
141 glDisable(GL_CULL_FACE);
142
143 glDisable(GL_DEPTH_TEST);
144 assert(glGetError() == GL_NO_ERROR);
145
146 glEnable(GL_BLEND);
147
148 assert(glGetError() == GL_NO_ERROR);
149 }
End()150 virtual void End()
151 {
152 glDisable(GL_BLEND);
153 }
154
StartClip()155 virtual void StartClip()
156 {
157 if (m_useTrueTypeFont)
158 sth_flush_draw(m_font);
159 Gwen::Rect rect = ClipRegion();
160
161 // OpenGL's coords are from the bottom left
162 // so we need to translate them here.
163 {
164 GLint view[4];
165 glGetIntegerv(GL_VIEWPORT, &view[0]);
166 rect.y = view[3] / m_retinaScale - (rect.y + rect.h);
167 }
168
169 glScissor(m_retinaScale * rect.x * Scale(), m_retinaScale * rect.y * Scale(), m_retinaScale * rect.w * Scale(), m_retinaScale * rect.h * Scale());
170 glEnable(GL_SCISSOR_TEST);
171 //glDisable( GL_SCISSOR_TEST );
172 };
173
EndClip()174 virtual void EndClip()
175 {
176 if (m_useTrueTypeFont)
177 sth_flush_draw(m_font);
178 glDisable(GL_SCISSOR_TEST);
179 };
180
SetDrawColor(Gwen::Color color)181 virtual void SetDrawColor(Gwen::Color color)
182 {
183 m_currentColor[0] = color.r / 256.f;
184 m_currentColor[1] = color.g / 256.f;
185 m_currentColor[2] = color.b / 256.f;
186 m_currentColor[3] = color.a / 256.f;
187 }
DrawFilledRect(Gwen::Rect rect)188 virtual void DrawFilledRect(Gwen::Rect rect)
189 {
190 // BT_PROFILE("GWEN_DrawFilledRect");
191 Translate(rect);
192
193 m_primitiveRenderer->drawRect(rect.x, rect.y + m_yOffset,
194 rect.x + rect.w, rect.y + rect.h + m_yOffset, m_currentColor);
195
196 // m_primitiveRenderer->drawTexturedRect2a(rect.x, rect.y+m_yOffset,
197 // rect.x+rect.w, rect.y+rect.h+m_yOffset, m_currentColor,0,0,1,1);
198 // m_yOffset+=rect.h+10;
199 }
200
RenderText(Gwen::Font * pFont,Gwen::Point rasterPos,const Gwen::UnicodeString & text)201 void RenderText(Gwen::Font* pFont, Gwen::Point rasterPos, const Gwen::UnicodeString& text)
202 {
203 // BT_PROFILE("GWEN_RenderText");
204
205 Gwen::String str = Gwen::Utility::UnicodeToString(text);
206 const char* unicodeText = (const char*)str.c_str();
207
208 Gwen::Rect r;
209 r.x = rasterPos.x;
210 r.y = rasterPos.y;
211 r.w = 0;
212 r.h = 0;
213
214 //
215 //printf("str = %s\n",unicodeText);
216 //int xpos=0;
217 //int ypos=0;
218 float dx;
219
220 int measureOnly = 0;
221
222 if (m_useTrueTypeFont)
223 {
224 float yoffset = 0.f;
225 if (m_retinaScale == 2.0f)
226 {
227 yoffset = -12;
228 }
229 Translate(r);
230 sth_draw_text(m_font,
231 1, m_fontScaling,
232 r.x, r.y + yoffset,
233 unicodeText, &dx, m_screenWidth, m_screenHeight, measureOnly, m_retinaScale);
234 }
235 else
236 {
237 //float width = 0.f;
238 int pos = 0;
239 //float color[]={0.2f,0.2,0.2f,1.f};
240
241 glBindTexture(GL_TEXTURE_2D, m_fontTextureId);
242 float width = r.x;
243
244 while (unicodeText[pos])
245 {
246 int c = unicodeText[pos];
247 r.h = m_currentFont->m_CharHeight;
248 r.w = m_currentFont->m_CharWidth[c] + extraSpacing;
249 Gwen::Rect rect = r;
250 Translate(rect);
251
252 m_primitiveRenderer->drawTexturedRect2(rect.x, rect.y + m_yOffset, rect.x + rect.w, rect.y + rect.h + m_yOffset, m_currentColor, m_currentFont->m_CharU0[c], m_currentFont->m_CharV0[c], m_currentFont->m_CharU1[c], m_currentFont->m_CharV1[c]);
253
254 width += r.w;
255 r.x = width;
256 pos++;
257 }
258 {
259 m_primitiveRenderer->drawTexturedRect3D2Text(false);
260 }
261 glBindTexture(GL_TEXTURE_2D, 0);
262 }
263 }
MeasureText(Gwen::Font * pFont,const Gwen::UnicodeString & text)264 Gwen::Point MeasureText(Gwen::Font* pFont, const Gwen::UnicodeString& text)
265 {
266 // BT_PROFILE("GWEN_MeasureText");
267 Gwen::String str = Gwen::Utility::UnicodeToString(text);
268 const char* unicodeText = (const char*)str.c_str();
269
270 // printf("str = %s\n",unicodeText);
271 int xpos = 0;
272 int ypos = 0;
273
274 int measureOnly = 1;
275 float dx = 0;
276 if (m_useTrueTypeFont)
277 {
278 sth_draw_text(m_font,
279 1, m_fontScaling,
280 xpos, ypos,
281 unicodeText, &dx, m_screenWidth, m_screenHeight, measureOnly);
282
283 Gwen::Point pt;
284
285 if (m_retinaScale == 2.0f)
286 {
287 pt.x = dx * Scale() / 2.f;
288 pt.y = m_fontScaling / 2 * Scale() + 1;
289 }
290 else
291 {
292 pt.x = dx * Scale();
293 pt.y = m_fontScaling * Scale() + 1;
294 }
295 return pt;
296 }
297 else
298 {
299 float width = 0.f;
300 int pos = 0;
301 while (unicodeText[pos])
302 {
303 width += m_currentFont->m_CharWidth[(int)unicodeText[pos]] + extraSpacing;
304 pos++;
305 }
306 Gwen::Point pt;
307 int fontHeight = m_currentFont->m_CharHeight;
308
309 pt.x = width * Scale();
310 pt.y = (fontHeight + 2) * Scale();
311
312 return pt;
313 }
314
315 return Gwen::Renderer::Base::MeasureText(pFont, text);
316 }
317
LoadTexture(Gwen::Texture * pTexture)318 virtual void LoadTexture(Gwen::Texture* pTexture)
319 {
320 if (m_textureLoader)
321 m_textureLoader->LoadTexture(pTexture);
322 }
FreeTexture(Gwen::Texture * pTexture)323 virtual void FreeTexture(Gwen::Texture* pTexture)
324 {
325 if (m_textureLoader)
326 m_textureLoader->FreeTexture(pTexture);
327 }
328
329 virtual void DrawTexturedRect(Gwen::Texture* pTexture, Gwen::Rect rect, float u1 = 0.0f, float v1 = 0.0f, float u2 = 1.0f, float v2 = 1.0f)
330 {
331 // BT_PROFILE("DrawTexturedRect");
332 Translate(rect);
333
334 //float eraseColor[4] = {0,0,0,0};
335 //m_primitiveRenderer->drawRect(rect.x, rect.y+m_yOffset, rect.x+rect.w, rect.y+rect.h+m_yOffset, eraseColor);
336
337 GLint texHandle = (GLint)pTexture->m_intData;
338 //if (!texHandle)
339 // return;
340
341 glActiveTexture(GL_TEXTURE0);
342 glBindTexture(GL_TEXTURE_2D, texHandle);
343 // glDisable(GL_DEPTH_TEST);
344
345 assert(glGetError() == GL_NO_ERROR);
346
347 /* bool useFiltering = true;
348 if (useFiltering)
349 {
350 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
351 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
352 } else
353 {
354 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
355 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
356 }
357 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
358 */
359
360 //glEnable(GL_TEXTURE_2D);
361
362 // glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE );
363 static float add = 0.0;
364 //add+=1./512.;//0.01;
365 float color[4] = {1, 1, 1, 1};
366
367 m_primitiveRenderer->drawTexturedRect(rect.x, rect.y + m_yOffset, rect.x + rect.w, rect.y + rect.h + m_yOffset, color, 0 + add, 0, 1 + add, 1, true);
368
369 assert(glGetError() == GL_NO_ERROR);
370 }
371 };
372 #endif //__GWEN_OPENGL3_CORE_RENDERER_H
373