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