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