ManaPlus
mobileopengl2graphics.cpp
Go to the documentation of this file.
1 /*
2  * The ManaPlus Client
3  * Copyright (C) 2004-2009 The Mana World Development Team
4  * Copyright (C) 2009-2010 The Mana Developers
5  * Copyright (C) 2011-2018 The ManaPlus Developers
6  *
7  * This file is part of The ManaPlus Client.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #if defined USE_OPENGL && !defined ANDROID
24 
26 
27 #include "graphicsmanager.h"
28 
29 #include "render/opengl/mgl.h"
30 #ifdef __native_client__
32 #endif // __native_client__
33 
36 
38 
39 #include "resources/imagerect.h"
40 
41 #include "resources/image/image.h"
42 
43 #include "utils/delete2.h"
44 #include "utils/foreach.h"
45 #include "utils/sdlcheckutils.h"
46 
47 #include "debug.h"
48 
49 #define vertFill2D(var, x1, y1, x2, y2, dstX, dstY, w, h) \
50  var[vp + 0] = dstX; \
51  var[vp + 1] = dstY; \
52  var[vp + 2] = x1; \
53  var[vp + 3] = y1; \
54  \
55  var[vp + 4] = dstX + w; \
56  var[vp + 5] = dstY; \
57  var[vp + 6] = x2; \
58  var[vp + 7] = y1; \
59  \
60  var[vp + 8] = dstX + w; \
61  var[vp + 9] = dstY + h; \
62  var[vp + 10] = x2; \
63  var[vp + 11] = y2; \
64  \
65  var[vp + 12] = dstX; \
66  var[vp + 13] = dstY; \
67  var[vp + 14] = x1; \
68  var[vp + 15] = y1; \
69  \
70  var[vp + 16] = dstX; \
71  var[vp + 17] = dstY + h; \
72  var[vp + 18] = x1; \
73  var[vp + 19] = y2; \
74  \
75  var[vp + 20] = dstX + w; \
76  var[vp + 21] = dstY + h; \
77  var[vp + 22] = x2; \
78  var[vp + 23] = y2;
79 
80 #define toGL static_cast<GLfloat>
81 
86 #ifdef DEBUG_DRAW_CALLS
87 unsigned int MobileOpenGL2Graphics::mDrawCalls = 0U;
88 unsigned int MobileOpenGL2Graphics::mLastDrawCalls = 0U;
89 #endif // DEBUG_DRAW_CALLS
90 
92  mFloatArray(nullptr),
93  mFloatArrayCached(nullptr),
94  mProgram(nullptr),
95  mAlphaCached(1.0F),
96  mVpCached(0),
97  mFloatColor(1.0F),
98  mMaxVertices(500),
99  mProgramId(0U),
100  mSimpleColorUniform(0U),
101  mPosAttrib(0),
102  mTextureColorUniform(0U),
103  mScreenUniform(0U),
104  mDrawTypeUniform(0U),
105 #ifndef __native_client__
106  mVao(0U),
107 #endif // __native_client__
108  mVbo(0U),
109  mVboBinded(0U),
110  mAttributesBinded(0U),
111  mColorAlpha(false),
112  mTextureDraw(false),
113 #ifdef DEBUG_BIND_TEXTURE
114  mOldTexture(),
115  mOldTextureId(0),
116 #endif // DEBUG_BIND_TEXTURE
117  mFbo()
118 {
120  mName = "mobile OpenGL ES 2";
121 }
122 
124 {
126  deleteGLObjects();
127 }
128 
130 {
131  delete2(mProgram);
132  if (mVbo != 0u)
133  mglDeleteBuffers(1, &mVbo);
134 #ifndef __native_client__
135  if (mVao != 0u)
136  mglDeleteVertexArrays(1, &mVao);
137 #endif // __native_client__
138 }
139 
141 {
142  mMaxVertices = vertCount;
143  if (mMaxVertices < 500)
144  mMaxVertices = 500;
145  else if (mMaxVertices > 1024)
146  mMaxVertices = 1024;
147 
148  // need alocate small size, after if limit reached reallocate to double size
149  const size_t sz = mMaxVertices * 4 + 30;
151  if (mFloatArray == nullptr)
152  mFloatArray = new GLfloat[sz];
153  if (mFloatArrayCached == nullptr)
154  mFloatArrayCached = new GLfloat[sz];
155 }
156 
158 {
159 #ifndef __native_client__
160  mglGenVertexArrays(1, &mVao);
161  mglBindVertexArray(mVao);
162 #endif // __native_client__
163  mglGenBuffers(1, &mVbo);
164 // logger->log("gen vbo buffer: %u", mVbo);
166 
167  logger->log("Compiling shaders");
169  if (mProgram == nullptr)
170  {
172  logger->safeError("Shader creation error. See manaplus.log.");
173  }
175  if (mProgramId == 0u)
176  logger->safeError("Shaders compilation error.");
177 
178  logger->log("Shaders compilation done.");
179  mglUseProgram(mProgramId);
180 
181  mPosAttrib = 0;
182 
183  mSimpleColorUniform = mglGetUniformLocation(mProgramId, "color");
184  mScreenUniform = mglGetUniformLocation(mProgramId, "screen");
185  mDrawTypeUniform = mglGetUniformLocation(mProgramId, "drawType");
186  mTextureColorUniform = mglGetUniformLocation(mProgramId, "alpha");
187  mTextureSizeUniform = mglGetUniformLocation(mProgramId, "textureSize");
188 
189  mglUniform1f(mTextureColorUniform, 1.0f);
190 
191  mglVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
192  mglEnableVertexAttribArray(0);
194 
195  mglUniform2f(mScreenUniform,
196  static_cast<float>(mWidth) / 2.0f,
197  static_cast<float>(mHeight) / 2.0f);
198  // for safty init texture size to 1x1
199  mglUniform2f(mTextureSizeUniform,
200  1.0f,
201  1.0f);
202  mglUniform4f(mSimpleColorUniform,
203  0.0F,
204  0.0F,
205  0.0F,
206  0.0F);
207 
208  mglActiveTexture(GL_TEXTURE0);
209 }
210 
212 {
213  deleteGLObjects();
214  mVboBinded = 0U;
215  mAttributesBinded = 0U;
216  mColor = Color(0, 0, 0, 0);
217  postInit();
218 }
219 
221 {
223 }
224 
226 {
227  delete [] mFloatArray;
228  mFloatArray = nullptr;
229  delete [] mFloatArrayCached;
230  mFloatArrayCached = nullptr;
231 }
232 
233 bool MobileOpenGL2Graphics::setVideoMode(const int w, const int h,
234  const int scale,
235  const int bpp,
236  const bool fs,
237  const bool hwaccel,
238  const bool resize,
239  const bool noFrame,
240  const bool allowHighDPI) restrict2
241 {
242  setMainFlags(w, h,
243  scale,
244  bpp,
245  fs,
246  hwaccel,
247  resize,
248  noFrame,
249  allowHighDPI);
250 
251  return setOpenGLMode();
252 }
253 
255 {
256  mColorAlpha = (color.a != 255);
257  if (mColor != color)
258  {
259  mColor = color;
260  mglUniform4f(mSimpleColorUniform,
261  static_cast<float>(color.r) / 255.0F,
262  static_cast<float>(color.g) / 255.0F,
263  static_cast<float>(color.b) / 255.0F,
264  static_cast<float>(color.a) / 255.0F);
265  }
266 }
267 
269 {
270  if (mAlphaCached != alpha)
271  {
272  mAlphaCached = alpha;
273  mglUniform1f(mTextureColorUniform, alpha);
274  }
275 }
276 
278  const int srcY,
279  const int dstX,
280  const int dstY,
281  const int width,
282  const int height) restrict2
283 {
284  const GLfloat texX2 = static_cast<GLfloat>(srcX + width);
285  const GLfloat texY2 = static_cast<GLfloat>(srcY + height);
286  const GLfloat x2 = static_cast<GLfloat>(dstX + width);
287  const GLfloat y2 = static_cast<GLfloat>(dstY + height);
288  const GLfloat srcX2 = toGL(srcX);
289  const GLfloat srcY2 = toGL(srcY);
290  const GLfloat dstX2 = toGL(dstX);
291  const GLfloat dstY2 = toGL(dstY);
292 
293  GLfloat vertices[] =
294  {
295  dstX2, dstY2, srcX2, srcY2,
296  x2, dstY2, texX2, srcY2,
297  dstX2, y2, srcX2, texY2,
298  x2, y2, texX2, texY2
299  };
300 
301  mglBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
302  vertices, GL_STREAM_DRAW);
303 #ifdef DEBUG_DRAW_CALLS
304  mDrawCalls ++;
305 #endif // DEBUG_DRAW_CALLS
306  mglDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
307 #ifdef OPENGLERRORS
309 #endif // OPENGLERRORS
310 }
311 
312 void MobileOpenGL2Graphics::drawRescaledQuad(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) restrict2
317 {
318  const GLfloat texX2 = static_cast<GLfloat>(srcX + width);
319  const GLfloat texY2 = static_cast<GLfloat>(srcY + height);
320  const GLfloat x2 = static_cast<GLfloat>(dstX + desiredWidth);
321  const GLfloat y2 = static_cast<GLfloat>(dstY + desiredHeight);
322  const GLfloat srcX2 = toGL(srcX);
323  const GLfloat srcY2 = toGL(srcY);
324  const GLfloat dstX2 = toGL(dstX);
325  const GLfloat dstY2 = toGL(dstY);
326 
327  GLfloat vertices[] =
328  {
329  dstX2, dstY2, srcX2, srcY2,
330  x2, dstY2, texX2, srcY2,
331  dstX2, y2, srcX2, texY2,
332  x2, y2, texX2, texY2
333  };
334 
335  mglBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
336  vertices, GL_STREAM_DRAW);
337 #ifdef DEBUG_DRAW_CALLS
338  mDrawCalls ++;
339 #endif // DEBUG_DRAW_CALLS
340  mglDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
341 #ifdef OPENGLERRORS
343 #endif // OPENGLERRORS
344 }
345 
347  int dstX, int dstY) restrict2
348 {
349  drawImageInline(image, dstX, dstY);
350 }
351 
353  int dstX, int dstY) restrict2
354 {
355  FUNC_BLOCK("Graphics::drawImage", 1)
356  if (image == nullptr)
357  return;
358 
359 #ifdef DEBUG_BIND_TEXTURE
360  debugBindTexture(image);
361 #endif // DEBUG_BIND_TEXTURE
362  bindTexture2(GL_TEXTURE_2D, image);
365  setColorAlpha(image->mAlpha);
366 
367  const ClipRect &clipArea = mClipStack.top();
368  const SDL_Rect &imageRect = image->mBounds;
369  drawQuad(imageRect.x,
370  imageRect.y,
371  dstX + clipArea.xOffset,
372  dstY + clipArea.yOffset,
373  imageRect.w,
374  imageRect.h);
375 }
376 
378  int dstX, int dstY) restrict2
379 {
380  drawImageInline(image, dstX, dstY);
381 }
382 
384 {
385 /*
386  GLfloat vertices[] =
387  {
388  0, 0, 0, 0,
389  800, 0, 800, 0,
390  0, 600, 0, 600,
391  800, 600, 800, 600
392  };
393 */
394 // logger->log("allocate: %d, %ld", mVboBinded, sizeof(vertices));
395 // mglBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
396 // vertices, GL_STREAM_DRAW);
397 #ifdef DEBUG_DRAW_CALLS
398  mDrawCalls ++;
399 #endif // DEBUG_DRAW_CALLS
400  mglDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
401 // glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
402 #ifdef OPENGLERRORS
404 #endif // OPENGLERRORS
405 }
406 
408  A_UNUSED,
409  int A_UNUSED x,
410  int y A_UNUSED) restrict2
411 {
412 }
413 
415  A_UNUSED,
416  const int x A_UNUSED,
417  const int y A_UNUSED,
418  const int w A_UNUSED,
419  const int h A_UNUSED) restrict2
420 {
421 }
422 
424 {
425 }
426 
428  restrict const image,
429  int dstX, int dstY,
430  const int desiredWidth,
431  const int desiredHeight)
432  restrict2
433 {
434  if (image == nullptr)
435  return;
436 
437  const SDL_Rect &imageRect = image->mBounds;
438 
439  // Just draw the image normally when no resizing is necessary,
440  if (imageRect.w == desiredWidth && imageRect.h == desiredHeight)
441  {
442  drawImageInline(image, dstX, dstY);
443  return;
444  }
445 
446  setColorAlpha(image->mAlpha);
447 #ifdef DEBUG_BIND_TEXTURE
448  debugBindTexture(image);
449 #endif // DEBUG_BIND_TEXTURE
450  bindTexture2(GL_TEXTURE_2D, image);
453 
454  const ClipRect &clipArea = mClipStack.top();
455  // Draw a textured quad.
456  drawRescaledQuad(imageRect.x,
457  imageRect.y,
458  dstX + clipArea.xOffset,
459  dstY + clipArea.yOffset,
460  imageRect.w,
461  imageRect.h,
462  desiredWidth,
463  desiredHeight);
464 }
465 
467  const int x, const int y,
468  const int w, const int h) restrict2
469 {
470  drawPatternInline(image, x, y, w, h);
471 }
472 
474  restrict const image,
475  const int x, const int y,
476  const int w, const int h)
477  restrict2
478 {
479  if (image == nullptr)
480  return;
481 
482  const SDL_Rect &imageRect = image->mBounds;
483  const int iw = imageRect.w;
484  const int ih = imageRect.h;
485 
486  if (iw == 0 || ih == 0)
487  return;
488 
489  const int srcX = imageRect.x;
490  const int srcY = imageRect.y;
491  const GLfloat srcX2 = toGL(srcX);
492  const GLfloat srcY2 = toGL(srcY);
493  const ClipRect &clipArea = mClipStack.top();
494  const int x2 = x + clipArea.xOffset;
495  const int y2 = y + clipArea.yOffset;
496 
497 #ifdef DEBUG_BIND_TEXTURE
498  debugBindTexture(image);
499 #endif // DEBUG_BIND_TEXTURE
500  bindTexture2(GL_TEXTURE_2D, image);
501 
504  setColorAlpha(image->mAlpha);
505 
506  unsigned int vp = 0;
507  const unsigned int vLimit = mMaxVertices * 4;
508 
509  for (int py = 0; py < h; py += ih)
510  {
511  const int height = (py + ih >= h) ? h - py : ih;
512  const GLfloat texY2 = static_cast<GLfloat>(srcY + height);
513  const GLfloat dstY = static_cast<GLfloat>(y2 + py);
514  for (int px = 0; px < w; px += iw)
515  {
516  const int width = (px + iw >= w) ? w - px : iw;
517  const GLfloat dstX = static_cast<GLfloat>(x2 + px);
518  const GLfloat texX2 = static_cast<GLfloat>(srcX + width);
519 
521  srcX2, srcY2, texX2, texY2,
522  dstX, dstY, width, height);
523 
524  vp += 24;
525  if (vp >= vLimit)
526  {
527  drawTriangleArray(vp);
528  vp = 0;
529  }
530  }
531  }
532  if (vp > 0)
533  drawTriangleArray(vp);
534 }
535 
537  restrict const image,
538  const int x, const int y,
539  const int w, const int h,
540  const int scaledWidth,
541  const int scaledHeight)
542  restrict2
543 {
544  if (image == nullptr)
545  return;
546 
547  if (scaledWidth == 0 || scaledHeight == 0)
548  return;
549 
550  const SDL_Rect &imageRect = image->mBounds;
551  const int iw = imageRect.w;
552  const int ih = imageRect.h;
553  if (iw == 0 || ih == 0)
554  return;
555 
556  const int srcX = imageRect.x;
557  const int srcY = imageRect.y;
558  const GLfloat srcX2 = toGL(srcX);
559  const GLfloat srcY2 = toGL(srcY);
560 
561 #ifdef DEBUG_BIND_TEXTURE
562  debugBindTexture(image);
563 #endif // DEBUG_BIND_TEXTURE
564  bindTexture2(GL_TEXTURE_2D, image);
565 
568  setColorAlpha(image->mAlpha);
569 
570  unsigned int vp = 0;
571  const unsigned int vLimit = mMaxVertices * 4;
572 
573  const ClipRect &clipArea = mClipStack.top();
574  const int x2 = x + clipArea.xOffset;
575  const int y2 = y + clipArea.yOffset;
576 
577  const float scaleFactorW = static_cast<float>(scaledWidth) / iw;
578  const float scaleFactorH = static_cast<float>(scaledHeight) / ih;
579 
580  for (int py = 0; py < h; py += scaledHeight)
581  {
582  const int height = (py + scaledHeight >= h)
583  ? h - py : scaledHeight;
584  const GLfloat dstY = static_cast<GLfloat>(y2 + py);
585  const GLfloat scaledY = srcY + height / scaleFactorH;
586  for (int px = 0; px < w; px += scaledWidth)
587  {
588  const int width = (px + scaledWidth >= w)
589  ? w - px : scaledWidth;
590  const GLfloat dstX = static_cast<GLfloat>(x2 + px);
591  const GLfloat scaledX = srcX + width / scaleFactorW;
592 
594  srcX2, srcY2,
595  scaledX, scaledY,
596  dstX, dstY,
597  static_cast<GLfloat>(width), static_cast<GLfloat>(height));
598 
599  vp += 24;
600  if (vp >= vLimit)
601  {
602  drawTriangleArray(vp);
603  vp = 0;
604  }
605  }
606  }
607  if (vp > 0)
608  drawTriangleArray(vp);
609 }
610 
613  restrict ogl) restrict2
614 {
615  const STD_VECTOR<int> &vp = ogl.mVp;
616  const STD_VECTOR<GLuint> &vbos = ogl.mVbo;
617  STD_VECTOR<int>::const_iterator ivp;
618  STD_VECTOR<GLuint>::const_iterator ivbo;
619  const STD_VECTOR<int>::const_iterator ivp_end = vp.end();
620 
621  for (ivp = vp.begin(), ivbo = vbos.begin();
622  ivp != ivp_end;
623  ++ ivp, ++ ivbo)
624  {
626 #ifdef DEBUG_DRAW_CALLS
627  mDrawCalls ++;
628 #endif // DEBUG_DRAW_CALLS
629  mglDrawArrays(GL_TRIANGLES, 0, *ivp / 4);
630 #ifdef OPENGLERRORS
632 #endif // OPENGLERRORS
633  }
634 }
635 
637  const Image *restrict const image,
638  const int x,
639  const int y,
640  const int w,
641  const int h) const restrict2
642 {
643  calcPatternInline(vert, image, x, y, w, h);
644 }
645 
647  restrict const vert,
648  const Image *
649  restrict const image,
650  const int x,
651  const int y,
652  const int w,
653  const int h) const restrict2
654 {
655  if (image == nullptr || vert == nullptr)
656  return;
657 
658  const SDL_Rect &imageRect = image->mBounds;
659  const int iw = imageRect.w;
660  const int ih = imageRect.h;
661 
662  if (iw == 0 || ih == 0)
663  return;
664 
665  const int srcX = imageRect.x;
666  const int srcY = imageRect.y;
667  const GLfloat srcX2 = toGL(srcX);
668  const GLfloat srcY2 = toGL(srcY);
669 
670  const ClipRect &clipArea = mClipStack.top();
671  const int x2 = x + clipArea.xOffset;
672  const int y2 = y + clipArea.yOffset;
673 
674  const unsigned int vLimit = mMaxVertices * 4;
675 
676  OpenGLGraphicsVertexes &ogl = vert->ogl;
677  unsigned int vp = ogl.continueVp();
678 
679  GLfloat *floatArray = ogl.continueFloatTexArray();
680 
681  for (int py = 0; py < h; py += ih)
682  {
683  const GLfloat height = static_cast<GLfloat>(
684  (py + ih >= h) ? h - py : ih);
685  const GLfloat dstY = static_cast<GLfloat>(y2 + py);
686  const GLfloat texY2 = srcY + height;
687  for (int px = 0; px < w; px += iw)
688  {
689  const GLfloat width = static_cast<GLfloat>(
690  (px + iw >= w) ? w - px : iw);
691  const GLfloat dstX = static_cast<GLfloat>(x2 + px);
692  const GLfloat texX2 = srcX2 + width;
693 
694  vertFill2D(floatArray,
695  srcX2, srcY2, texX2, texY2,
696  dstX, dstY, width, height);
697 
698  vp += 24;
699  if (vp >= vLimit)
700  {
701  floatArray = ogl.switchFloatTexArray();
702  ogl.switchVp(vp);
703  vp = 0;
704  }
705  }
706  }
707  ogl.switchVp(vp);
708 }
709 
711  restrict const vertCol,
712  const Image *
713  restrict const image,
714  int x, int y) restrict2
715 {
716  if (vertCol == nullptr || image == nullptr)
717  return;
718  if (vertCol->currentGLImage != image->mGLImage)
719  {
720  ImageVertexes *const vert = new ImageVertexes;
721  vertCol->currentGLImage = image->mGLImage;
722  vertCol->currentVert = vert;
723  vert->image = image;
724  vertCol->draws.push_back(vert);
725  calcTileVertexesInline(vert, image, x, y);
726  }
727  else
728  {
729  calcTileVertexesInline(vertCol->currentVert, image, x, y);
730  }
731 }
732 
734  *restrict const vertCol)
735  restrict2
736 {
738  const ImageVertexesVector &draws = vertCol->draws;
739  const ImageCollectionCIter it_end = draws.end();
740  for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
741  {
742  const ImageVertexes *const vert = *it;
743  const Image *const image = vert->image;
744 
745  setColorAlpha(image->mAlpha);
746 #ifdef DEBUG_BIND_TEXTURE
747  debugBindTexture(image);
748 #endif // DEBUG_BIND_TEXTURE
749  bindTexture2(GL_TEXTURE_2D, image);
750  drawVertexes(vert->ogl);
751  }
752 }
753 
755  vertCol,
756  const Image *restrict const image,
757  const int x,
758  const int y,
759  const int w,
760  const int h) const restrict2
761 {
762  if (vertCol == nullptr || image == nullptr)
763  return;
764  ImageVertexes *vert = nullptr;
765  if (vertCol->currentGLImage != image->mGLImage)
766  {
767  vert = new ImageVertexes;
768  vertCol->currentGLImage = image->mGLImage;
769  vertCol->currentVert = vert;
770  vert->image = image;
771  vertCol->draws.push_back(vert);
772  }
773  else
774  {
775  vert = vertCol->currentVert;
776  }
777 
778  calcPatternInline(vert, image, x, y, w, h);
779 }
780 
782  restrict const vert,
783  const Image *restrict const image,
784  int dstX,
785  int dstY) const restrict2
786 {
787  calcTileVertexesInline(vert, image, dstX, dstY);
788 }
789 
791  restrict const vert,
792  const Image *
793  restrict const image,
794  int dstX,
795  int dstY) const restrict2
796 {
797  const SDL_Rect &imageRect = image->mBounds;
798  const int w = imageRect.w;
799  const int h = imageRect.h;
800 
801  if (w == 0 || h == 0)
802  return;
803 
804  const int srcX = imageRect.x;
805  const int srcY = imageRect.y;
806  const GLfloat srcX2 = toGL(srcX);
807  const GLfloat srcY2 = toGL(srcY);
808 
809  const ClipRect &clipArea = mClipStack.top();
810  const GLfloat x2 = static_cast<GLfloat>(dstX + clipArea.xOffset);
811  const GLfloat y2 = static_cast<GLfloat>(dstY + clipArea.yOffset);
812 
813  const unsigned int vLimit = mMaxVertices * 4;
814 
815  OpenGLGraphicsVertexes &ogl = vert->ogl;
816 
817  unsigned int vp = ogl.continueVp();
818 
819  GLfloat texX2 = static_cast<GLfloat>(srcX + w);
820  GLfloat texY2 = static_cast<GLfloat>(srcY + h);
821 
822  GLfloat *const floatArray = ogl.continueFloatTexArray();
823 
824  vertFill2D(floatArray,
825  srcX2, srcY2, texX2, texY2,
826  x2, y2, w, h);
827 
828  vp += 24;
829  if (vp >= vLimit)
830  {
831  ogl.switchFloatTexArray();
832  ogl.switchVp(vp);
833  vp = 0;
834  }
835 
836  ogl.switchVp(vp);
837 }
838 
840  restrict const vert) restrict2
841 {
842  if (vert == nullptr)
843  return;
844  const Image *const image = vert->image;
845 
846  setColorAlpha(image->mAlpha);
847 #ifdef DEBUG_BIND_TEXTURE
848  debugBindTexture(image);
849 #endif // DEBUG_BIND_TEXTURE
850  bindTexture2(GL_TEXTURE_2D, image);
853 
854  drawVertexes(vert->ogl);
855 }
856 
858  const int x, const int y,
859  const int w, const int h,
860  const ImageRect &restrict imgRect)
861  restrict2
862 {
863  ImageVertexes *vert = nullptr;
864  const Image *const image = imgRect.grid[4];
865  if (image == nullptr)
866  return;
867  if (vertCol->currentGLImage != image->mGLImage)
868  {
869  vert = new ImageVertexes;
870  vertCol->currentGLImage = image->mGLImage;
871  vertCol->currentVert = vert;
872  vert->image = image;
873  vertCol->draws.push_back(vert);
874  }
875  else
876  {
877  vert = vertCol->currentVert;
878  }
879  calcImageRect(vert, x, y, w, h, imgRect);
880 }
881 
883 {
884  BLOCK_START("Graphics::updateScreen")
885 #ifdef DEBUG_DRAW_CALLS
886  mLastDrawCalls = mDrawCalls;
887  mDrawCalls = 0;
888 #endif // DEBUG_DRAW_CALLS
889 #ifdef USE_SDL2
890  SDL_GL_SwapWindow(mWindow);
891 #else // USE_SDL2
892  SDL_GL_SwapBuffers();
893 #endif // USE_SDL2
894 #ifdef DEBUG_OPENGL
895  if (isGLNotNull(mglFrameTerminator))
896  mglFrameTerminator();
897 #endif // DEBUG_OPENGL
898  BLOCK_END("Graphics::updateScreen")
899 }
900 
902 {
903  setOpenGLFlags();
904 #ifndef __native_client__
905  mglDisable(GL_VERTEX_PROGRAM_POINT_SIZE_ARB);
906  mglHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB, GL_FASTEST);
907 #endif // __native_client__
908  pushClipArea(Rect(0, 0, mRect.w, mRect.h));
909 }
910 
912 {
913  popClipArea();
914 }
915 
917 {
919  const ClipRect &clipArea = mClipStack.top();
920 
921  mglScissor(clipArea.x * mScale,
922  (mRect.h - clipArea.y - clipArea.height) * mScale,
923  clipArea.width * mScale,
924  clipArea.height * mScale);
925 }
926 
928 {
929  if (mClipStack.empty())
930  return;
932  if (mClipStack.empty())
933  return;
934 
935  const ClipRect &clipArea = mClipStack.top();
936  mglScissor(clipArea.x * mScale,
937  (mRect.h - clipArea.y - clipArea.height) * mScale,
938  clipArea.width * mScale,
939  clipArea.height * mScale);
940 }
941 
943 {
946  const ClipRect &clipArea = mClipStack.top();
947  GLfloat vertices[] =
948  {
949  toGL(x + clipArea.xOffset), toGL(y + clipArea.yOffset), 0.0f, 0.0f
950  };
951  mglBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
952  vertices, GL_STREAM_DRAW);
953 #ifdef DEBUG_DRAW_CALLS
954  mDrawCalls ++;
955 #endif // DEBUG_DRAW_CALLS
956  mglDrawArrays(GL_POINTS, 0, 1);
957 #ifdef OPENGLERRORS
959 #endif // OPENGLERRORS
960 }
961 
963  int x2, int y2) restrict2
964 {
967  const ClipRect &clipArea = mClipStack.top();
968  GLfloat vertices[] =
969  {
970  toGL(x1 + clipArea.xOffset), toGL(y1 + clipArea.yOffset), 0.0f, 0.0f,
971  toGL(x2 + clipArea.xOffset), toGL(y2 + clipArea.yOffset), 0.0f, 0.0f
972  };
973  mglBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
974  vertices, GL_STREAM_DRAW);
975 #ifdef DEBUG_DRAW_CALLS
976  mDrawCalls ++;
977 #endif // DEBUG_DRAW_CALLS
978  mglDrawArrays(GL_LINES, 0, 2);
979 #ifdef OPENGLERRORS
981 #endif // OPENGLERRORS
982 }
983 
985 {
988  const ClipRect &clipArea = mClipStack.top();
989  const GLfloat x1 = static_cast<GLfloat>(rect.x + clipArea.xOffset);
990  const GLfloat y1 = static_cast<GLfloat>(rect.y + clipArea.yOffset);
991  const GLfloat x2 = x1 + static_cast<GLfloat>(rect.width);
992  const GLfloat y2 = y1 + static_cast<GLfloat>(rect.height);
993  GLfloat vertices[] =
994  {
995  x1, y1, 0.0f, 0.0f,
996  x1, y2, 0.0f, 0.0f,
997  x2, y2, 0.0f, 0.0f,
998  x2, y1, 0.0f, 0.0f
999  };
1000 
1001  mglBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
1002  vertices, GL_STREAM_DRAW);
1003 #ifdef DEBUG_DRAW_CALLS
1004  mDrawCalls ++;
1005 #endif // DEBUG_DRAW_CALLS
1006  mglDrawArrays(GL_LINE_LOOP, 0, 4);
1007 #ifdef OPENGLERRORS
1009 #endif // OPENGLERRORS
1010 }
1011 
1013 {
1016  const ClipRect &clipArea = mClipStack.top();
1017  const GLfloat x1 = static_cast<GLfloat>(rect.x + clipArea.xOffset);
1018  const GLfloat y1 = static_cast<GLfloat>(rect.y + clipArea.yOffset);
1019  const GLfloat x2 = x1 + static_cast<GLfloat>(rect.width);
1020  const GLfloat y2 = y1 + static_cast<GLfloat>(rect.height);
1021  GLfloat vertices[] =
1022  {
1023  x1, y1, 0.0f, 0.0f,
1024  x2, y1, 0.0f, 0.0f,
1025  x1, y2, 0.0f, 0.0f,
1026  x2, y2, 0.0f, 0.0f
1027  };
1028 
1029  mglBufferData(GL_ARRAY_BUFFER, sizeof(vertices),
1030  vertices, GL_STREAM_DRAW);
1031 #ifdef DEBUG_DRAW_CALLS
1032  mDrawCalls ++;
1033 #endif // DEBUG_DRAW_CALLS
1034  mglDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1035 #ifdef OPENGLERRORS
1037 #endif // OPENGLERRORS
1038 }
1039 
1041 {
1042  if (!mTextureDraw)
1043  {
1044  mTextureDraw = true;
1045  mglUniform1f(mDrawTypeUniform, 1.0f);
1046  }
1047  if (!mAlpha)
1048  {
1049  mglEnable(GL_BLEND);
1050  mAlpha = true;
1051  }
1052 }
1053 
1055 {
1056  if (mTextureDraw)
1057  {
1058  mTextureDraw = false;
1059  mglUniform1f(mDrawTypeUniform, 0.0f);
1060  }
1061  if (mAlpha && !mColorAlpha)
1062  {
1063  mglDisable(GL_BLEND);
1064  mAlpha = false;
1065  }
1066  else if (!mAlpha && mColorAlpha)
1067  {
1068  mglEnable(GL_BLEND);
1069  mAlpha = true;
1070  }
1071 }
1072 
1074  const bool filled A_UNUSED) restrict2
1075 {
1076 }
1077 
1079  const int y1,
1080  const int x2,
1081  const int y2,
1082  const int width,
1083  const int height) restrict2
1084 {
1085  unsigned int vp = 0;
1086  const unsigned int vLimit = mMaxVertices * 4;
1087 
1090  const ClipRect &clipArea = mClipStack.top();
1091  const GLfloat dx = static_cast<GLfloat>(clipArea.xOffset);
1092  const GLfloat dy = static_cast<GLfloat>(clipArea.yOffset);
1093 
1094  const GLfloat xs1 = x1 + dx;
1095  const GLfloat xs2 = x2 + dx;
1096  const GLfloat ys1 = y1 + dy;
1097  const GLfloat ys2 = y2 + dy;
1098 
1099  for (int y = y1; y < y2; y += height)
1100  {
1101  mFloatArray[vp + 0] = xs1;
1102  mFloatArray[vp + 1] = toGL(y);
1103  mFloatArray[vp + 2] = 0.0f;
1104  mFloatArray[vp + 3] = 0.0f;
1105 
1106  mFloatArray[vp + 4] = xs2;
1107  mFloatArray[vp + 5] = toGL(y);
1108  mFloatArray[vp + 6] = 0.0f;
1109  mFloatArray[vp + 7] = 0.0f;
1110 
1111  vp += 8;
1112  if (vp >= vLimit)
1113  {
1114  drawLineArrays(vp);
1115  vp = 0;
1116  }
1117  }
1118 
1119  for (int x = x1; x < x2; x += width)
1120  {
1121  mFloatArray[vp + 0] = toGL(x);
1122  mFloatArray[vp + 1] = ys1;
1123  mFloatArray[vp + 2] = 0.0f;
1124  mFloatArray[vp + 3] = 0.0f;
1125 
1126  mFloatArray[vp + 4] = toGL(x);
1127  mFloatArray[vp + 5] = ys2;
1128  mFloatArray[vp + 6] = 0.0f;
1129  mFloatArray[vp + 7] = 0.0f;
1130 
1131  vp += 8;
1132  if (vp >= vLimit)
1133  {
1134  drawLineArrays(vp);
1135  vp = 0;
1136  }
1137  }
1138 
1139  if (vp > 0)
1140  drawLineArrays(vp);
1141 }
1142 
1143 void MobileOpenGL2Graphics::bindTexture2(const GLenum target,
1144  const Image *restrict const image)
1145 {
1146  const GLuint texture = image->mGLImage;
1147  if (mTextureBinded != texture)
1148  {
1149  mTextureBinded = texture;
1150  mglBindTexture(target, texture);
1151  if (mTextureWidth != image->mTexWidth ||
1152  mTextureHeight != image->mTexHeight)
1153  {
1154  mTextureWidth = image->mTexWidth;
1155  mTextureHeight = image->mTexHeight;
1156  mglUniform2f(mTextureSizeUniform,
1157  static_cast<GLfloat>(image->mTexWidth),
1158  static_cast<GLfloat>(image->mTexHeight));
1159  }
1160  }
1161 }
1162 
1163 void MobileOpenGL2Graphics::bindTexture(const GLenum target,
1164  const GLuint texture)
1165 {
1166  if (mTextureBinded != texture)
1167  {
1168  // for safty not storing textures because cant update size uniform
1169  mTextureBinded = 0;
1170  mglBindTexture(target, texture);
1171  }
1172 }
1173 
1174 void MobileOpenGL2Graphics::removeArray(const uint32_t sz,
1175  uint32_t *restrict const arr) restrict2
1176 {
1177  mglDeleteBuffers(sz, arr);
1178  for (size_t f = 0; f < sz; f ++)
1179  {
1180  if (arr[f] == mVboBinded)
1181  mVboBinded = 0;
1182  }
1183 }
1184 
1186 {
1187  if (mVboBinded != vbo)
1188  {
1189  mVboBinded = vbo;
1190  mglBindBuffer(GL_ARRAY_BUFFER, vbo);
1191  mAttributesBinded = 0U;
1192  }
1193 }
1194 
1196  restrict2
1197 {
1198  if (mVboBinded != vbo)
1199  {
1200  mVboBinded = vbo;
1201  mglBindBuffer(GL_ARRAY_BUFFER, vbo);
1202 
1204  mglVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
1205  }
1206  else if (mAttributesBinded != mVboBinded)
1207  {
1209  mglVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
1210  }
1211 }
1212 
1214 {
1216  {
1218  mglVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, nullptr);
1219  }
1220 }
1221 
1223 {
1224  GLint test[1000];
1225  logger->log("\n\n");
1226  logger->log("start opengl dump");
1227  for (int f = 0; f < 65535; f ++)
1228  {
1229  test[0] = 0;
1230  test[1] = 0;
1231  test[2] = 0;
1232  test[3] = 0;
1233  mglGetIntegerv(f, &test[0]);
1234  if (test[0] != 0 || test[1] != 0 || test[2] != 0 || test[3] != 0)
1235  {
1236  logger->log("\n%d = %d, %d, %d, %d", f,
1237  test[0], test[1], test[2], test[3]);
1238  }
1239  }
1240 }
1241 
1242 void MobileOpenGL2Graphics::drawImageRect(const int x, const int y,
1243  const int w, const int h,
1244  const ImageRect &restrict imgRect)
1245  restrict2
1246 {
1248 }
1249 
1251  const int x, const int y,
1252  const int w, const int h,
1253  const ImageRect &restrict imgRect)
1254  restrict2
1255 {
1257 }
1258 
1260 {
1261  mglClear(GL_COLOR_BUFFER_BIT |
1262  GL_DEPTH_BUFFER_BIT |
1263  GL_STENCIL_BUFFER_BIT);
1264 }
1265 
1267 {
1268  Graphics::createGLContext(custom);
1269 /*
1270  if (mGLContext)
1271  SDL::makeCurrentContext(mGLContext);
1272  else
1273  mGLContext = SDL::createGLContext(mWindow, 2, 0, 0x04);
1274 */
1275 }
1276 
1278  restrict2
1279 {
1280  if (col == nullptr)
1281  return;
1282  FOR_EACH (ImageCollectionIter, it, col->draws)
1283  finalize(*it);
1284 }
1285 
1287  restrict2
1288 {
1289  // in future need convert in each switchVp/continueVp
1290 
1291  if (vert == nullptr)
1292  return;
1293  OpenGLGraphicsVertexes &ogl = vert->ogl;
1294  const STD_VECTOR<int> &vp = ogl.mVp;
1295  STD_VECTOR<int>::const_iterator ivp;
1296  const STD_VECTOR<int>::const_iterator ivp_end = vp.end();
1297  STD_VECTOR<GLfloat*> &floatTexPool = ogl.mFloatTexPool;
1298  STD_VECTOR<GLfloat*>::const_iterator ft;
1299  const STD_VECTOR<GLfloat*>::const_iterator ft_end = floatTexPool.end();
1300  STD_VECTOR<GLuint> &vbos = ogl.mVbo;
1301  STD_VECTOR<GLuint>::const_iterator ivbo;
1302 
1303  const int sz = CAST_S32(floatTexPool.size());
1304  vbos.resize(sz);
1305  mglGenBuffers(sz, &vbos[0]);
1306 
1307  for (ft = floatTexPool.begin(), ivp = vp.begin(), ivbo = vbos.begin();
1308  ft != ft_end && ivp != ivp_end;
1309  ++ ft, ++ ivp, ++ ivbo)
1310  {
1311  bindArrayBuffer(*ivbo);
1312  mglBufferData(GL_ARRAY_BUFFER, (*ivp) * sizeof(GLfloat),
1313  *ft, GL_STATIC_DRAW);
1314  }
1315 
1316  for (STD_VECTOR<GLfloat*>::iterator it = floatTexPool.begin();
1317  it != floatTexPool.end(); ++ it)
1318  {
1319  delete [] (*it);
1320  }
1321  floatTexPool.clear();
1322 }
1323 
1325 {
1326  mglBufferData(GL_ARRAY_BUFFER, size * sizeof(GLfloat),
1328 #ifdef DEBUG_DRAW_CALLS
1329  mDrawCalls ++;
1330 #endif // DEBUG_DRAW_CALLS
1331  mglDrawArrays(GL_TRIANGLES, 0, size / 4);
1332 #ifdef OPENGLERRORS
1334 #endif // OPENGLERRORS
1335 }
1336 
1338  array,
1339  const int size) restrict2
1340 {
1341  mglBufferData(GL_ARRAY_BUFFER, size * sizeof(GLfloat),
1342  array, GL_STREAM_DRAW);
1343 #ifdef DEBUG_DRAW_CALLS
1344  mDrawCalls ++;
1345 #endif // DEBUG_DRAW_CALLS
1346  mglDrawArrays(GL_TRIANGLES, 0, size / 4);
1347 #ifdef OPENGLERRORS
1349 #endif // OPENGLERRORS
1350 }
1351 
1353 {
1354  mglBufferData(GL_ARRAY_BUFFER, size * sizeof(GLfloat),
1356 #ifdef DEBUG_DRAW_CALLS
1357  mDrawCalls ++;
1358 #endif // DEBUG_DRAW_CALLS
1359  mglDrawArrays(GL_LINES, 0, size / 4);
1360 #ifdef OPENGLERRORS
1362 #endif // OPENGLERRORS
1363 }
1364 
1365 #ifdef DEBUG_BIND_TEXTURE
1367  restrict2
1368 {
1369  const std::string texture = image->mIdPath;
1370  if (mOldTexture != texture)
1371  {
1372  if ((!mOldTexture.empty() || !texture.empty())
1373  && mOldTextureId != image->mGLImage)
1374  {
1375  logger->log("bind: %s (%d) to %s (%d)", mOldTexture.c_str(),
1376  mOldTextureId, texture.c_str(), image->mGLImage);
1377  }
1378  mOldTextureId = image->mGLImage;
1379  mOldTexture = texture;
1380  }
1381 }
1382 #else // DEBUG_BIND_TEXTURE
1384  image A_UNUSED) restrict2
1385 {
1386 }
1387 #endif // DEBUG_BIND_TEXTURE
1388 
1389 #endif // USE_OPENGL
static void bindTexture2(const GLenum target, const Image *const image)
#define FOR_EACH(type, iter, array)
Definition: foreach.h:24
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
std::vector< GLuint > mVbo
int width
Definition: rect.h:218
#define mglHint(...)
Definition: mgl.hpp:86
void drawTriangleArray(const int size) A_INLINE
std::string mName
Definition: graphics.h:548
SDL_Surface * mWindow
Definition: graphics.h:522
RenderType mOpenGL
Definition: graphics.h:544
#define GL_ARRAY_BUFFER
Definition: mgldefines.h:83
void calcPatternInline(ImageVertexes *const vert, const Image *const image, const int x, const int y, const int w, const int h) const A_INLINE
#define isGLNotNull(func)
Definition: mglcheck.h:27
void drawRescaledQuad(const int srcX, const int srcY, const int dstX, const int dstY, const int width, const int height, const int desiredWidth, const int desiredHeight) A_INLINE
void finalize(ImageCollection *const col)
void removeArray(const uint32_t id, uint32_t *const arr)
std::vector< ImageVertexes * > ImageVertexesVector
Definition: imagevertexes.h:55
Definition: rect.h:72
void calcTileVertexes(ImageVertexes *const vert, const Image *const image, int x, int y) const
int mWidth
Definition: graphics.h:483
#define BLOCK_START(name)
Definition: perfomance.h:78
#define toGL
void bindArrayBufferAndAttributes(const GLuint vbo) A_INLINE
const Image * image
Definition: imagevertexes.h:47
#define mglBindTexture(...)
Definition: mgl.hpp:92
unsigned int vertexBufSize
void fillRectangle(const Rect &rect)
#define BLOCK_END(name)
Definition: perfomance.h:79
ImageVertexesVector::iterator ImageCollectionIter
Definition: imagevertexes.h:56
int yOffset
Definition: cliprect.h:126
void drawRectangle(const Rect &rect)
virtual void popClipArea()
Definition: graphics.cpp:738
#define mglScissor(...)
Definition: mgl.hpp:88
#define delete2(var)
Definition: delete2.h:24
unsigned int getProgramId() const
Definition: shaderprogram.h:41
void copyImage(const Image *const image, int dstX, int dstY)
void drawNet(const int x1, const int y1, const int x2, const int y2, const int width, const int height)
#define vertFill2D(var, x1, y1, x2, y2, dstX, dstY, w, h)
ImageVertexesVector::const_iterator ImageCollectionCIter
Definition: imagevertexes.h:57
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 setColor(const Color &color)
Logger * logger
Definition: logger.cpp:95
Color mColor
Definition: graphics.h:552
void drawImageInline(const Image *const image, int dstX, int dstY) A_INLINE
#define mglClear(...)
Definition: mgl.hpp:96
int x
Definition: rect.h:208
void drawLine(int x1, int y1, int x2, int y2)
#define CAST_S32
Definition: cast.h:29
static void bindTexture(const GLenum target, const GLuint texture)
void drawPatternCached(const Image *const image, const int x, const int y, const int w, const int h)
void calcPattern(ImageVertexes *const vert, const Image *const image, const int x, const int y, const int w, const int h) const
void calcImageRect(ImageVertexes *const vert, int x, int y, int w, int h, const ImageRect &imgRect) A_INLINE
int xOffset
Definition: cliprect.h:121
int y
Definition: rect.h:213
void safeError(const std::string &error_text) __attribute__((noreturn))
Definition: logger.cpp:378
bool mAlpha
Definition: graphics.h:537
void drawVertexes(const OpenGLGraphicsVertexes &ogl) A_INLINE
#define GL_STREAM_DRAW
Definition: mgldefines.h:88
void drawPattern(const Image *const image, const int x, const int y, const int w, const int h)
#define nullptr
Definition: localconsts.h:44
void debugBindTexture(const Image *const image)
#define mglDrawArrays(...)
Definition: mgl.hpp:82
float mAlpha
Definition: image.h:212
int height
Definition: rect.h:223
int mHeight
Definition: graphics.h:484
void drawTileCollection(const ImageCollection *const vertCol)
#define GL_STATIC_DRAW
Definition: mgldefines.h:89
void calcTileCollection(ImageCollection *const vertCol, const Image *const image, int x, int y)
#define FUNC_BLOCK(name, id)
Definition: perfomance.h:80
SDL_Rect mRect
Definition: graphics.h:542
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 drawImageRect(int x, int y, int w, int h, const ImageRect &imgRect)
void setOpenGLFlags()
Definition: graphics.cpp:747
GLuint mGLImage
Definition: image.h:182
void drawTileVertexes(const ImageVertexes *const vert)
void drawLineArrays(const int size) A_INLINE
virtual void createGLContext(const bool custom)
Definition: graphics.cpp:417
ShadersManager shaders
std::vector< GLfloat * > mFloatTexPool
#define A_UNUSED
Definition: localconsts.h:171
static void logError()
void initArrays(const int vertCount)
#define mglGetIntegerv(...)
Definition: mgl.hpp:94
int mScale
Definition: graphics.h:551
MStack< ClipRect > mClipStack
Definition: graphics.h:520
void createGLContext(const bool custom)
Definition: image.h:61
void drawRescaledImage(const Image *const image, int dstX, int dstY, const int desiredWidth, const int desiredHeight)
void pushClipArea(const Rect &area)
Definition: color.h:74
virtual void pushClipArea(const Rect &area)
Definition: graphics.cpp:676
#define restrict
Definition: localconsts.h:176
void drawImage(const Image *const image, int dstX, int dstY)
#define mglDisable(...)
Definition: mgl.hpp:84
T & top() const
Definition: mstack.h:72
void drawImageCached(const Image *const image, int x, int y)
void bindArrayBuffer(const GLuint vbo) A_INLINE
void log(const char *const log_text,...)
Definition: logger.cpp:243
OpenGLGraphicsVertexes ogl
Definition: imagevertexes.h:49
void calcTileVertexesInline(ImageVertexes *const vert, const Image *const image, int x, int y) const A_INLINE
void calcWindow(ImageCollection *const vertCol, const int x, const int y, const int w, const int h, const ImageRect &imgRect)
void drawQuad(const int srcX, const int srcY, const int dstX, const int dstY, const int width, const int height) A_INLINE
bool empty() const
Definition: mstack.h:87
GraphicsManager graphicsManager
#define restrict2
Definition: localconsts.h:177
void setColorAlpha(const float alpha) A_INLINE
bool setOpenGLMode()
Definition: graphics.cpp:282
void drawPatternInline(const Image *const image, const int x, const int y, const int w, const int h) A_INLINE
#define mglEnable(...)
Definition: mgl.hpp:90
ShaderProgram * getGles2Program()