ManaPlus
normalopenglgraphics.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2018 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #if defined(USE_OPENGL) && !defined(ANDROID) && !defined(__native_client__)
24 
26 
27 #ifdef OPENGLERRORS
28 #include "graphicsmanager.h"
29 #endif // OPENGLERRORS
30 
31 #ifdef DEBUG_OPENGL
32 #include "render/opengl/mgl.h"
33 #endif // DEBUG_OPENGL
34 
36 
37 #include "resources/imagerect.h"
39 
40 #include "resources/image/image.h"
41 
42 #include "utils/sdlcheckutils.h"
43 
44 #include "debug.h"
45 
46 #define vertFill2D(tVar, vVar, x1, y1, x2, y2, dstX, dstY, w, h) \
47  tVar[vp + 0] = x1; \
48  tVar[vp + 1] = y1; \
49  tVar[vp + 2] = x2; \
50  tVar[vp + 3] = y1; \
51  tVar[vp + 4] = x2; \
52  tVar[vp + 5] = y2; \
53  tVar[vp + 6] = x1; \
54  tVar[vp + 7] = y2; \
55  vVar[vp + 0] = dstX; \
56  vVar[vp + 1] = dstY; \
57  vVar[vp + 2] = dstX + w; \
58  vVar[vp + 3] = dstY; \
59  vVar[vp + 4] = dstX + w; \
60  vVar[vp + 5] = dstY + h; \
61  vVar[vp + 6] = dstX; \
62  vVar[vp + 7] = dstY + h;
63 
64 
65 #define vertFillNv(tVar, vVar, srcX, srcY, dstX, dstY, w, h) \
66  tVar[vp + 0] = srcX; \
67  tVar[vp + 1] = srcY; \
68  tVar[vp + 2] = srcX + w; \
69  tVar[vp + 3] = srcY; \
70  tVar[vp + 4] = srcX + w; \
71  tVar[vp + 5] = srcY + h; \
72  tVar[vp + 6] = srcX; \
73  tVar[vp + 7] = srcY + h; \
74  vVar[vp + 0] = dstX; \
75  vVar[vp + 1] = dstY; \
76  vVar[vp + 2] = dstX + w; \
77  vVar[vp + 3] = dstY; \
78  vVar[vp + 4] = dstX + w; \
79  vVar[vp + 5] = dstY + h; \
80  vVar[vp + 6] = dstX; \
81  vVar[vp + 7] = dstY + h;
82 
83 namespace
84 {
85  const void *vertPtr = nullptr;
86 } // namespace
87 
89 #ifdef DEBUG_DRAW_CALLS
90 unsigned int NormalOpenGLGraphics::mDrawCalls = 0;
91 unsigned int NormalOpenGLGraphics::mLastDrawCalls = 0;
92 #endif // DEBUG_DRAW_CALLS
93 #ifdef DEBUG_BIND_TEXTURE
94 unsigned int NormalOpenGLGraphics::mBinds = 0;
95 unsigned int NormalOpenGLGraphics::mLastBinds = 0;
96 #endif // DEBUG_BIND_TEXTURE
97 
99  mFloatTexArray(nullptr),
100  mIntTexArray(nullptr),
101  mIntVertArray(nullptr),
102  mFloatTexArrayCached(nullptr),
103  mIntTexArrayCached(nullptr),
104  mIntVertArrayCached(nullptr),
105  mAlphaCached(1.0F),
106  mVpCached(0),
107  mTexture(false),
108  mIsByteColor(false),
109  mByteColor(),
110  mImageCached(0),
111  mFloatColor(1.0F),
112  mMaxVertices(500),
113  mColorAlpha(false),
114 #ifdef DEBUG_BIND_TEXTURE
115  mOldTexture(),
116  mOldTextureId(0),
117 #endif // DEBUG_BIND_TEXTURE
118  mFbo()
119 {
121  mName = "normal OpenGL";
122 }
123 
125 {
127 }
128 
130 {
131  mMaxVertices = vertCount;
132  if (mMaxVertices < 500)
133  mMaxVertices = 500;
134  else if (mMaxVertices > 1024)
135  mMaxVertices = 1024;
136 
137  // need alocate small size, after if limit reached reallocate to double size
139  const size_t sz = mMaxVertices * 4 + 30;
140  if (mFloatTexArray == nullptr)
141  mFloatTexArray = new GLfloat[sz];
142  if (mIntTexArray == nullptr)
143  mIntTexArray = new GLint[sz];
144  if (mIntVertArray == nullptr)
145  mIntVertArray = new GLint[sz];
146  if (mFloatTexArrayCached == nullptr)
147  mFloatTexArrayCached = new GLfloat[sz];
148  if (mIntTexArrayCached == nullptr)
149  mIntTexArrayCached = new GLint[sz];
150  if (mIntVertArrayCached == nullptr)
151  mIntVertArrayCached = new GLint[sz];
152 }
153 
155 {
157 }
158 
160 {
161  delete [] mFloatTexArray;
162  mFloatTexArray = nullptr;
163  delete [] mIntTexArray;
164  mIntTexArray = nullptr;
165  delete [] mIntVertArray;
166  mIntVertArray = nullptr;
167  delete [] mFloatTexArrayCached;
168  mFloatTexArrayCached = nullptr;
169  delete [] mIntTexArrayCached;
170  mIntTexArrayCached = nullptr;
171  delete [] mIntVertArrayCached;
172  mIntVertArrayCached = nullptr;
173 }
174 
175 bool NormalOpenGLGraphics::setVideoMode(const int w, const int h,
176  const int scale,
177  const int bpp,
178  const bool fs,
179  const bool hwaccel,
180  const bool resize,
181  const bool noFrame,
182  const bool allowHighDPI) restrict2
183 {
184  setMainFlags(w, h,
185  scale,
186  bpp,
187  fs,
188  hwaccel,
189  resize,
190  noFrame,
191  allowHighDPI);
192 
193  return setOpenGLMode();
194 }
195 
196 static inline void bindPointerIntFloat(const GLint *restrict const vert,
197  const GLfloat *restrict const tex)
198  A_INLINE;
199 
200 static inline void bindPointerIntFloat(const GLint *restrict const vert,
201  const GLfloat *restrict const tex)
202 {
203  if (vertPtr != vert)
204  {
205  vertPtr = vert;
206  glVertexPointer(2, GL_INT, 0, vert);
207  glTexCoordPointer(2, GL_FLOAT, 0, tex);
208  }
209 }
210 
211 static inline void bindPointerInt(const GLint *restrict const vert,
212  const GLint *restrict const tex) A_INLINE;
213 
214 static inline void bindPointerInt(const GLint *restrict const vert,
215  const GLint *restrict const tex)
216 {
217  if (vertPtr != vert)
218  {
219  vertPtr = vert;
220  glVertexPointer(2, GL_INT, 0, vert);
221  glTexCoordPointer(2, GL_INT, 0, tex);
222  }
223 }
224 
225 static inline void drawQuad(const Image *restrict const image,
226  const int srcX, const int srcY,
227  const int dstX, const int dstY,
228  const int width, const int height)
229  A_NONNULL(1) A_INLINE;
230 
231 static inline void drawQuad(const Image *restrict const image,
232  const int srcX, const int srcY,
233  const int dstX, const int dstY,
234  const int width, const int height)
235 {
236  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
237  {
238  const float tw = static_cast<float>(image->mTexWidth);
239  const float th = static_cast<float>(image->mTexHeight);
240  // Find OpenGL normalized texture coordinates.
241  const float texX1 = static_cast<float>(srcX) / tw;
242  const float texY1 = static_cast<float>(srcY) / th;
243  const float texX2 = static_cast<float>(srcX + width) / tw;
244  const float texY2 = static_cast<float>(srcY + height) / th;
245 
246  GLfloat tex[] =
247  {
248  texX1, texY1,
249  texX2, texY1,
250  texX2, texY2,
251  texX1, texY2
252  };
253 
254  GLint vert[] =
255  {
256  dstX, dstY,
257  dstX + width, dstY,
258  dstX + width, dstY + height,
259  dstX, dstY + height
260  };
261 
262  bindPointerIntFloat(&vert[0], &tex[0]);
263 #ifdef DEBUG_DRAW_CALLS
264  NormalOpenGLGraphics::mDrawCalls ++;
265 #endif // DEBUG_DRAW_CALLS
266 
267  glDrawArrays(GL_QUADS, 0, 4);
268 #ifdef OPENGLERRORS
270 #endif // OPENGLERRORS
271  }
272  else
273  {
274  GLint tex[] =
275  {
276  srcX, srcY,
277  srcX + width, srcY,
278  srcX + width, srcY + height,
279  srcX, srcY + height
280  };
281  GLint vert[] =
282  {
283  dstX, dstY,
284  dstX + width, dstY,
285  dstX + width, dstY + height,
286  dstX, dstY + height
287  };
288 
289  bindPointerInt(&vert[0], &tex[0]);
290 #ifdef DEBUG_DRAW_CALLS
291  NormalOpenGLGraphics::mDrawCalls ++;
292 #endif // DEBUG_DRAW_CALLS
293 
294  glDrawArrays(GL_QUADS, 0, 4);
295 #ifdef OPENGLERRORS
297 #endif // OPENGLERRORS
298  }
299 }
300 
301 static inline void drawRescaledQuad(const Image *restrict const image,
302  const int srcX, const int srcY,
303  const int dstX, const int dstY,
304  const int width, const int height,
305  const int desiredWidth,
306  const int desiredHeight)
307  A_NONNULL(1) A_INLINE;
308 
309 static inline void drawRescaledQuad(const Image *restrict const image,
310  const int srcX, const int srcY,
311  const int dstX, const int dstY,
312  const int width, const int height,
313  const int desiredWidth,
314  const int desiredHeight)
315 {
316  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
317  {
318  const float tw = static_cast<float>(image->mTexWidth);
319  const float th = static_cast<float>(image->mTexHeight);
320  // Find OpenGL normalized texture coordinates.
321  const float texX1 = static_cast<float>(srcX) / tw;
322  const float texY1 = static_cast<float>(srcY) / th;
323  const float texX2 = static_cast<float>(srcX + width) / tw;
324  const float texY2 = static_cast<float>(srcY + height) / th;
325 
326  GLfloat tex[] =
327  {
328  texX1, texY1,
329  texX2, texY1,
330  texX2, texY2,
331  texX1, texY2
332  };
333 
334  GLint vert[] =
335  {
336  dstX, dstY,
337  dstX + desiredWidth, dstY,
338  dstX + desiredWidth, dstY + desiredHeight,
339  dstX, dstY + desiredHeight
340  };
341 
342  bindPointerIntFloat(&vert[0], &tex[0]);
343 #ifdef DEBUG_DRAW_CALLS
344  NormalOpenGLGraphics::mDrawCalls ++;
345 #endif // DEBUG_DRAW_CALLS
346 
347  glDrawArrays(GL_QUADS, 0, 4);
348 #ifdef OPENGLERRORS
350 #endif // OPENGLERRORS
351  }
352  else
353  {
354  GLint tex[] =
355  {
356  srcX, srcY,
357  srcX + width, srcY,
358  srcX + width, srcY + height,
359  srcX, srcY + height
360  };
361  GLint vert[] =
362  {
363  dstX, dstY,
364  dstX + desiredWidth, dstY,
365  dstX + desiredWidth, dstY + desiredHeight,
366  dstX, dstY + desiredHeight
367  };
368 
369  bindPointerInt(&vert[0], &tex[0]);
370 #ifdef DEBUG_DRAW_CALLS
371  NormalOpenGLGraphics::mDrawCalls ++;
372 #endif // DEBUG_DRAW_CALLS
373 
374  glDrawArrays(GL_QUADS, 0, 4);
375 #ifdef OPENGLERRORS
377 #endif // OPENGLERRORS
378  }
379 }
380 
382  int dstX, int dstY) restrict2
383 {
384  drawImageInline(image, dstX, dstY);
385 }
386 
388  int dstX, int dstY) restrict2
389 {
390  FUNC_BLOCK("Graphics::drawImage", 1)
391  if (image == nullptr)
392  return;
393 
394  setColorAlpha(image->mAlpha);
395 #ifdef DEBUG_BIND_TEXTURE
396  debugBindTexture(image);
397 #endif // DEBUG_BIND_TEXTURE
398 
401 
402  const SDL_Rect &imageRect = image->mBounds;
403  drawQuad(image, imageRect.x, imageRect.y,
404  dstX, dstY, imageRect.w, imageRect.h);
405 }
406 
408  int dstX, int dstY) restrict2
409 {
410  drawImageInline(image, dstX, dstY);
411 }
412 
414 {
415  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
416  {
417  GLfloat tex[] =
418  {
419  0.0F, 0.781250f,
420  0.0F, 0.781250f,
421  0.0F, 0.585938f,
422  0.0F, 0.585938f
423  };
424 
425  GLint vert[] =
426  {
427  0, 0,
428  800, 0,
429  800, 600,
430  0, 600
431  };
432 
433  bindPointerIntFloat(&vert[0], &tex[0]);
434 #ifdef DEBUG_DRAW_CALLS
435  NormalOpenGLGraphics::mDrawCalls ++;
436 #endif // DEBUG_DRAW_CALLS
437 
438  glDrawArrays(GL_QUADS, 0, 4);
439 #ifdef OPENGLERRORS
441 #endif // OPENGLERRORS
442  }
443  else
444  {
445  GLint tex[] =
446  {
447  0, 0,
448  800, 0,
449  800, 600,
450  0, 600
451  };
452 
453  GLint vert[] =
454  {
455  0, 0,
456  800, 0,
457  800, 600,
458  0, 600
459  };
460 
461  bindPointerInt(&vert[0], &tex[0]);
462 #ifdef DEBUG_DRAW_CALLS
463  NormalOpenGLGraphics::mDrawCalls ++;
464 #endif // DEBUG_DRAW_CALLS
465 
466  glDrawArrays(GL_QUADS, 0, 4);
467 #ifdef OPENGLERRORS
469 #endif // OPENGLERRORS
470  }
471 }
472 
474  int x, int y) restrict2
475 {
476  if (image == nullptr)
477  return;
478 
479  if (image->mGLImage != mImageCached)
480  {
481  completeCache();
482  mImageCached = image->mGLImage;
483  mAlphaCached = image->mAlpha;
484  }
485 
486  const SDL_Rect &imageRect = image->mBounds;
487  const int w = imageRect.w;
488  const int h = imageRect.h;
489 
490  if (w == 0 || h == 0)
491  return;
492 
493  const int srcX = imageRect.x;
494  const int srcY = imageRect.y;
495 
496  const float tw = static_cast<float>(image->mTexWidth);
497  const float th = static_cast<float>(image->mTexHeight);
498 
499  const unsigned int vLimit = mMaxVertices * 4;
500 
501  unsigned int vp = mVpCached;
502 
503  // Draw a set of textured rectangles
504  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
505  {
506  const float texX1 = static_cast<float>(srcX) / tw;
507  const float texY1 = static_cast<float>(srcY) / th;
508 
509  const float texX2 = static_cast<float>(srcX + w) / tw;
510  const float texY2 = static_cast<float>(srcY + h) / th;
511 
513  texX1, texY1, texX2, texY2,
514  x, y, w, h);
515 
516  vp += 8;
517  if (vp >= vLimit)
518  {
519  completeCache();
520  vp = 0;
521  }
522  else
523  {
524  mVpCached = vp;
525  }
526  }
527  else
528  {
530  srcX, srcY, x, y, w, h);
531 
532  vp += 8;
533  if (vp >= vLimit)
534  {
535  completeCache();
536  vp = 0;
537  }
538  else
539  {
540  mVpCached = vp;
541  }
542  }
543 }
544 
546  const int x,
547  const int y,
548  const int w,
549  const int h) restrict2
550 {
551  FUNC_BLOCK("Graphics::drawPatternCached", 1)
552  if (image == nullptr)
553  return;
554 
555  if (image->mGLImage != mImageCached)
556  {
557  completeCache();
558  mImageCached = image->mGLImage;
559  }
560 
561  const SDL_Rect &imageRect = image->mBounds;
562  const int srcX = imageRect.x;
563  const int srcY = imageRect.y;
564  const int iw = imageRect.w;
565  const int ih = imageRect.h;
566 
567  if (iw == 0 || ih == 0)
568  return;
569 
570  const float tw = static_cast<float>(image->mTexWidth);
571  const float th = static_cast<float>(image->mTexHeight);
572 
573  unsigned int vp = mVpCached;
574  const unsigned int vLimit = mMaxVertices * 4;
575  // Draw a set of textured rectangles
576  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
577  {
578  const float texX1 = static_cast<float>(srcX) / tw;
579  const float texY1 = static_cast<float>(srcY) / th;
580 
581  for (int py = 0; py < h; py += ih)
582  {
583  const int height = (py + ih >= h) ? h - py : ih;
584  const int dstY = y + py;
585  const float texY2 = static_cast<float>(srcY + height) / th;
586  for (int px = 0; px < w; px += iw)
587  {
588  const int width = (px + iw >= w) ? w - px : iw;
589  const int dstX = x + px;
590 
591  const float texX2 = static_cast<float>(srcX + width) / tw;
592 
594  texX1, texY1, texX2, texY2,
595  dstX, dstY, width, height);
596 
597  vp += 8;
598  if (vp >= vLimit)
599  {
600  completeCache();
601  vp = 0;
602  }
603  }
604  }
605  }
606  else
607  {
608  for (int py = 0; py < h; py += ih)
609  {
610  const int height = (py + ih >= h) ? h - py : ih;
611  const int dstY = y + py;
612  for (int px = 0; px < w; px += iw)
613  {
614  const int width = (px + iw >= w) ? w - px : iw;
615  const int dstX = x + px;
616 
618  srcX, srcY, dstX, dstY, width, height);
619 
620  vp += 8;
621  if (vp >= vLimit)
622  {
623  completeCache();
624  vp = 0;
625  }
626  }
627  }
628  }
629  mVpCached = vp;
630 }
631 
633 {
634  if (mImageCached == 0U)
635  return;
636 
638 #ifdef DEBUG_BIND_TEXTURE
639  debugBindTexture(image);
640 #endif // DEBUG_BIND_TEXTURE
641 
644 
645  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
647  else
649 
650  mImageCached = 0;
651  mVpCached = 0;
652 }
653 
655  int dstX, int dstY,
656  const int desiredWidth,
657  const int desiredHeight) restrict2
658 {
659  FUNC_BLOCK("Graphics::drawRescaledImage", 1)
660  if (image == nullptr)
661  return;
662 
663  const SDL_Rect &imageRect = image->mBounds;
664 
665  // Just draw the image normally when no resizing is necessary,
666  if (imageRect.w == desiredWidth && imageRect.h == desiredHeight)
667  {
668  drawImageInline(image, dstX, dstY);
669  return;
670  }
671 
672  setColorAlpha(image->mAlpha);
673 #ifdef DEBUG_BIND_TEXTURE
674  debugBindTexture(image);
675 #endif // DEBUG_BIND_TEXTURE
676 
679 
680  // Draw a textured quad.
681  drawRescaledQuad(image, imageRect.x, imageRect.y, dstX, dstY,
682  imageRect.w, imageRect.h, desiredWidth, desiredHeight);
683 }
684 
686  const int x, const int y,
687  const int w, const int h) restrict2
688 {
689  drawPatternInline(image, x, y, w, h);
690 }
691 
693  const int x,
694  const int y,
695  const int w,
696  const int h) restrict2
697 {
698  FUNC_BLOCK("Graphics::drawPattern", 1)
699  if (image == nullptr)
700  return;
701 
702  const SDL_Rect &imageRect = image->mBounds;
703  const int srcX = imageRect.x;
704  const int srcY = imageRect.y;
705  const int iw = imageRect.w;
706  const int ih = imageRect.h;
707 
708  if (iw == 0 || ih == 0)
709  return;
710 
711  const float tw = static_cast<float>(image->mTexWidth);
712  const float th = static_cast<float>(image->mTexHeight);
713 
714  setColorAlpha(image->mAlpha);
715 
716 #ifdef DEBUG_BIND_TEXTURE
717  debugBindTexture(image);
718 #endif // DEBUG_BIND_TEXTURE
719 
721 
723 
724  unsigned int vp = 0;
725  const unsigned int vLimit = mMaxVertices * 4;
726  // Draw a set of textured rectangles
727  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
728  {
729  const float texX1 = static_cast<float>(srcX) / tw;
730  const float texY1 = static_cast<float>(srcY) / th;
731 
732  for (int py = 0; py < h; py += ih)
733  {
734  const int height = (py + ih >= h) ? h - py : ih;
735  const int dstY = y + py;
736  const float texY2 = static_cast<float>(srcY + height) / th;
737  for (int px = 0; px < w; px += iw)
738  {
739  const int width = (px + iw >= w) ? w - px : iw;
740  const int dstX = x + px;
741  const float texX2 = static_cast<float>(srcX + width) / tw;
742 
744  texX1, texY1, texX2, texY2,
745  dstX, dstY, width, height);
746 
747  vp += 8;
748  if (vp >= vLimit)
749  {
750  drawQuadArrayfi(vp);
751  vp = 0;
752  }
753  }
754  }
755  if (vp > 0)
756  drawQuadArrayfi(vp);
757  }
758  else
759  {
760  for (int py = 0; py < h; py += ih)
761  {
762  const int height = (py + ih >= h) ? h - py : ih;
763  const int dstY = y + py;
764  for (int px = 0; px < w; px += iw)
765  {
766  const int width = (px + iw >= w) ? w - px : iw;
767  const int dstX = x + px;
768 
770  srcX, srcY, dstX, dstY, width, height);
771 
772  vp += 8;
773  if (vp >= vLimit)
774  {
775  drawQuadArrayii(vp);
776  vp = 0;
777  }
778  }
779  }
780  if (vp > 0)
781  drawQuadArrayii(vp);
782  }
783 }
784 
786  restrict const image,
787  const int x, const int y,
788  const int w, const int h,
789  const int scaledWidth,
790  const int scaledHeight)
791  restrict2
792 {
793  if (image == nullptr)
794  return;
795 
796  if (scaledWidth == 0 || scaledHeight == 0)
797  return;
798 
799  const SDL_Rect &imageRect = image->mBounds;
800  const int iw = imageRect.w;
801  const int ih = imageRect.h;
802  if (iw == 0 || ih == 0)
803  return;
804 
805  const int srcX = imageRect.x;
806  const int srcY = imageRect.y;
807 
808  setColorAlpha(image->mAlpha);
809 
810 #ifdef DEBUG_BIND_TEXTURE
811  debugBindTexture(image);
812 #endif // DEBUG_BIND_TEXTURE
813 
815 
817 
818  unsigned int vp = 0;
819  const unsigned int vLimit = mMaxVertices * 4;
820 
821  // Draw a set of textured rectangles
822  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
823  {
824  const float tw = static_cast<float>(image->mTexWidth);
825  const float th = static_cast<float>(image->mTexHeight);
826 
827  const float texX1 = static_cast<float>(srcX) / tw;
828  const float texY1 = static_cast<float>(srcY) / th;
829 
830  const float tFractionW = iw / tw;
831  const float tFractionH = ih / th;
832 
833  for (int py = 0; py < h; py += scaledHeight)
834  {
835  const int height = (py + scaledHeight >= h)
836  ? h - py : scaledHeight;
837  const int dstY = y + py;
838  const float visibleFractionH = static_cast<float>(height)
839  / scaledHeight;
840  const float texY2 = texY1 + tFractionH * visibleFractionH;
841  for (int px = 0; px < w; px += scaledWidth)
842  {
843  const int width = (px + scaledWidth >= w)
844  ? w - px : scaledWidth;
845  const int dstX = x + px;
846  const float visibleFractionW = static_cast<float>(width)
847  / scaledWidth;
848  const float texX2 = texX1 + tFractionW * visibleFractionW;
849 
851  texX1, texY1, texX2, texY2,
852  dstX, dstY, width, height);
853 
854  vp += 8;
855  if (vp >= vLimit)
856  {
857  drawQuadArrayfi(vp);
858  vp = 0;
859  }
860  }
861  }
862  if (vp > 0)
863  drawQuadArrayfi(vp);
864  }
865  else
866  {
867  const float scaleFactorW = static_cast<float>(scaledWidth) / iw;
868  const float scaleFactorH = static_cast<float>(scaledHeight) / ih;
869 
870  for (int py = 0; py < h; py += scaledHeight)
871  {
872  const int height = (py + scaledHeight >= h)
873  ? h - py : scaledHeight;
874  const int dstY = y + py;
875  const int scaledY = srcY + height / scaleFactorH;
876  for (int px = 0; px < w; px += scaledWidth)
877  {
878  const int width = (px + scaledWidth >= w)
879  ? w - px : scaledWidth;
880  const int dstX = x + px;
881  const int scaledX = srcX + width / scaleFactorW;
882 
883  mIntTexArray[vp + 0] = srcX;
884  mIntTexArray[vp + 1] = srcY;
885 
886  mIntTexArray[vp + 2] = scaledX;
887  mIntTexArray[vp + 3] = srcY;
888 
889  mIntTexArray[vp + 4] = scaledX;
890  mIntTexArray[vp + 5] = scaledY;
891 
892  mIntTexArray[vp + 6] = srcX;
893  mIntTexArray[vp + 7] = scaledY;
894 
895  mIntVertArray[vp + 0] = dstX;
896  mIntVertArray[vp + 1] = dstY;
897 
898  mIntVertArray[vp + 2] = dstX + width;
899  mIntVertArray[vp + 3] = dstY;
900 
901  mIntVertArray[vp + 4] = dstX + width;
902  mIntVertArray[vp + 5] = dstY + height;
903 
904  mIntVertArray[vp + 6] = dstX;
905  mIntVertArray[vp + 7] = dstY + height;
906 
907  vp += 8;
908  if (vp >= vLimit)
909  {
910  drawQuadArrayii(vp);
911  vp = 0;
912  }
913  }
914  }
915  if (vp > 0)
916  drawQuadArrayii(vp);
917  }
918 }
919 
922  &restrict ogl) restrict2
923 {
924  const STD_VECTOR<GLint*> &intVertPool = ogl.mIntVertPool;
925  STD_VECTOR<GLint*>::const_iterator iv;
926  const STD_VECTOR<GLint*>::const_iterator iv_end = intVertPool.end();
927  const STD_VECTOR<int> &vp = ogl.mVp;
928  STD_VECTOR<int>::const_iterator ivp;
929  const STD_VECTOR<int>::const_iterator ivp_end = vp.end();
930 
931  // Draw a set of textured rectangles
932  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
933  {
934  const STD_VECTOR<GLfloat*> &floatTexPool = ogl.mFloatTexPool;
935  STD_VECTOR<GLfloat*>::const_iterator ft;
936  const STD_VECTOR<GLfloat*>::const_iterator
937  ft_end = floatTexPool.end();
938 
939  for (iv = intVertPool.begin(), ft = floatTexPool.begin(),
940  ivp = vp.begin();
941  iv != iv_end && ft != ft_end && ivp != ivp_end;
942  ++ iv, ++ ft, ++ ivp)
943  {
944  drawQuadArrayfi(*iv, *ft, *ivp);
945  }
946  }
947  else
948  {
949  const STD_VECTOR<GLint*> &intTexPool = ogl.mIntTexPool;
950  STD_VECTOR<GLint*>::const_iterator it;
951  const STD_VECTOR<GLint*>::const_iterator it_end = intTexPool.end();
952 
953  for (iv = intVertPool.begin(), it = intTexPool.begin(),
954  ivp = vp.begin();
955  iv != iv_end && it != it_end && ivp != ivp_end;
956  ++ iv, ++ it, ++ ivp)
957  {
958  drawQuadArrayii(*iv, *it, *ivp);
959  }
960  }
961 }
962 
964  const Image *restrict const image,
965  const int x,
966  const int y,
967  const int w,
968  const int h) const restrict2
969 {
970  calcPatternInline(vert, image, x, y, w, h);
971 }
972 
974  restrict const vert,
975  const Image *restrict const image,
976  const int x,
977  const int y,
978  const int w,
979  const int h) const restrict2
980 {
981  if (image == nullptr || vert == nullptr)
982  return;
983 
984  const SDL_Rect &imageRect = image->mBounds;
985  const int iw = imageRect.w;
986  const int ih = imageRect.h;
987 
988  if (iw == 0 || ih == 0)
989  return;
990 
991  const int srcX = imageRect.x;
992  const int srcY = imageRect.y;
993  const float tw = static_cast<float>(image->mTexWidth);
994  const float th = static_cast<float>(image->mTexHeight);
995 
996  const unsigned int vLimit = mMaxVertices * 4;
997 
998  OpenGLGraphicsVertexes &ogl = vert->ogl;
999  unsigned int vp = ogl.continueVp();
1000 
1001  // Draw a set of textured rectangles
1002  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
1003  {
1004  const float texX1 = static_cast<float>(srcX) / tw;
1005  const float texY1 = static_cast<float>(srcY) / th;
1006 
1007  GLfloat *floatTexArray = ogl.continueFloatTexArray();
1008  GLint *intVertArray = ogl.continueIntVertArray();
1009 
1010  for (int py = 0; py < h; py += ih)
1011  {
1012  const int height = (py + ih >= h) ? h - py : ih;
1013  const int dstY = y + py;
1014  const float texY2 = static_cast<float>(srcY + height) / th;
1015  for (int px = 0; px < w; px += iw)
1016  {
1017  const int width = (px + iw >= w) ? w - px : iw;
1018  const int dstX = x + px;
1019  const float texX2 = static_cast<float>(srcX + width) / tw;
1020 
1021  vertFill2D(floatTexArray, intVertArray,
1022  texX1, texY1, texX2, texY2,
1023  dstX, dstY, width, height);
1024 
1025  vp += 8;
1026  if (vp >= vLimit)
1027  {
1028  floatTexArray = ogl.switchFloatTexArray();
1029  intVertArray = ogl.switchIntVertArray();
1030  ogl.switchVp(vp);
1031  vp = 0;
1032  }
1033  }
1034  }
1035  }
1036  else
1037  {
1038  GLint *intTexArray = ogl.continueIntTexArray();
1039  GLint *intVertArray = ogl.continueIntVertArray();
1040 
1041  for (int py = 0; py < h; py += ih)
1042  {
1043  const int height = (py + ih >= h) ? h - py : ih;
1044  const int dstY = y + py;
1045  for (int px = 0; px < w; px += iw)
1046  {
1047  const int width = (px + iw >= w) ? w - px : iw;
1048  const int dstX = x + px;
1049 
1050  vertFillNv(intTexArray, intVertArray,
1051  srcX, srcY, dstX, dstY, width, height);
1052 
1053  vp += 8;
1054  if (vp >= vLimit)
1055  {
1056  intTexArray = ogl.switchIntTexArray();
1057  intVertArray = ogl.switchIntVertArray();
1058  ogl.switchVp(vp);
1059  vp = 0;
1060  }
1061  }
1062  }
1063  }
1064  ogl.switchVp(vp);
1065 }
1066 
1068  restrict const vertCol,
1069  const Image *
1070  restrict const image,
1071  int x, int y) restrict2
1072 {
1073  if (vertCol == nullptr || image == nullptr)
1074  return;
1075  if (vertCol->currentGLImage != image->mGLImage)
1076  {
1077  ImageVertexes *const vert = new ImageVertexes;
1078  vertCol->currentGLImage = image->mGLImage;
1079  vertCol->currentVert = vert;
1080  vert->image = image;
1081  vertCol->draws.push_back(vert);
1082  calcTileVertexesInline(vert, image, x, y);
1083  }
1084  else
1085  {
1086  calcTileVertexesInline(vertCol->currentVert, image, x, y);
1087  }
1088 }
1089 
1091  *restrict const vertCol)
1092  restrict2
1093 {
1094  const ImageVertexesVector &draws = vertCol->draws;
1095  const ImageCollectionCIter it_end = draws.end();
1096  for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
1097  {
1098  const ImageVertexes *const vert = *it;
1099  const Image *const image = vert->image;
1100 
1101  setColorAlpha(image->mAlpha);
1102 #ifdef DEBUG_BIND_TEXTURE
1103  debugBindTexture(image);
1104 #endif // DEBUG_BIND_TEXTURE
1105 
1108  drawVertexes(vert->ogl);
1109  }
1110 }
1111 
1113  const Image *restrict const image,
1114  const int x,
1115  const int y,
1116  const int w,
1117  const int h) const restrict2
1118 {
1119  if (vertCol == nullptr || image == nullptr)
1120  return;
1121  ImageVertexes *vert = nullptr;
1122  if (vertCol->currentGLImage != image->mGLImage)
1123  {
1124  vert = new ImageVertexes;
1125  vertCol->currentGLImage = image->mGLImage;
1126  vertCol->currentVert = vert;
1127  vert->image = image;
1128  vertCol->draws.push_back(vert);
1129  }
1130  else
1131  {
1132  vert = vertCol->currentVert;
1133  }
1134 
1135  calcPatternInline(vert, image, x, y, w, h);
1136 }
1137 
1139  const Image *restrict const image,
1140  int dstX, int dstY) const restrict2
1141 {
1142  calcTileVertexesInline(vert, image, dstX, dstY);
1143 }
1144 
1146  restrict const vert,
1147  const Image *
1148  restrict const image,
1149  int dstX,
1150  int dstY) const restrict2
1151 {
1152  const SDL_Rect &imageRect = image->mBounds;
1153  const int w = imageRect.w;
1154  const int h = imageRect.h;
1155 
1156  if (w == 0 || h == 0)
1157  return;
1158 
1159  const int srcX = imageRect.x;
1160  const int srcY = imageRect.y;
1161 
1162  const float tw = static_cast<float>(image->mTexWidth);
1163  const float th = static_cast<float>(image->mTexHeight);
1164 
1165  const unsigned int vLimit = mMaxVertices * 4;
1166 
1167  OpenGLGraphicsVertexes &ogl = vert->ogl;
1168 
1169 // STD_VECTOR<int> *vps = ogl.getVp();
1170  unsigned int vp = ogl.continueVp();
1171 
1172  // Draw a set of textured rectangles
1173  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
1174  {
1175  const float texX1 = static_cast<float>(srcX) / tw;
1176  const float texY1 = static_cast<float>(srcY) / th;
1177 
1178  const float texX2 = static_cast<float>(srcX + w) / tw;
1179  const float texY2 = static_cast<float>(srcY + h) / th;
1180 
1181  GLfloat *const floatTexArray = ogl.continueFloatTexArray();
1182  GLint *const intVertArray = ogl.continueIntVertArray();
1183 
1184  vertFill2D(floatTexArray, intVertArray,
1185  texX1, texY1, texX2, texY2,
1186  dstX, dstY, w, h);
1187 
1188  vp += 8;
1189  if (vp >= vLimit)
1190  {
1191  ogl.switchFloatTexArray();
1192  ogl.switchIntVertArray();
1193  ogl.switchVp(vp);
1194  vp = 0;
1195  }
1196  }
1197  else
1198  {
1199  GLint *const intTexArray = ogl.continueIntTexArray();
1200  GLint *const intVertArray = ogl.continueIntVertArray();
1201 
1202  vertFillNv(intTexArray, intVertArray,
1203  srcX, srcY, dstX, dstY, w, h);
1204 
1205  vp += 8;
1206  if (vp >= vLimit)
1207  {
1208  ogl.switchIntTexArray();
1209  ogl.switchIntVertArray();
1210  ogl.switchVp(vp);
1211  vp = 0;
1212  }
1213  }
1214  ogl.switchVp(vp);
1215 }
1216 
1218  restrict const vert) restrict2
1219 {
1220  if (vert == nullptr)
1221  return;
1222  const Image *const image = vert->image;
1223 
1224  setColorAlpha(image->mAlpha);
1225 #ifdef DEBUG_BIND_TEXTURE
1226  debugBindTexture(image);
1227 #endif // DEBUG_BIND_TEXTURE
1228 
1231  drawVertexes(vert->ogl);
1232 }
1233 
1235  const int x, const int y,
1236  const int w, const int h,
1237  const ImageRect &restrict imgRect)
1238  restrict2
1239 {
1240  ImageVertexes *vert = nullptr;
1241  Image *const image = imgRect.grid[4];
1242  if (image == nullptr)
1243  return;
1244  if (vertCol->currentGLImage != image->mGLImage)
1245  {
1246  vert = new ImageVertexes;
1247  vertCol->currentGLImage = image->mGLImage;
1248  vertCol->currentVert = vert;
1249  vert->image = image;
1250  vertCol->draws.push_back(vert);
1251  }
1252  else
1253  {
1254  vert = vertCol->currentVert;
1255  }
1256  calcImageRect(vert, x, y, w, h, imgRect);
1257 }
1258 
1260 {
1261  BLOCK_START("Graphics::updateScreen")
1262 // glFlush();
1263 // glFinish();
1264 #ifdef DEBUG_DRAW_CALLS
1265  mLastDrawCalls = mDrawCalls;
1266  mDrawCalls = 0;
1267 #endif // DEBUG_DRAW_CALLS
1268 #ifdef DEBUG_BIND_TEXTURE
1269  mLastBinds = mBinds;
1270  mBinds = 0;
1271 #endif // DEBUG_BIND_TEXTURE
1272 #ifdef USE_SDL2
1273  SDL_GL_SwapWindow(mWindow);
1274 #else // USE_SDL2
1275  SDL_GL_SwapBuffers();
1276 #endif // USE_SDL2
1277 #ifdef DEBUG_OPENGL
1278  if (isGLNotNull(mglFrameTerminator))
1279  mglFrameTerminator();
1280 #endif // DEBUG_OPENGL
1281 
1282 // may be need clear?
1283 // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1284  BLOCK_END("Graphics::updateScreen")
1285 }
1286 
1288 {
1289  glMatrixMode(GL_TEXTURE);
1290  glLoadIdentity();
1291 
1292  glMatrixMode(GL_PROJECTION);
1293  glLoadIdentity();
1294 
1295  const int w = mRect.w;
1296  const int h = mRect.h;
1297 
1298 #ifdef ANDROID
1299  glOrthof(0.0, static_cast<float>(w),
1300  static_cast<float>(h),
1301  0.0, -1.0, 1.0);
1302 #else // ANDROID
1303 
1304  glOrtho(0.0, static_cast<double>(w),
1305  static_cast<double>(h),
1306  0.0, -1.0, 1.0);
1307 #endif // ANDROID
1308 
1309  glMatrixMode(GL_MODELVIEW);
1310  glLoadIdentity();
1311 
1312  setOpenGLFlags();
1313  glDisable(GL_LIGHTING);
1314  glDisable(GL_FOG);
1315  glDisable(GL_COLOR_MATERIAL);
1316 
1317  glEnableClientState(GL_VERTEX_ARRAY);
1318  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1319 
1320  glShadeModel(GL_FLAT);
1321  glDepthMask(GL_FALSE);
1322 
1323  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1324 #ifndef ANDROID
1325  glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
1326  glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
1327  glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
1328  glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
1329 #endif // ANDROID
1330 
1331  pushClipArea(Rect(0, 0, w, h));
1332 }
1333 
1335 {
1336  popClipArea();
1337 }
1338 
1340 {
1341  int transX = 0;
1342  int transY = 0;
1343 
1344  if (!mClipStack.empty())
1345  {
1346  const ClipRect &clipArea = mClipStack.top();
1347  transX = -clipArea.xOffset;
1348  transY = -clipArea.yOffset;
1349  }
1350 
1351  Graphics::pushClipArea(area);
1352 
1353  const ClipRect &clipArea = mClipStack.top();
1354  transX += clipArea.xOffset;
1355  transY += clipArea.yOffset;
1356 
1357  if (transX != 0 || transY != 0)
1358  {
1359  glTranslatef(static_cast<GLfloat>(transX),
1360  static_cast<GLfloat>(transY), 0);
1361  }
1362  glScissor(clipArea.x * mScale,
1363  (mRect.h - clipArea.y - clipArea.height) * mScale,
1364  clipArea.width * mScale,
1365  clipArea.height * mScale);
1366 }
1367 
1369 {
1370  if (mClipStack.empty())
1371  return;
1372 
1373  const ClipRect &clipArea1 = mClipStack.top();
1374  int transX = -clipArea1.xOffset;
1375  int transY = -clipArea1.yOffset;
1376 
1378 
1379  if (mClipStack.empty())
1380  return;
1381 
1382  const ClipRect &clipArea = mClipStack.top();
1383  transX += clipArea.xOffset;
1384  transY += clipArea.yOffset;
1385  if (transX != 0 || transY != 0)
1386  {
1387  glTranslatef(static_cast<GLfloat>(transX),
1388  static_cast<GLfloat>(transY), 0);
1389  }
1390  glScissor(clipArea.x * mScale,
1391  (mRect.h - clipArea.y - clipArea.height) * mScale,
1392  clipArea.width * mScale,
1393  clipArea.height * mScale);
1394 }
1395 
1397 {
1399  restoreColor();
1400 
1401 #ifdef ANDROID
1402  // TODO need fix
1403 #else // ANDROID
1404 
1405  glBegin(GL_POINTS);
1406  glVertex2i(x, y);
1407  glEnd();
1408 #endif // ANDROID
1409 }
1410 
1412  int x2, int y2) restrict2
1413 {
1415  restoreColor();
1416 
1417  mFloatTexArray[0] = static_cast<float>(x1) + 0.5F;
1418  mFloatTexArray[1] = static_cast<float>(y1) + 0.5F;
1419  mFloatTexArray[2] = static_cast<float>(x2) + 0.5F;
1420  mFloatTexArray[3] = static_cast<float>(y2) + 0.5F;
1421 
1422  drawLineArrayf(4);
1423 }
1424 
1426 {
1427  drawRectangle(rect, false);
1428 }
1429 
1431 {
1432  drawRectangle(rect, true);
1433 }
1434 
1436 {
1437  if (!mTexture)
1438  {
1440  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1441  mTexture = true;
1442  }
1443 
1444  if (!mAlpha)
1445  {
1446  glEnable(GL_BLEND);
1447  mAlpha = true;
1448  }
1449 }
1450 
1452 {
1453  mTextureBinded = 0;
1454  if (mAlpha && !mColorAlpha)
1455  {
1456  glDisable(GL_BLEND);
1457  mAlpha = false;
1458  }
1459  else if (!mAlpha && mColorAlpha)
1460  {
1461  glEnable(GL_BLEND);
1462  mAlpha = true;
1463  }
1464 
1465  if (mTexture)
1466  {
1468  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1469  mTexture = false;
1470  }
1471 }
1472 
1474  const bool filled) restrict2
1475 {
1476  BLOCK_START("Graphics::drawRectangle")
1477  const float offset = filled ? 0 : 0.5F;
1478  const float x = static_cast<float>(rect.x);
1479  const float y = static_cast<float>(rect.y);
1480  const float width = static_cast<float>(rect.width);
1481  const float height = static_cast<float>(rect.height);
1482 
1484  restoreColor();
1485 
1486  GLfloat vert[] =
1487  {
1488  x + offset, y + offset,
1489  x + width - offset, y + offset,
1490  x + width - offset, y + height - offset,
1491  x + offset, y + height - offset
1492  };
1493 
1494  glVertexPointer(2, GL_FLOAT, 0, &vert);
1495  vertPtr = nullptr;
1496 #ifdef DEBUG_DRAW_CALLS
1497  mDrawCalls ++;
1498 #endif // DEBUG_DRAW_CALLS
1499 
1500  glDrawArrays(filled ? GL_QUADS : GL_LINE_LOOP, 0, 4);
1501 #ifdef OPENGLERRORS
1503 #endif // OPENGLERRORS
1504  BLOCK_END("Graphics::drawRectangle")
1505 }
1506 
1507 void NormalOpenGLGraphics::drawNet(const int x1, const int y1,
1508  const int x2, const int y2,
1509  const int width, const int height) restrict2
1510 {
1511  unsigned int vp = 0;
1512  const unsigned int vLimit = mMaxVertices * 4;
1513 
1515  restoreColor();
1516 
1517  const float xf1 = static_cast<float>(x1);
1518  const float xf2 = static_cast<float>(x2);
1519  const float yf1 = static_cast<float>(y1);
1520  const float yf2 = static_cast<float>(y2);
1521 
1522  for (int y = y1; y < y2; y += height)
1523  {
1524  mFloatTexArray[vp + 0] = xf1;
1525  mFloatTexArray[vp + 1] = static_cast<float>(y);
1526 
1527  mFloatTexArray[vp + 2] = xf2;
1528  mFloatTexArray[vp + 3] = static_cast<float>(y);
1529 
1530  vp += 4;
1531  if (vp >= vLimit)
1532  {
1533  drawLineArrayf(vp);
1534  vp = 0;
1535  }
1536  }
1537 
1538  for (int x = x1; x < x2; x += width)
1539  {
1540  mFloatTexArray[vp + 0] = static_cast<float>(x);
1541  mFloatTexArray[vp + 1] = yf1;
1542 
1543  mFloatTexArray[vp + 2] = static_cast<float>(x);
1544  mFloatTexArray[vp + 3] = yf2;
1545 
1546  vp += 4;
1547  if (vp >= vLimit)
1548  {
1549  drawLineArrayf(vp);
1550  vp = 0;
1551  }
1552  }
1553 
1554  if (vp > 0)
1555  drawLineArrayf(vp);
1556 }
1557 
1558 void NormalOpenGLGraphics::bindTexture(const GLenum target,
1559  const GLuint texture)
1560 {
1561  if (mTextureBinded != texture)
1562  {
1563  mTextureBinded = texture;
1564  glBindTexture(target, texture);
1565 #ifdef DEBUG_BIND_TEXTURE
1566  mBinds ++;
1567 #endif // DEBUG_BIND_TEXTURE
1568  }
1569 }
1570 
1572 {
1574 #ifdef DEBUG_DRAW_CALLS
1575  mDrawCalls ++;
1576 #endif // DEBUG_DRAW_CALLS
1577 
1578  glDrawArrays(GL_QUADS, 0, size / 2);
1579 #ifdef OPENGLERRORS
1581 #endif // OPENGLERRORS
1582 }
1583 
1585  restrict2
1586 {
1588 #ifdef DEBUG_DRAW_CALLS
1589  mDrawCalls ++;
1590 #endif // DEBUG_DRAW_CALLS
1591 
1592  glDrawArrays(GL_QUADS, 0, size / 2);
1593 #ifdef OPENGLERRORS
1595 #endif // OPENGLERRORS
1596 }
1597 
1598 inline void NormalOpenGLGraphics::drawQuadArrayfi(const GLint *restrict const
1599  intVertArray,
1600  const GLfloat *restrict const
1601  floatTexArray,
1602  const int size) restrict2
1603 {
1604  vertPtr = intVertArray;
1605  glVertexPointer(2, GL_INT, 0, intVertArray);
1606  glTexCoordPointer(2, GL_FLOAT, 0, floatTexArray);
1607 #ifdef DEBUG_DRAW_CALLS
1608  mDrawCalls ++;
1609 #endif // DEBUG_DRAW_CALLS
1610 
1611  glDrawArrays(GL_QUADS, 0, size / 2);
1612 #ifdef OPENGLERRORS
1614 #endif // OPENGLERRORS
1615 }
1616 
1618 {
1620 #ifdef DEBUG_DRAW_CALLS
1621  mDrawCalls ++;
1622 #endif // DEBUG_DRAW_CALLS
1623 
1624  glDrawArrays(GL_QUADS, 0, size / 2);
1625 #ifdef OPENGLERRORS
1627 #endif // OPENGLERRORS
1628 }
1629 
1631  restrict2
1632 {
1634 #ifdef DEBUG_DRAW_CALLS
1635  mDrawCalls ++;
1636 #endif // DEBUG_DRAW_CALLS
1637 
1638  glDrawArrays(GL_QUADS, 0, size / 2);
1639 #ifdef OPENGLERRORS
1641 #endif // OPENGLERRORS
1642 }
1643 
1644 inline void NormalOpenGLGraphics::drawQuadArrayii(const GLint *restrict const
1645  intVertArray,
1646  const GLint *restrict const
1647  intTexArray,
1648  const int size) restrict2
1649 {
1650  vertPtr = intVertArray;
1651  glVertexPointer(2, GL_INT, 0, intVertArray);
1652  glTexCoordPointer(2, GL_INT, 0, intTexArray);
1653 #ifdef DEBUG_DRAW_CALLS
1654  mDrawCalls ++;
1655 #endif // DEBUG_DRAW_CALLS
1656 
1657  glDrawArrays(GL_QUADS, 0, size / 2);
1658 #ifdef OPENGLERRORS
1660 #endif // OPENGLERRORS
1661 }
1662 
1664 {
1665  glVertexPointer(2, GL_INT, 0, mIntVertArray);
1666  vertPtr = nullptr;
1667 #ifdef DEBUG_DRAW_CALLS
1668  mDrawCalls ++;
1669 #endif // DEBUG_DRAW_CALLS
1670 
1671  glDrawArrays(GL_LINES, 0, size / 2);
1672 #ifdef OPENGLERRORS
1674 #endif // OPENGLERRORS
1675 }
1676 
1678 {
1679  glVertexPointer(2, GL_FLOAT, 0, mFloatTexArray);
1680  vertPtr = nullptr;
1681 #ifdef DEBUG_DRAW_CALLS
1682  mDrawCalls ++;
1683 #endif // DEBUG_DRAW_CALLS
1684 
1685  glDrawArrays(GL_LINES, 0, size / 2);
1686 #ifdef OPENGLERRORS
1688 #endif // OPENGLERRORS
1689 }
1690 
1692 {
1693  GLint test[1000];
1694  logger->log("\n\n");
1695  logger->log("start opengl dump");
1696  for (int f = 0; f < 65535; f ++)
1697  {
1698  test[0] = 0;
1699  test[1] = 0;
1700  test[2] = 0;
1701  test[3] = 0;
1702  glGetIntegerv(f, &test[0]);
1703  if (test[0] != 0 || test[1] != 0 || test[2] != 0 || test[3] != 0)
1704  {
1705  logger->log("\n%d = %d, %d, %d, %d", f,
1706  test[0], test[1], test[2], test[3]);
1707  }
1708  }
1709 }
1710 
1712 {
1713  if (!mIsByteColor && mFloatColor == alpha)
1714  return;
1715 
1716  glColor4f(1.0F, 1.0F, 1.0F, alpha);
1717  mIsByteColor = false;
1718  mFloatColor = alpha;
1719 }
1720 
1722 {
1723  if (mIsByteColor && mByteColor == mColor)
1724  return;
1725 
1726  glColor4ub(static_cast<GLubyte>(mColor.r),
1727  static_cast<GLubyte>(mColor.g),
1728  static_cast<GLubyte>(mColor.b),
1729  static_cast<GLubyte>(mColor.a));
1730  mIsByteColor = true;
1731  mByteColor = mColor;
1732 }
1733 
1734 void NormalOpenGLGraphics::drawImageRect(const int x, const int y,
1735  const int w, const int h,
1736  const ImageRect &restrict imgRect)
1737  restrict2
1738 {
1740 }
1741 
1743  const int x, const int y,
1744  const int w, const int h,
1745  const ImageRect &restrict imgRect)
1746  restrict2
1747 {
1749 }
1750 
1752 {
1753  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1754 }
1755 
1756 #ifdef DEBUG_BIND_TEXTURE
1757 void NormalOpenGLGraphics::debugBindTexture(const Image *restrict const image)
1758  restrict2
1759 {
1760  const std::string texture = image->mIdPath;
1761  if (mOldTexture != texture)
1762  {
1763  if ((!mOldTexture.empty() || !texture.empty())
1764  && mOldTextureId != image->mGLImage)
1765  {
1766  logger->log("bind: %s (%d) to %s (%d)", mOldTexture.c_str(),
1767  mOldTextureId, texture.c_str(), image->mGLImage);
1768  }
1769  mOldTextureId = image->mGLImage;
1770  mOldTexture = texture;
1771  }
1772 }
1773 #else // DEBUG_BIND_TEXTURE
1774 
1776  image A_UNUSED) restrict2
1777 {
1778 }
1779 #endif // DEBUG_BIND_TEXTURE
1780 
1781 #endif // defined(USE_OPENGL) && !defined(ANDROID) &&
1782  // !defined(__native_client__)
void drawPoint(int x, int y)
void calcTileVertexes(ImageVertexes *const vert, const Image *const image, int x, int y) const
void setMainFlags(const int w, const int h, const int scale, const int bpp, const bool fs, const bool hwaccel, const bool resize, const bool noFrame, const bool allowHighDPI)
Definition: graphics.cpp:181
#define vertFill2D(tVar, vVar, x1, y1, x2, y2, dstX, dstY, w, h)
int width
Definition: rect.h:218
std::string mName
Definition: graphics.h:548
void drawQuadArrayii(const int size) A_INLINE
void drawLine(int x1, int y1, int x2, int y2)
SDL_Surface * mWindow
Definition: graphics.h:522
RenderType mOpenGL
Definition: graphics.h:544
unsigned int a
Definition: color.h:250
#define isGLNotNull(func)
Definition: mglcheck.h:27
void drawRescaledPattern(const Image *const image, const int x, const int y, const int w, const int h, const int scaledWidth, const int scaledHeight)
void calcImageRect(ImageVertexes *const vert, int x, int y, int w, int h, const ImageRect &imgRect) A_INLINE
std::vector< ImageVertexes * > ImageVertexesVector
Definition: imagevertexes.h:55
#define vertFillNv(tVar, vVar, srcX, srcY, dstX, dstY, w, h)
unsigned int g
Definition: color.h:239
Definition: rect.h:72
void copyImage(const Image *const image, int dstX, int dstY)
void debugBindTexture(const Image *const image)
void drawQuadArrayiiCached(const int size) A_INLINE
void drawPatternInline(const Image *const image, const int x, const int y, const int w, const int h) A_INLINE
#define BLOCK_START(name)
Definition: perfomance.h:78
void drawQuadArrayfiCached(const int size) A_INLINE
const Image * image
Definition: imagevertexes.h:47
unsigned int vertexBufSize
#define BLOCK_END(name)
Definition: perfomance.h:79
void drawTileCollection(const ImageCollection *const vertCol)
int yOffset
Definition: cliprect.h:126
virtual void popClipArea()
Definition: graphics.cpp:738
void drawRescaledImage(const Image *const image, int dstX, int dstY, const int desiredWidth, const int desiredHeight)
void drawQuadArrayfi(const int size) A_INLINE
#define A_NONNULL(...)
Definition: localconsts.h:167
ImageVertexesVector::const_iterator ImageCollectionCIter
Definition: imagevertexes.h:57
static void bindTexture(const GLenum target, const GLuint texture)
static void drawRescaledQuad(const Image *const image, const int srcX, const int srcY, const int dstX, const int dstY, const int width, const int height, const int desiredWidth, const int desiredHeight) A_INLINE
void drawImageInline(const Image *const image, int dstX, int dstY) A_INLINE
void drawImage(const Image *const image, int dstX, int dstY)
Logger * logger
Definition: logger.cpp:88
Color mColor
Definition: graphics.h:552
int x
Definition: rect.h:208
bool setVideoMode(const int w, const int h, const int scalle, const int bpp, const bool fs, const bool hwaccel, const bool resize, const bool noFrame, const bool allowHighDPI)
unsigned int b
Definition: color.h:244
void drawLineArrayf(const int size) A_INLINE
static void drawQuad(const Image *const image, const int srcX, const int srcY, const int dstX, const int dstY, const int width, const int height) A_INLINE
void drawImageCached(const Image *const image, int x, int y)
int xOffset
Definition: cliprect.h:121
int y
Definition: rect.h:213
bool mAlpha
Definition: graphics.h:537
void fillRectangle(const Rect &rect)
#define nullptr
Definition: localconsts.h:44
float mAlpha
Definition: image.h:212
int height
Definition: rect.h:223
void drawNet(const int x1, const int y1, const int x2, const int y2, const int width, const int height)
#define FUNC_BLOCK(name, id)
Definition: perfomance.h:80
void calcTileVertexesInline(ImageVertexes *const vert, const Image *const image, int x, int y) const A_INLINE
SDL_Rect mRect
Definition: graphics.h:542
void setOpenGLFlags()
Definition: graphics.cpp:747
GLuint mGLImage
Definition: image.h:182
#define A_UNUSED
Definition: localconsts.h:159
static void logError()
void calcPatternInline(ImageVertexes *const vert, const Image *const image, const int x, const int y, const int w, const int h) const A_INLINE
int mScale
Definition: graphics.h:551
static void bindPointerInt(const GLint *const vert, const GLint *const tex) A_INLINE
void drawRectangle(const Rect &rect)
MStack< ClipRect > mClipStack
Definition: graphics.h:520
Definition: image.h:61
void drawLineArrayi(const int size) A_INLINE
virtual void pushClipArea(const Rect &area)
Definition: graphics.cpp:676
#define restrict
Definition: localconsts.h:164
T & top() const
Definition: mstack.h:72
void log(const char *const log_text,...)
Definition: logger.cpp:264
void drawPattern(const Image *const image, const int x, const int y, const int w, const int h)
OpenGLGraphicsVertexes ogl
Definition: imagevertexes.h:49
void calcWindow(ImageCollection *const vertCol, const int x, const int y, const int w, const int h, const ImageRect &imgRect)
bool empty() const
Definition: mstack.h:87
void calcPattern(ImageVertexes *const vert, const Image *const image, const int x, const int y, const int w, const int h) const
GraphicsManager graphicsManager
void drawPatternCached(const Image *const image, const int x, const int y, const int w, const int h)
#define restrict2
Definition: localconsts.h:165
void initArrays(const int vertCount)
bool setOpenGLMode()
Definition: graphics.cpp:282
void setColorAlpha(const float alpha) A_INLINE
void drawVertexes(const OpenGLGraphicsVertexes &ogl) A_INLINE
void drawTileVertexes(const ImageVertexes *const vert)
unsigned int r
Definition: color.h:234
static void bindPointerIntFloat(const GLint *const vert, const GLfloat *const tex) A_INLINE
void pushClipArea(const Rect &area)
void calcTileCollection(ImageCollection *const vertCol, const Image *const image, int x, int y)
void drawImageRect(int x, int y, int w, int h, const ImageRect &imgRect)