ManaPlus
nullopenglgraphics.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 #if defined USE_OPENGL
25 
27 
28 #ifdef DEBUG_BIND_TEXTURE
29 #include "logger.h"
30 #endif // DEBUG_BIND_TEXTURE
31 
33 
34 #include "resources/imagerect.h"
36 
37 #include "resources/image/image.h"
38 
39 #include "debug.h"
40 
42 #ifdef DEBUG_DRAW_CALLS
43 unsigned int NullOpenGLGraphics::mDrawCalls = 0;
44 unsigned int NullOpenGLGraphics::mLastDrawCalls = 0;
45 #endif // DEBUG_DRAW_CALLS
46 
48  mFloatTexArray(nullptr),
49  mIntTexArray(nullptr),
50  mIntVertArray(nullptr),
51  mTexture(false),
52  mIsByteColor(false),
53  mByteColor(),
54  mFloatColor(1.0F),
55  mMaxVertices(500),
56  mColorAlpha(false),
57 #ifdef DEBUG_BIND_TEXTURE
58  mOldTexture(),
59  mOldTextureId(0),
60 #endif // DEBUG_BIND_TEXTURE
61  mFbo()
62 {
64  mName = "null OpenGL";
65 }
66 
68 {
69  delete [] mFloatTexArray;
70  delete [] mIntTexArray;
71  delete [] mIntVertArray;
72 }
73 
74 void NullOpenGLGraphics::initArrays(const int vertCount) restrict2
75 {
76  mMaxVertices = vertCount;
77  if (mMaxVertices < 500)
78  mMaxVertices = 500;
79  else if (mMaxVertices > 1024)
80  mMaxVertices = 1024;
81 
82  // need alocate small size, after if limit reached reallocate to double size
83  vertexBufSize = mMaxVertices;
84  const size_t sz = mMaxVertices * 4 + 30;
85  if (mFloatTexArray == nullptr)
86  mFloatTexArray = new GLfloat[sz];
87  if (mIntTexArray == nullptr)
88  mIntTexArray = new GLint[sz];
89  if (mIntVertArray == nullptr)
90  mIntVertArray = new GLint[sz];
91 }
92 
94 {
95 }
96 
97 bool NullOpenGLGraphics::setVideoMode(const int w, const int h,
98  const int scale,
99  const int bpp,
100  const bool fs,
101  const bool hwaccel,
102  const bool resize,
103  const bool noFrame,
104  const bool allowHighDPI) restrict2
105 {
106  setMainFlags(w, h,
107  scale,
108  bpp,
109  fs,
110  hwaccel,
111  resize,
112  noFrame,
113  allowHighDPI);
114 
115  return setOpenGLMode();
116 }
117 
118 static inline void drawQuad(const Image *restrict const image A_UNUSED,
119  const int srcX A_UNUSED, const int srcY A_UNUSED,
120  const int dstX A_UNUSED, const int dstY A_UNUSED,
121  const int width A_UNUSED,
122  const int height A_UNUSED) A_NONNULL(1);
123 
124 static inline void drawQuad(const Image *restrict const image A_UNUSED,
125  const int srcX A_UNUSED, const int srcY A_UNUSED,
126  const int dstX A_UNUSED, const int dstY A_UNUSED,
127  const int width A_UNUSED,
128  const int height A_UNUSED)
129 {
130  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
131  {
132 #ifdef DEBUG_DRAW_CALLS
133  NullOpenGLGraphics::mDrawCalls ++;
134 #endif // DEBUG_DRAW_CALLS
135  }
136  else
137  {
138 #ifdef DEBUG_DRAW_CALLS
139  NullOpenGLGraphics::mDrawCalls ++;
140 #endif // DEBUG_DRAW_CALLS
141  }
142 }
143 
144 static inline void drawRescaledQuad(const Image *restrict const image A_UNUSED,
145  const int srcX A_UNUSED,
146  const int srcY A_UNUSED,
147  const int dstX A_UNUSED,
148  const int dstY A_UNUSED,
149  const int width A_UNUSED,
150  const int height A_UNUSED,
151  const int desiredWidth A_UNUSED,
152  const int desiredHeight A_UNUSED)
153 {
154  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
155  {
156 #ifdef DEBUG_DRAW_CALLS
157  NullOpenGLGraphics::mDrawCalls ++;
158 #endif // DEBUG_DRAW_CALLS
159  }
160  else
161  {
162 #ifdef DEBUG_DRAW_CALLS
163  NullOpenGLGraphics::mDrawCalls ++;
164 #endif // DEBUG_DRAW_CALLS
165  }
166 }
167 
168 void NullOpenGLGraphics::drawImage(const Image *restrict const image,
169  int dstX, int dstY) restrict2
170 {
171  drawImageInline(image, dstX, dstY);
172 }
173 
174 void NullOpenGLGraphics::copyImage(const Image *restrict const image,
175  int dstX, int dstY) restrict2
176 {
177  drawImageInline(image, dstX, dstY);
178 }
179 
180 void NullOpenGLGraphics::drawImageInline(const Image *restrict const image,
181  int dstX, int dstY) restrict2
182 {
183  FUNC_BLOCK("Graphics::drawImage", 1)
184  if (image == nullptr)
185  return;
186 
187  setColorAlpha(image->mAlpha);
188 #ifdef DEBUG_BIND_TEXTURE
189  debugBindTexture(image);
190 #endif // DEBUG_BIND_TEXTURE
191 
194 
195  const SDL_Rect &imageRect = image->mBounds;
196  drawQuad(image, imageRect.x, imageRect.y, dstX, dstY,
197  imageRect.w, imageRect.h);
198 }
199 
200 void NullOpenGLGraphics::drawImageCached(const Image *restrict const image
201  A_UNUSED,
202  int x A_UNUSED,
203  int y A_UNUSED) restrict2
204 {
205 }
206 
208  A_UNUSED,
209  const int x A_UNUSED,
210  const int y A_UNUSED,
211  const int w A_UNUSED,
212  const int h A_UNUSED) restrict2
213 {
214 }
215 
217 {
218 }
219 
221  int dstX, int dstY,
222  const int desiredWidth,
223  const int desiredHeight) restrict2
224 {
225  FUNC_BLOCK("Graphics::drawRescaledImage", 1)
226  if (image == nullptr)
227  return;
228 
229  const SDL_Rect &imageRect = image->mBounds;
230 
231  // Just draw the image normally when no resizing is necessary,
232  if (imageRect.w == desiredWidth && imageRect.h == desiredHeight)
233  {
234  drawImageInline(image, dstX, dstY);
235  return;
236  }
237 
238  setColorAlpha(image->mAlpha);
239 #ifdef DEBUG_BIND_TEXTURE
240  debugBindTexture(image);
241 #endif // DEBUG_BIND_TEXTURE
242 
245 
246  // Draw a textured quad.
247  drawRescaledQuad(image, imageRect.x, imageRect.y, dstX, dstY,
248  imageRect.w, imageRect.h, desiredWidth, desiredHeight);
249 }
250 
251 void NullOpenGLGraphics::drawPattern(const Image *restrict const image,
252  const int x, const int y,
253  const int w, const int h) restrict2
254 {
255  drawPatternInline(image, x, y, w, h);
256 }
257 
259  const int x, const int y,
260  const int w, const int h) restrict2
261 {
262  FUNC_BLOCK("Graphics::drawPattern", 1)
263  if (image == nullptr)
264  return;
265 
266  const SDL_Rect &imageRect = image->mBounds;
267  const int srcX = imageRect.x;
268  const int srcY = imageRect.y;
269  const int iw = imageRect.w;
270  const int ih = imageRect.h;
271 
272  if (iw == 0 || ih == 0)
273  return;
274 
275  setColorAlpha(image->mAlpha);
276 
277 #ifdef DEBUG_BIND_TEXTURE
278  debugBindTexture(image);
279 #endif // DEBUG_BIND_TEXTURE
280 
282 
284 
285  unsigned int vp = 0;
286  const unsigned int vLimit = mMaxVertices * 4;
287  // Draw a set of textured rectangles
288  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
289  {
290  const float tw = static_cast<float>(image->mTexWidth);
291  const float th = static_cast<float>(image->mTexHeight);
292 
293  const float texX1 = static_cast<float>(srcX) / tw;
294  const float texY1 = static_cast<float>(srcY) / th;
295 
296  for (int py = 0; py < h; py += ih)
297  {
298  const int height = (py + ih >= h) ? h - py : ih;
299  const int dstY = y + py;
300  const float texY2 = static_cast<float>(srcY + height) / th;
301  for (int px = 0; px < w; px += iw)
302  {
303  const int width = (px + iw >= w) ? w - px : iw;
304  const int dstX = x + px;
305 
306  const float texX2 = static_cast<float>(srcX + width) / tw;
307 
308  mFloatTexArray[vp + 0] = texX1;
309  mFloatTexArray[vp + 1] = texY1;
310 
311  mFloatTexArray[vp + 2] = texX2;
312  mFloatTexArray[vp + 3] = texY1;
313 
314  mFloatTexArray[vp + 4] = texX2;
315  mFloatTexArray[vp + 5] = texY2;
316 
317  mFloatTexArray[vp + 6] = texX1;
318  mFloatTexArray[vp + 7] = texY2;
319 
320  mIntVertArray[vp + 0] = dstX;
321  mIntVertArray[vp + 1] = dstY;
322 
323  mIntVertArray[vp + 2] = dstX + width;
324  mIntVertArray[vp + 3] = dstY;
325 
326  mIntVertArray[vp + 4] = dstX + width;
327  mIntVertArray[vp + 5] = dstY + height;
328 
329  mIntVertArray[vp + 6] = dstX;
330  mIntVertArray[vp + 7] = dstY + height;
331 
332  vp += 8;
333  if (vp >= vLimit)
334  {
335  drawQuadArrayfi(vp);
336  vp = 0;
337  }
338  }
339  }
340  if (vp > 0)
341  drawQuadArrayfi(vp);
342  }
343  else
344  {
345  for (int py = 0; py < h; py += ih)
346  {
347  const int height = (py + ih >= h) ? h - py : ih;
348  const int dstY = y + py;
349  for (int px = 0; px < w; px += iw)
350  {
351  const int width = (px + iw >= w) ? w - px : iw;
352  const int dstX = x + px;
353 
354  mIntTexArray[vp + 0] = srcX;
355  mIntTexArray[vp + 1] = srcY;
356 
357  mIntTexArray[vp + 2] = srcX + width;
358  mIntTexArray[vp + 3] = srcY;
359 
360  mIntTexArray[vp + 4] = srcX + width;
361  mIntTexArray[vp + 5] = srcY + height;
362 
363  mIntTexArray[vp + 6] = srcX;
364  mIntTexArray[vp + 7] = srcY + height;
365 
366  mIntVertArray[vp + 0] = dstX;
367  mIntVertArray[vp + 1] = dstY;
368 
369  mIntVertArray[vp + 2] = dstX + width;
370  mIntVertArray[vp + 3] = dstY;
371 
372  mIntVertArray[vp + 4] = dstX + width;
373  mIntVertArray[vp + 5] = dstY + height;
374 
375  mIntVertArray[vp + 6] = dstX;
376  mIntVertArray[vp + 7] = dstY + height;
377 
378  vp += 8;
379  if (vp >= vLimit)
380  {
381  drawQuadArrayii(vp);
382  vp = 0;
383  }
384  }
385  }
386  if (vp > 0)
387  drawQuadArrayii(vp);
388  }
389 }
390 
392  const int x, const int y,
393  const int w, const int h,
394  const int scaledWidth,
395  const int scaledHeight) restrict2
396 {
397  if (image == nullptr)
398  return;
399 
400  if (scaledWidth == 0 || scaledHeight == 0)
401  return;
402 
403  const SDL_Rect &imageRect = image->mBounds;
404  const int iw = imageRect.w;
405  const int ih = imageRect.h;
406  if (iw == 0 || ih == 0)
407  return;
408 
409  const int srcX = imageRect.x;
410  const int srcY = imageRect.y;
411 
412  setColorAlpha(image->mAlpha);
413 
414 #ifdef DEBUG_BIND_TEXTURE
415  debugBindTexture(image);
416 #endif // DEBUG_BIND_TEXTURE
417 
419 
421 
422  unsigned int vp = 0;
423  const unsigned int vLimit = mMaxVertices * 4;
424 
425  // Draw a set of textured rectangles
426  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
427  {
428  const float tw = static_cast<float>(image->mTexWidth);
429  const float th = static_cast<float>(image->mTexHeight);
430 
431  const float texX1 = static_cast<float>(srcX) / tw;
432  const float texY1 = static_cast<float>(srcY) / th;
433 
434  const float tFractionW = iw / tw;
435  const float tFractionH = ih / th;
436 
437  for (int py = 0; py < h; py += scaledHeight)
438  {
439  const int height = (py + scaledHeight >= h)
440  ? h - py : scaledHeight;
441  const int dstY = y + py;
442  const float visibleFractionH = static_cast<float>(height)
443  / scaledHeight;
444  const float texY2 = texY1 + tFractionH * visibleFractionH;
445  for (int px = 0; px < w; px += scaledWidth)
446  {
447  const int width = (px + scaledWidth >= w)
448  ? w - px : scaledWidth;
449  const int dstX = x + px;
450  const float visibleFractionW = static_cast<float>(width)
451  / scaledWidth;
452  const float texX2 = texX1 + tFractionW * visibleFractionW;
453 
454  mFloatTexArray[vp + 0] = texX1;
455  mFloatTexArray[vp + 1] = texY1;
456 
457  mFloatTexArray[vp + 2] = texX2;
458  mFloatTexArray[vp + 3] = texY1;
459 
460  mFloatTexArray[vp + 4] = texX2;
461  mFloatTexArray[vp + 5] = texY2;
462 
463  mFloatTexArray[vp + 6] = texX1;
464  mFloatTexArray[vp + 7] = texY2;
465 
466  mIntVertArray[vp + 0] = dstX;
467  mIntVertArray[vp + 1] = dstY;
468 
469  mIntVertArray[vp + 2] = dstX + width;
470  mIntVertArray[vp + 3] = dstY;
471 
472  mIntVertArray[vp + 4] = dstX + width;
473  mIntVertArray[vp + 5] = dstY + height;
474 
475  mIntVertArray[vp + 6] = dstX;
476  mIntVertArray[vp + 7] = dstY + height;
477 
478  vp += 8;
479  if (vp >= vLimit)
480  {
481  drawQuadArrayfi(vp);
482  vp = 0;
483  }
484  }
485  }
486  if (vp > 0)
487  drawQuadArrayfi(vp);
488  }
489  else
490  {
491  const float scaleFactorW = static_cast<float>(scaledWidth) / iw;
492  const float scaleFactorH = static_cast<float>(scaledHeight) / ih;
493 
494  for (int py = 0; py < h; py += scaledHeight)
495  {
496  const int height = (py + scaledHeight >= h)
497  ? h - py : scaledHeight;
498  const int dstY = y + py;
499  const int scaledY = srcY + height / scaleFactorH;
500  for (int px = 0; px < w; px += scaledWidth)
501  {
502  const int width = (px + scaledWidth >= w)
503  ? w - px : scaledWidth;
504  const int dstX = x + px;
505  const int scaledX = srcX + width / scaleFactorW;
506 
507  mIntTexArray[vp + 0] = srcX;
508  mIntTexArray[vp + 1] = srcY;
509 
510  mIntTexArray[vp + 2] = scaledX;
511  mIntTexArray[vp + 3] = srcY;
512 
513  mIntTexArray[vp + 4] = scaledX;
514  mIntTexArray[vp + 5] = scaledY;
515 
516  mIntTexArray[vp + 6] = srcX;
517  mIntTexArray[vp + 7] = scaledY;
518 
519  mIntVertArray[vp + 0] = dstX;
520  mIntVertArray[vp + 1] = dstY;
521 
522  mIntVertArray[vp + 2] = dstX + width;
523  mIntVertArray[vp + 3] = dstY;
524 
525  mIntVertArray[vp + 4] = dstX + width;
526  mIntVertArray[vp + 5] = dstY + height;
527 
528  mIntVertArray[vp + 6] = dstX;
529  mIntVertArray[vp + 7] = dstY + height;
530 
531  vp += 8;
532  if (vp >= vLimit)
533  {
534  drawQuadArrayii(vp);
535  vp = 0;
536  }
537  }
538  }
539  if (vp > 0)
540  drawQuadArrayii(vp);
541  }
542 }
543 
544 inline void NullOpenGLGraphics::drawVertexes(const
545  OpenGLGraphicsVertexes
546  &restrict ogl) restrict2
547 {
548  const STD_VECTOR<GLint*> &intVertPool = ogl.mIntVertPool;
549  STD_VECTOR<GLint*>::const_iterator iv;
550  const STD_VECTOR<GLint*>::const_iterator iv_end = intVertPool.end();
551  const STD_VECTOR<int> &vp = ogl.mVp;
552  STD_VECTOR<int>::const_iterator ivp;
553  const STD_VECTOR<int>::const_iterator ivp_end = vp.end();
554 
555  // Draw a set of textured rectangles
556  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
557  {
558  const STD_VECTOR<GLfloat*> &floatTexPool = ogl.mFloatTexPool;
559  STD_VECTOR<GLfloat*>::const_iterator ft;
560  const STD_VECTOR<GLfloat*>::const_iterator
561  ft_end = floatTexPool.end();
562 
563  for (iv = intVertPool.begin(), ft = floatTexPool.begin(),
564  ivp = vp.begin();
565  iv != iv_end && ft != ft_end && ivp != ivp_end;
566  ++ iv, ++ ft, ++ ivp)
567  {
568  drawQuadArrayfi(*iv, *ft, *ivp);
569  }
570  }
571  else
572  {
573  const STD_VECTOR<GLint*> &intTexPool = ogl.mIntTexPool;
574  STD_VECTOR<GLint*>::const_iterator it;
575  const STD_VECTOR<GLint*>::const_iterator it_end = intTexPool.end();
576 
577  for (iv = intVertPool.begin(), it = intTexPool.begin(),
578  ivp = vp.begin();
579  iv != iv_end && it != it_end && ivp != ivp_end;
580  ++ iv, ++ it, ++ ivp)
581  {
582  drawQuadArrayii(*iv, *it, *ivp);
583  }
584  }
585 }
586 
588  const Image *restrict const image,
589  const int x, const int y,
590  const int w, const int h) const restrict2
591 {
592  calcPatternInline(vert, image, x, y, w, h);
593 }
594 
596  const Image *restrict const image,
597  const int x,
598  const int y,
599  const int w,
600  const int h) const restrict2
601 {
602  if (image == nullptr || vert == nullptr)
603  return;
604 
605  const SDL_Rect &imageRect = image->mBounds;
606  const int iw = imageRect.w;
607  const int ih = imageRect.h;
608 
609  if (iw == 0 || ih == 0)
610  return;
611 
612  const int srcX = imageRect.x;
613  const int srcY = imageRect.y;
614  const unsigned int vLimit = mMaxVertices * 4;
615 
616  OpenGLGraphicsVertexes &ogl = vert->ogl;
617  unsigned int vp = ogl.continueVp();
618 
619  // Draw a set of textured rectangles
620  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
621  {
622  const float tw = static_cast<float>(image->mTexWidth);
623  const float th = static_cast<float>(image->mTexHeight);
624 
625  const float texX1 = static_cast<float>(srcX) / tw;
626  const float texY1 = static_cast<float>(srcY) / th;
627 
628  GLfloat *floatTexArray = ogl.continueFloatTexArray();
629  GLint *intVertArray = ogl.continueIntVertArray();
630 
631  for (int py = 0; py < h; py += ih)
632  {
633  const int height = (py + ih >= h) ? h - py : ih;
634  const int dstY = y + py;
635  const float texY2 = static_cast<float>(srcY + height) / th;
636  for (int px = 0; px < w; px += iw)
637  {
638  const int width = (px + iw >= w) ? w - px : iw;
639  const int dstX = x + px;
640  const float texX2 = static_cast<float>(srcX + width) / tw;
641 
642  floatTexArray[vp + 0] = texX1;
643  floatTexArray[vp + 1] = texY1;
644 
645  floatTexArray[vp + 2] = texX2;
646  floatTexArray[vp + 3] = texY1;
647 
648  floatTexArray[vp + 4] = texX2;
649  floatTexArray[vp + 5] = texY2;
650 
651  floatTexArray[vp + 6] = texX1;
652  floatTexArray[vp + 7] = texY2;
653 
654  intVertArray[vp + 0] = dstX;
655  intVertArray[vp + 1] = dstY;
656 
657  intVertArray[vp + 2] = dstX + width;
658  intVertArray[vp + 3] = dstY;
659 
660  intVertArray[vp + 4] = dstX + width;
661  intVertArray[vp + 5] = dstY + height;
662 
663  intVertArray[vp + 6] = dstX;
664  intVertArray[vp + 7] = dstY + height;
665 
666  vp += 8;
667  if (vp >= vLimit)
668  {
669  floatTexArray = ogl.switchFloatTexArray();
670  intVertArray = ogl.switchIntVertArray();
671  ogl.switchVp(vp);
672  vp = 0;
673  }
674  }
675  }
676  }
677  else
678  {
679  GLint *intTexArray = ogl.continueIntTexArray();
680  GLint *intVertArray = ogl.continueIntVertArray();
681 
682  for (int py = 0; py < h; py += ih)
683  {
684  const int height = (py + ih >= h) ? h - py : ih;
685  const int dstY = y + py;
686  for (int px = 0; px < w; px += iw)
687  {
688  const int width = (px + iw >= w) ? w - px : iw;
689  const int dstX = x + px;
690 
691  intTexArray[vp + 0] = srcX;
692  intTexArray[vp + 1] = srcY;
693 
694  intTexArray[vp + 2] = srcX + width;
695  intTexArray[vp + 3] = srcY;
696 
697  intTexArray[vp + 4] = srcX + width;
698  intTexArray[vp + 5] = srcY + height;
699 
700  intTexArray[vp + 6] = srcX;
701  intTexArray[vp + 7] = srcY + height;
702 
703  intVertArray[vp + 0] = dstX;
704  intVertArray[vp + 1] = dstY;
705 
706  intVertArray[vp + 2] = dstX + width;
707  intVertArray[vp + 3] = dstY;
708 
709  intVertArray[vp + 4] = dstX + width;
710  intVertArray[vp + 5] = dstY + height;
711 
712  intVertArray[vp + 6] = dstX;
713  intVertArray[vp + 7] = dstY + height;
714 
715  vp += 8;
716  if (vp >= vLimit)
717  {
718  intTexArray = ogl.switchIntTexArray();
719  intVertArray = ogl.switchIntVertArray();
720  ogl.switchVp(vp);
721  vp = 0;
722  }
723  }
724  }
725  }
726  ogl.switchVp(vp);
727 }
728 
730  restrict const vertCol,
731  const Image *restrict const image,
732  int x, int y) restrict2
733 {
734  if (vertCol == nullptr || image == nullptr)
735  return;
736  if (vertCol->currentGLImage != image->mGLImage)
737  {
738  ImageVertexes *const vert = new ImageVertexes;
739  vertCol->currentGLImage = image->mGLImage;
740  vertCol->currentVert = vert;
741  vert->image = image;
742  vertCol->draws.push_back(vert);
743  calcTileVertexesInline(vert, image, x, y);
744  }
745  else
746  {
747  calcTileVertexesInline(vertCol->currentVert, image, x, y);
748  }
749 }
750 
752  *restrict const vertCol) restrict2
753 {
754  const ImageVertexesVector &draws = vertCol->draws;
755  const ImageCollectionCIter it_end = draws.end();
756  for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
757  {
758  const ImageVertexes *const vert = *it;
759  const Image *const image = vert->image;
760 
761  setColorAlpha(image->mAlpha);
762 #ifdef DEBUG_BIND_TEXTURE
763  debugBindTexture(image);
764 #endif // DEBUG_BIND_TEXTURE
765 
768  drawVertexes(vert->ogl);
769  }
770 }
771 
773  const Image *restrict const image,
774  const int x, const int y,
775  const int w, const int h) const restrict2
776 {
777  if (vertCol == nullptr || image == nullptr)
778  return;
779  ImageVertexes *vert = nullptr;
780  if (vertCol->currentGLImage != image->mGLImage)
781  {
782  vert = new ImageVertexes;
783  vertCol->currentGLImage = image->mGLImage;
784  vertCol->currentVert = vert;
785  vert->image = image;
786  vertCol->draws.push_back(vert);
787  }
788  else
789  {
790  vert = vertCol->currentVert;
791  }
792 
793  calcPatternInline(vert, image, x, y, w, h);
794 }
795 
797  const Image *restrict const image,
798  int dstX, int dstY) const restrict2
799 {
800  calcTileVertexesInline(vert, image, dstX, dstY);
801 }
802 
804  restrict const vert,
805  const Image *
806  restrict const image,
807  int dstX,
808  int dstY) const restrict2
809 {
810  const SDL_Rect &imageRect = image->mBounds;
811  const int w = imageRect.w;
812  const int h = imageRect.h;
813 
814  if (w == 0 || h == 0)
815  return;
816 
817  const int srcX = imageRect.x;
818  const int srcY = imageRect.y;
819 
820  const unsigned int vLimit = mMaxVertices * 4;
821 
822  OpenGLGraphicsVertexes &ogl = vert->ogl;
823 
824 // STD_VECTOR<int> *vps = ogl.getVp();
825  unsigned int vp = ogl.continueVp();
826 
827  // Draw a set of textured rectangles
828  if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
829  {
830  const float tw = static_cast<float>(image->mTexWidth);
831  const float th = static_cast<float>(image->mTexHeight);
832 
833  const float texX1 = static_cast<float>(srcX) / tw;
834  const float texY1 = static_cast<float>(srcY) / th;
835 
836  const float texX2 = static_cast<float>(srcX + w) / tw;
837  const float texY2 = static_cast<float>(srcY + h) / th;
838 
839  GLfloat *const floatTexArray = ogl.continueFloatTexArray();
840  GLint *const intVertArray = ogl.continueIntVertArray();
841 
842  floatTexArray[vp + 0] = texX1;
843  floatTexArray[vp + 1] = texY1;
844 
845  floatTexArray[vp + 2] = texX2;
846  floatTexArray[vp + 3] = texY1;
847 
848  floatTexArray[vp + 4] = texX2;
849  floatTexArray[vp + 5] = texY2;
850 
851  floatTexArray[vp + 6] = texX1;
852  floatTexArray[vp + 7] = texY2;
853 
854  intVertArray[vp + 0] = dstX;
855  intVertArray[vp + 1] = dstY;
856 
857  intVertArray[vp + 2] = dstX + w;
858  intVertArray[vp + 3] = dstY;
859 
860  intVertArray[vp + 4] = dstX + w;
861  intVertArray[vp + 5] = dstY + h;
862 
863  intVertArray[vp + 6] = dstX;
864  intVertArray[vp + 7] = dstY + h;
865 
866  vp += 8;
867  if (vp >= vLimit)
868  {
869  ogl.switchFloatTexArray();
870  ogl.switchIntVertArray();
871  ogl.switchVp(vp);
872  vp = 0;
873  }
874  }
875  else
876  {
877  GLint *const intTexArray = ogl.continueIntTexArray();
878  GLint *const intVertArray = ogl.continueIntVertArray();
879 
880  intTexArray[vp + 0] = srcX;
881  intTexArray[vp + 1] = srcY;
882 
883  intTexArray[vp + 2] = srcX + w;
884  intTexArray[vp + 3] = srcY;
885 
886  intTexArray[vp + 4] = srcX + w;
887  intTexArray[vp + 5] = srcY + h;
888 
889  intTexArray[vp + 6] = srcX;
890  intTexArray[vp + 7] = srcY + h;
891 
892  intVertArray[vp + 0] = dstX;
893  intVertArray[vp + 1] = dstY;
894 
895  intVertArray[vp + 2] = dstX + w;
896  intVertArray[vp + 3] = dstY;
897 
898  intVertArray[vp + 4] = dstX + w;
899  intVertArray[vp + 5] = dstY + h;
900 
901  intVertArray[vp + 6] = dstX;
902  intVertArray[vp + 7] = dstY + h;
903 
904  vp += 8;
905  if (vp >= vLimit)
906  {
907  ogl.switchIntTexArray();
908  ogl.switchIntVertArray();
909  ogl.switchVp(vp);
910  vp = 0;
911  }
912  }
913  ogl.switchVp(vp);
914 }
915 
917  restrict const vert) restrict2
918 {
919  if (vert == nullptr)
920  return;
921  const Image *const image = vert->image;
922 
923  setColorAlpha(image->mAlpha);
924 #ifdef DEBUG_BIND_TEXTURE
925  debugBindTexture(image);
926 #endif // DEBUG_BIND_TEXTURE
927 
930  drawVertexes(vert->ogl);
931 }
932 
934  const int x, const int y,
935  const int w, const int h,
936  const ImageRect &restrict imgRect)
937  restrict2
938 {
939  ImageVertexes *vert = nullptr;
940  Image *const image = imgRect.grid[4];
941  if (image == nullptr)
942  return;
943  if (vertCol->currentGLImage != image->mGLImage)
944  {
945  vert = new ImageVertexes;
946  vertCol->currentGLImage = image->mGLImage;
947  vertCol->currentVert = vert;
948  vert->image = image;
949  vertCol->draws.push_back(vert);
950  }
951  else
952  {
953  vert = vertCol->currentVert;
954  }
955  calcImageRect(vert, x, y, w, h, imgRect);
956 }
957 
959 {
960  BLOCK_START("Graphics::updateScreen")
961 #ifdef DEBUG_DRAW_CALLS
962  mLastDrawCalls = mDrawCalls;
963  mDrawCalls = 0;
964 #endif // DEBUG_DRAW_CALLS
965 
966  BLOCK_END("Graphics::updateScreen")
967 }
968 
970 {
971  pushClipArea(Rect(0, 0, 640, 480));
972 }
973 
975 {
976  popClipArea();
977 }
978 
980 {
981  int transX = 0;
982  int transY = 0;
983 
984  if (!mClipStack.empty())
985  {
986  const ClipRect &clipArea = mClipStack.top();
987  transX = -clipArea.xOffset;
988  transY = -clipArea.yOffset;
989  }
990 
992 
993  const ClipRect &clipArea = mClipStack.top();
994  transX += clipArea.xOffset;
995  transY += clipArea.yOffset;
996 }
997 
999 {
1001 
1002  if (mClipStack.empty())
1003  return;
1004 }
1005 
1007 {
1009  restoreColor();
1010 }
1011 
1012 void NullOpenGLGraphics::drawLine(int x1, int y1,
1013  int x2, int y2) restrict2
1014 {
1016  restoreColor();
1017 
1018  mFloatTexArray[0] = static_cast<float>(x1) + 0.5F;
1019  mFloatTexArray[1] = static_cast<float>(y1) + 0.5F;
1020  mFloatTexArray[2] = static_cast<float>(x2) + 0.5F;
1021  mFloatTexArray[3] = static_cast<float>(y2) + 0.5F;
1022 
1023  drawLineArrayf(4);
1024 }
1025 
1027 {
1028  drawRectangle(rect, false);
1029 }
1030 
1032 {
1033  drawRectangle(rect, true);
1034 }
1035 
1037 {
1038  if (!mTexture)
1039  mTexture = true;
1040 
1041  if (!mAlpha)
1042  mAlpha = true;
1043 }
1044 
1046 {
1047  mTextureBinded = 0;
1048  if (mAlpha && !mColorAlpha)
1049  mAlpha = false;
1050  else if (!mAlpha && mColorAlpha)
1051  mAlpha = true;
1052 
1053  if (mTexture)
1054  mTexture = false;
1055 }
1056 
1058  const bool filled A_UNUSED) restrict2
1059 {
1060  BLOCK_START("Graphics::drawRectangle")
1062  restoreColor();
1063 
1064 #ifdef DEBUG_DRAW_CALLS
1065  mDrawCalls ++;
1066 #endif // DEBUG_DRAW_CALLS
1067 
1068  BLOCK_END("Graphics::drawRectangle")
1069 }
1070 
1071 void NullOpenGLGraphics::drawNet(const int x1, const int y1,
1072  const int x2, const int y2,
1073  const int width, const int height) restrict2
1074 {
1075  unsigned int vp = 0;
1076  const unsigned int vLimit = mMaxVertices * 4;
1077 
1079  restoreColor();
1080 
1081  const float xf1 = static_cast<float>(x1);
1082  const float xf2 = static_cast<float>(x2);
1083  const float yf1 = static_cast<float>(y1);
1084  const float yf2 = static_cast<float>(y2);
1085 
1086  for (int y = y1; y < y2; y += height)
1087  {
1088  mFloatTexArray[vp + 0] = xf1;
1089  mFloatTexArray[vp + 1] = static_cast<float>(y);
1090 
1091  mFloatTexArray[vp + 2] = xf2;
1092  mFloatTexArray[vp + 3] = static_cast<float>(y);
1093 
1094  vp += 4;
1095  if (vp >= vLimit)
1096  {
1097  drawLineArrayf(vp);
1098  vp = 0;
1099  }
1100  }
1101 
1102  for (int x = x1; x < x2; x += width)
1103  {
1104  mFloatTexArray[vp + 0] = static_cast<float>(x);
1105  mFloatTexArray[vp + 1] = yf1;
1106 
1107  mFloatTexArray[vp + 2] = static_cast<float>(x);
1108  mFloatTexArray[vp + 3] = yf2;
1109 
1110  vp += 4;
1111  if (vp >= vLimit)
1112  {
1113  drawLineArrayf(vp);
1114  vp = 0;
1115  }
1116  }
1117 
1118  if (vp > 0)
1119  drawLineArrayf(vp);
1120 }
1121 
1122 void NullOpenGLGraphics::bindTexture(const GLenum target A_UNUSED,
1123  const GLuint texture)
1124 {
1125  if (mTextureBinded != texture)
1126  mTextureBinded = texture;
1127 }
1128 
1130  restrict2
1131 {
1132 #ifdef DEBUG_DRAW_CALLS
1133  mDrawCalls ++;
1134 #endif // DEBUG_DRAW_CALLS
1135 }
1136 
1137 inline void NullOpenGLGraphics::drawQuadArrayfi(const GLint *restrict const
1138  intVertArray A_UNUSED,
1139  const GLfloat *restrict const
1140  floatTexArray A_UNUSED,
1141  const int size A_UNUSED)
1142  restrict2
1143 {
1144 #ifdef DEBUG_DRAW_CALLS
1145  mDrawCalls ++;
1146 #endif // DEBUG_DRAW_CALLS
1147 }
1148 
1150  restrict2
1151 {
1152 #ifdef DEBUG_DRAW_CALLS
1153  mDrawCalls ++;
1154 #endif // DEBUG_DRAW_CALLS
1155 }
1156 
1157 inline void NullOpenGLGraphics::drawQuadArrayii(const GLint *restrict const
1158  intVertArray A_UNUSED,
1159  const GLint *restrict const
1160  intTexArray A_UNUSED,
1161  const int size A_UNUSED)
1162  restrict2
1163 {
1164 #ifdef DEBUG_DRAW_CALLS
1165  mDrawCalls ++;
1166 #endif // DEBUG_DRAW_CALLS
1167 }
1168 
1170  restrict2
1171 {
1172 #ifdef DEBUG_DRAW_CALLS
1173  mDrawCalls ++;
1174 #endif // DEBUG_DRAW_CALLS
1175 }
1176 
1178  restrict2
1179 {
1180 #ifdef DEBUG_DRAW_CALLS
1181  mDrawCalls ++;
1182 #endif // DEBUG_DRAW_CALLS
1183 }
1184 
1186 {
1187 }
1188 
1189 void NullOpenGLGraphics::setColorAlpha(const float alpha) restrict2
1190 {
1191  if (!mIsByteColor && mFloatColor == alpha)
1192  return;
1193 
1194  mIsByteColor = false;
1195  mFloatColor = alpha;
1196 }
1197 
1199 {
1200  if (mIsByteColor && mByteColor == mColor)
1201  return;
1202 
1203  mIsByteColor = true;
1204  mByteColor = mColor;
1205 }
1206 
1207 void NullOpenGLGraphics::drawImageRect(const int x, const int y,
1208  const int w, const int h,
1209  const ImageRect &restrict imgRect)
1210  restrict2
1211 {
1213 }
1214 
1216  const int x, const int y,
1217  const int w, const int h,
1218  const ImageRect &restrict imgRect)
1219  restrict2
1220 {
1222 }
1223 
1225 {
1226 }
1227 
1228 #ifdef DEBUG_BIND_TEXTURE
1229 void NullOpenGLGraphics::debugBindTexture(const Image *restrict const image)
1230  restrict2
1231 {
1232  const std::string texture = image->mIdPath;
1233  if (mOldTexture != texture)
1234  {
1235  if ((!mOldTexture.empty() || !texture.empty())
1236  && mOldTextureId != image->mGLImage)
1237  {
1238  logger->log("bind: %s (%d) to %s (%d)", mOldTexture.c_str(),
1239  mOldTextureId, texture.c_str(), image->mGLImage);
1240  }
1241  mOldTextureId = image->mGLImage;
1242  mOldTexture = texture;
1243  }
1244 }
1245 #else // DEBUG_BIND_TEXTURE
1246 
1248  image A_UNUSED) restrict2
1249 {
1250 }
1251 #endif // DEBUG_BIND_TEXTURE
1252 #endif // USE_OPENGL
int yOffset
Definition: cliprect.h:127
int xOffset
Definition: cliprect.h:122
virtual void updateScreen()=0
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
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
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
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
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 drawLineArrayf(const int size) A_INLINE
void drawQuadArrayfi(const int size) A_INLINE
void drawLineArrayi(const int size) A_INLINE
void drawQuadArrayii(const int size) A_INLINE
Definition: rect.h:74
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
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
int size()
Definition: emotedb.cpp:306
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)
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)
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 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_NULL
Definition: rendertype.h:34
bool empty() const
Definition: mstack.h:88