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