25 #if !defined(ANDROID) && !defined(__native_client__) && !defined(__SWITCH__)
32 #ifdef __native_client__
53 #define vertFill2D(var, x1, y1, x2, y2, dstX, dstY, w, h) \
59 var[vp + 4] = dstX + w; \
64 var[vp + 8] = dstX + w; \
65 var[vp + 9] = dstY + h; \
69 var[vp + 12] = dstX; \
70 var[vp + 13] = dstY; \
74 var[vp + 16] = dstX; \
75 var[vp + 17] = dstY + h; \
79 var[vp + 20] = dstX + w; \
80 var[vp + 21] = dstY + h; \
85 #ifdef DEBUG_DRAW_CALLS
86 unsigned int ModernOpenGLGraphics::mDrawCalls = 0;
87 unsigned int ModernOpenGLGraphics::mLastDrawCalls = 0;
99 mSimpleColorUniform(0U),
101 mTextureColorUniform(0U),
103 mDrawTypeUniform(0U),
109 mAttributesBinded(0U),
112 #ifdef DEBUG_BIND_TEXTURE
119 mName =
"modern OpenGL";
134 mglDeleteBuffers(1, &
mVbo);
139 mglDeleteBuffers(1, &
mEbo);
142 mglDeleteVertexArrays(1, &
mVao);
147 mMaxVertices = vertCount;
148 if (mMaxVertices < 500)
150 else if (mMaxVertices > 1024)
154 const size_t sz = mMaxVertices * 4 + 30;
156 if (mIntArray ==
nullptr)
157 mIntArray =
new GLint[sz];
158 if (mIntArrayCached ==
nullptr)
159 mIntArrayCached =
new GLint[sz];
164 mglGenVertexArrays(1, &
mVao);
165 mglBindVertexArray(
mVao);
166 mglGenBuffers(1, &
mVbo);
169 mglGenBuffers(1, &
mEbo);
184 logger->
log(
"Shaders compilation done.");
189 mglVertexAttribIFormat(
mPosAttrib, 4, GL_INT, 0);
198 mglBindVertexBuffer(0,
mVbo, 0, 4 *
sizeof(GLint));
204 static_cast<float>(
mWidth) / 2.0F,
205 static_cast<float>(
mHeight) / 2.0F);
254 return setOpenGLMode();
259 mColorAlpha = (color.a != 255);
263 mglUniform4f(mSimpleColorUniform,
264 static_cast<float>(color.r) / 255.0F,
265 static_cast<float>(color.g) / 255.0F,
266 static_cast<float>(color.b) / 255.0F,
267 static_cast<float>(color.a) / 255.0F);
273 if (mAlphaCached != alpha)
275 mAlphaCached = alpha;
276 mglUniform1f(mTextureColorUniform, alpha);
287 const int texX2 = srcX + width;
288 const int texY2 = srcY + height;
289 const int x2 = dstX + width;
290 const int y2 = dstY + height;
294 dstX, dstY, srcX, srcY,
295 x2, dstY, texX2, srcY,
296 dstX, y2, srcX, texY2,
303 #ifdef DEBUG_DRAW_CALLS
313 const int dstX,
const int dstY,
314 const int width,
const int height,
315 const int desiredWidth,
318 const int texX2 = srcX + width;
319 const int texY2 = srcY + height;
320 const int x2 = dstX + desiredWidth;
321 const int y2 = dstY + desiredHeight;
325 dstX, dstY, srcX, srcY,
326 x2, dstY, texX2, srcY,
327 dstX, y2, srcX, texY2,
334 #ifdef DEBUG_DRAW_CALLS
353 if (image ==
nullptr)
356 #ifdef DEBUG_BIND_TEXTURE
361 bindArrayBufferAndAttributes(mVbo);
364 const ClipRect &clipArea = mClipStack.top();
365 const SDL_Rect &imageRect = image->mBounds;
368 imageRect.w, imageRect.h);
394 #ifdef DEBUG_DRAW_CALLS
426 const int desiredWidth,
429 if (image ==
nullptr)
432 const SDL_Rect &imageRect = image->mBounds;
435 if (imageRect.w == desiredWidth && imageRect.h == desiredHeight)
442 #ifdef DEBUG_BIND_TEXTURE
447 bindArrayBufferAndAttributes(mVbo);
449 const ClipRect &clipArea = mClipStack.top();
453 imageRect.w, imageRect.h,
454 desiredWidth, desiredHeight);
458 const int x,
const int y,
470 if (image ==
nullptr)
473 const SDL_Rect &imageRect = image->mBounds;
474 const int srcX = imageRect.x;
475 const int srcY = imageRect.y;
476 const int iw = imageRect.w;
477 const int ih = imageRect.h;
479 if (iw == 0 || ih == 0)
482 const ClipRect &clipArea = mClipStack.top();
483 const int x2 =
x + clipArea.
xOffset;
484 const int y2 =
y + clipArea.
yOffset;
486 #ifdef DEBUG_BIND_TEXTURE
493 bindArrayBufferAndAttributes(mVbo);
497 const unsigned int vLimit = mMaxVertices * 4;
499 for (
int py = 0; py < h; py += ih)
501 const int height = (py + ih >= h) ? h - py : ih;
502 const int texY2 = srcY + height;
503 const int dstY = y2 + py;
504 for (
int px = 0; px < w; px += iw)
506 const int width = (px + iw >= w) ? w - px : iw;
507 const int dstX = x2 + px;
509 const int texX2 = srcX + width;
512 srcX, srcY, texX2, texY2,
513 dstX, dstY, width, height);
518 drawTriangleArray(vp);
524 drawTriangleArray(vp);
529 const int x,
const int y,
530 const int w,
const int h,
531 const int scaledWidth,
532 const int scaledHeight)
535 if (image ==
nullptr)
538 if (scaledWidth == 0 || scaledHeight == 0)
541 const SDL_Rect &imageRect = image->mBounds;
542 const int srcX = imageRect.x;
543 const int srcY = imageRect.y;
544 const int iw = imageRect.w;
545 const int ih = imageRect.h;
546 if (iw == 0 || ih == 0)
549 #ifdef DEBUG_BIND_TEXTURE
556 bindArrayBufferAndAttributes(mVbo);
560 const unsigned int vLimit = mMaxVertices * 4;
562 const ClipRect &clipArea = mClipStack.top();
563 const int x2 =
x + clipArea.
xOffset;
564 const int y2 =
y + clipArea.
yOffset;
566 const float scaleFactorW =
static_cast<float>(scaledWidth) / iw;
567 const float scaleFactorH =
static_cast<float>(scaledHeight) / ih;
569 for (
int py = 0; py < h; py += scaledHeight)
571 const int height = (py + scaledHeight >= h)
572 ? h - py : scaledHeight;
573 const int dstY = y2 + py;
574 const int scaledY = srcY + height / scaleFactorH;
575 for (
int px = 0; px < w; px += scaledWidth)
577 const int width = (px + scaledWidth >= w)
578 ? w - px : scaledWidth;
579 const int dstX = x2 + px;
580 const int scaledX = srcX + width / scaleFactorW;
583 srcX, srcY, scaledX, scaledY,
584 dstX, dstY, width, height);
589 drawTriangleArray(vp);
595 drawTriangleArray(vp);
599 OpenGLGraphicsVertexes &
602 const STD_VECTOR<int> &vp = ogl.mVp;
603 const STD_VECTOR<GLuint> &vbos = ogl.mVbo;
604 STD_VECTOR<int>::const_iterator ivp;
605 STD_VECTOR<GLuint>::const_iterator ivbo;
606 const STD_VECTOR<int>::const_iterator ivp_end = vp.end();
613 for (ivp = vp.begin(), ivbo = vbos.begin();
617 bindArrayBufferAndAttributes(*ivbo);
618 #ifdef DEBUG_DRAW_CALLS
647 if (image ==
nullptr || vert ==
nullptr)
650 const SDL_Rect &imageRect = image->mBounds;
651 const int srcX = imageRect.x;
652 const int srcY = imageRect.y;
653 const int iw = imageRect.w;
654 const int ih = imageRect.h;
656 if (iw == 0 || ih == 0)
659 const ClipRect &clipArea = mClipStack.top();
660 const int x2 =
x + clipArea.
xOffset;
661 const int y2 =
y + clipArea.
yOffset;
663 const unsigned int vLimit = mMaxVertices * 4;
665 OpenGLGraphicsVertexes &ogl = vert->ogl;
666 unsigned int vp = ogl.continueVp();
668 GLint *intArray = ogl.continueIntTexArray();
670 for (
int py = 0; py < h; py += ih)
672 const int height = (py + ih >= h) ? h - py : ih;
673 const int dstY = y2 + py;
674 const int texY2 = srcY + height;
675 for (
int px = 0; px < w; px += iw)
677 const int width = (px + iw >= w) ? w - px : iw;
678 const int dstX = x2 + px;
679 const int texX2 = srcX + width;
682 srcX, srcY, texX2, texY2,
683 dstX, dstY, width, height);
688 intArray = ogl.switchIntTexArray();
703 if (vertCol ==
nullptr || image ==
nullptr)
705 if (vertCol->currentGLImage != image->mGLImage)
708 vertCol->currentGLImage = image->mGLImage;
709 vertCol->currentVert = vert;
711 vertCol->draws.push_back(vert);
740 #ifdef DEBUG_BIND_TEXTURE
756 if (vertCol ==
nullptr || image ==
nullptr)
759 if (vertCol->currentGLImage != image->mGLImage)
762 vertCol->currentGLImage = image->mGLImage;
763 vertCol->currentVert = vert;
765 vertCol->draws.push_back(vert);
769 vert = vertCol->currentVert;
789 const SDL_Rect &imageRect = image->mBounds;
790 const int srcX = imageRect.x;
791 const int srcY = imageRect.y;
792 const int w = imageRect.w;
793 const int h = imageRect.h;
795 if (w == 0 || h == 0)
798 const ClipRect &clipArea = mClipStack.top();
799 const int x2 = dstX + clipArea.
xOffset;
800 const int y2 = dstY + clipArea.
yOffset;
802 const unsigned int vLimit = mMaxVertices * 4;
804 OpenGLGraphicsVertexes &ogl = vert->
ogl;
806 unsigned int vp = ogl.continueVp();
808 int texX2 = srcX + w;
809 int texY2 = srcY + h;
811 GLint *
const intArray = ogl.continueIntTexArray();
814 srcX, srcY, texX2, texY2,
820 ogl.switchIntTexArray();
836 #ifdef DEBUG_BIND_TEXTURE
842 bindArrayBufferAndAttributes(mVbo);
848 const int x,
const int y,
849 const int w,
const int h,
854 const Image *
const image = imgRect.grid[4];
855 if (image ==
nullptr)
857 if (vertCol->currentGLImage != image->mGLImage)
860 vertCol->currentGLImage = image->mGLImage;
861 vertCol->currentVert = vert;
863 vertCol->draws.push_back(vert);
867 vert = vertCol->currentVert;
875 #ifdef DEBUG_DRAW_CALLS
876 mLastDrawCalls = mDrawCalls;
882 SDL_GL_SwapBuffers();
886 mglFrameTerminator();
895 mglHint(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB, GL_FASTEST);
907 const ClipRect &clipArea = mClipStack.top();
910 (mRect.h - clipArea.
y - clipArea.
height) * mScale,
911 clipArea.
width * mScale,
912 clipArea.
height * mScale);
933 bindArrayBufferAndAttributes(mVbo);
934 const ClipRect &clipArea = mClipStack.top();
942 #ifdef DEBUG_DRAW_CALLS
955 bindArrayBufferAndAttributes(mVbo);
956 const ClipRect &clipArea = mClipStack.top();
965 #ifdef DEBUG_DRAW_CALLS
977 bindArrayBufferAndAttributes(mVbo);
978 const ClipRect &clipArea = mClipStack.top();
979 const int x1 = rect.
x + clipArea.
xOffset;
980 const int y1 = rect.y + clipArea.
yOffset;
981 const int x2 = x1 + rect.width;
982 const int y2 = y1 + rect.height;
994 #ifdef DEBUG_DRAW_CALLS
1006 bindArrayBufferAndAttributes(mVbo);
1007 const ClipRect &clipArea = mClipStack.top();
1008 const int x1 = rect.
x + clipArea.
xOffset;
1009 const int y1 = rect.y + clipArea.
yOffset;
1010 const int x2 = x1 + rect.width;
1011 const int y2 = y1 + rect.height;
1023 #ifdef DEBUG_DRAW_CALLS
1071 const int x2,
const int y2,
1072 const int width,
const int height)
restrict2
1074 unsigned int vp = 0;
1075 const unsigned int vLimit = mMaxVertices * 4;
1078 bindArrayBufferAndAttributes(mVbo);
1079 const ClipRect &clipArea = mClipStack.top();
1080 const GLint dx = clipArea.
xOffset;
1081 const GLint dy = clipArea.
yOffset;
1083 const GLint xs1 = x1 + dx;
1084 const GLint xs2 = x2 + dx;
1085 const GLint ys1 = y1 + dy;
1086 const GLint ys2 = y2 + dy;
1088 for (
int y = y1;
y < y2;
y += height)
1090 mIntArray[vp + 0] = xs1;
1091 mIntArray[vp + 1] =
y;
1092 mIntArray[vp + 2] = 0;
1093 mIntArray[vp + 3] = 0;
1095 mIntArray[vp + 4] = xs2;
1096 mIntArray[vp + 5] =
y;
1097 mIntArray[vp + 6] = 0;
1098 mIntArray[vp + 7] = 0;
1108 for (
int x = x1;
x < x2;
x += width)
1110 mIntArray[vp + 0] =
x;
1111 mIntArray[vp + 1] = ys1;
1112 mIntArray[vp + 2] = 0.0F;
1113 mIntArray[vp + 3] = 0.0F;
1115 mIntArray[vp + 4] =
x;
1116 mIntArray[vp + 5] = ys2;
1117 mIntArray[vp + 6] = 0.0F;
1118 mIntArray[vp + 7] = 0.0F;
1133 const GLuint texture)
1145 mglDeleteBuffers(sz, arr);
1146 for (
size_t f = 0; f < sz; f ++)
1148 if (arr[f] == mVboBinded)
1156 if (mVboBinded != vbo)
1165 mAttributesBinded = 0U;
1171 if (mEboBinded != ebo)
1186 if (mVboBinded != vbo)
1196 mAttributesBinded = mVboBinded;
1198 mglBindVertexBuffer(0, mVboBinded, 0, 4 *
sizeof(GLint));
1202 else if (mAttributesBinded != mVboBinded)
1204 mAttributesBinded = mVboBinded;
1206 mglBindVertexBuffer(0, mVboBinded, 0, 4 *
sizeof(GLint));
1217 mglBindVertexBuffer(0,
mVboBinded, 0, 4 *
sizeof(GLint));
1228 for (
int f = 0; f < 65535; f ++)
1235 if (test[0] != 0 || test[1] != 0 || test[2] != 0 || test[3] != 0)
1238 test[0], test[1], test[2], test[3]);
1244 const int w,
const int h,
1252 const int x,
const int y,
1253 const int w,
const int h,
1263 GL_DEPTH_BUFFER_BIT |
1264 GL_STENCIL_BUFFER_BIT);
1271 if (mGLContext !=
nullptr)
1296 if (vert ==
nullptr)
1298 OpenGLGraphicsVertexes &ogl = vert->
ogl;
1299 const STD_VECTOR<int> &vp = ogl.mVp;
1300 STD_VECTOR<int>::const_iterator ivp;
1301 const STD_VECTOR<int>::const_iterator ivp_end = vp.end();
1302 STD_VECTOR<GLint*> &intTexPool = ogl.mIntTexPool;
1303 STD_VECTOR<GLint*>::const_iterator ft;
1304 const STD_VECTOR<GLint*>::const_iterator ft_end = intTexPool.end();
1305 STD_VECTOR<GLuint> &vbos = ogl.mVbo;
1306 STD_VECTOR<GLuint>::const_iterator ivbo;
1308 const int sz =
CAST_S32(intTexPool.size());
1312 mglGenBuffers(sz, &vbos[0]);
1318 for (ft = intTexPool.begin(), ivp = vp.begin(), ivbo = vbos.begin();
1319 ft != ft_end && ivp != ivp_end;
1320 ++ ft, ++ ivp, ++ ivbo)
1322 bindArrayBuffer(*ivbo);
1331 for (STD_VECTOR<GLint*>::iterator it = intTexPool.begin();
1332 it != intTexPool.end(); ++ it)
1344 #ifdef DEBUG_DRAW_CALLS
1359 #ifdef DEBUG_DRAW_CALLS
1373 #ifdef DEBUG_DRAW_CALLS
1382 #ifdef DEBUG_BIND_TEXTURE
1386 const std::string texture = image->mIdPath;
1387 if (mOldTexture != texture)
1389 if ((!mOldTexture.empty() || !texture.empty())
1390 && mOldTextureId != image->mGLImage)
1392 logger->
log(
"bind: %s (%d) to %s (%d)", mOldTexture.c_str(),
1393 mOldTextureId, texture.c_str(), image->mGLImage);
1395 mOldTextureId = image->mGLImage;
1396 mOldTexture = texture;
virtual void updateScreen()=0
virtual void drawImage(const Image *const image, int dstX, int dstY)=0
virtual void popClipArea()
virtual void drawRescaledPattern(const Image *const image, const int x, const int y, const int w, const int h, const int scaledWidth, const int scaledHeight)=0
virtual void drawTileCollection(const ImageCollection *const vertCol)=0
virtual bool setVideoMode(const int w, const int h, const int scale, const int bpp, const bool fs, const bool hwaccel, const bool resize, const bool noFrame, const bool allowHighDPI)=0
virtual void createGLContext(const bool custom)
virtual void fillRectangle(const Rect &rectangle)=0
virtual void calcTileCollection(ImageCollection *const vertCol, const Image *const image, int x, int y)=0
virtual void drawImageCached(const Image *const image, int srcX, int srcY)=0
virtual void calcPattern(ImageVertexes *const vert, const Image *const image, const int x, const int y, const int w, const int h) const =0
virtual void deleteArrays()
virtual void drawRectangle(const Rect &rectangle)=0
MStack< ClipRect > mClipStack
virtual void calcWindow(ImageCollection *const vertCol, const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
virtual void drawLine(int x1, int y1, int x2, int y2)=0
virtual void calcTileVertexes(ImageVertexes *const vert, const Image *const image, int x, int y) const =0
virtual void drawPattern(const Image *const image, const int x, const int y, const int w, const int h)=0
virtual void initArrays(const int vertCount)
virtual void clearScreen() const
virtual void drawPoint(int x, int y)=0
virtual void drawImageRect(const int x, const int y, const int w, const int h, const ImageRect &imgRect)=0
virtual void copyImage(const Image *const image, int dstX, int dstY)=0
virtual void pushClipArea(const Rect &area)
virtual void drawTileVertexes(const ImageVertexes *const vert)=0
virtual void drawPatternCached(const Image *const image, const int x, const int y, const int w, const int h)=0
virtual void completeCache()=0
virtual void drawNet(const int x1, const int y1, const int x2, const int y2, const int width, const int height)
virtual void drawRescaledImage(const Image *const image, int dstX, int dstY, const int desiredWidth, const int desiredHeight)=0
OpenGLGraphicsVertexes ogl
void log(const char *const log_text,...)
void safeError(const std::string &error_text) __attribute__((noreturn))
void error(const std::string &error_text) __attribute__((noreturn))
GLint mTextureColorUniform
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 createGLContext(const bool custom)
void drawLineArrays(const int size) A_INLINE
void drawTriangleArray(const int size) A_INLINE
void bindAttributes() A_INLINE
GLuint mSimpleColorUniform
void removeArray(const uint32_t id, uint32_t *const arr)
void bindElementBuffer(const GLuint ebo) A_INLINE
void bindArrayBuffer(const GLuint vbo) A_INLINE
void setColor(const Color &color)
void bindArrayBufferAndAttributes(const GLuint vbo) A_INLINE
void drawQuad(const int srcX, const int srcY, const int dstX, const int dstY, const int width, const int height) A_INLINE
void finalize(ImageCollection *const col)
unsigned int getProgramId() const
ShaderProgram * getSimpleProgram()
#define FOR_EACH(type, iter, array)
void calcPatternInline(ImageVertexes *restrict const vert, const Image *restrict const image, const int x, const int y, const int w, const int h) const restrict2 A_INLINE
void drawPatternInline(const Image *restrict const image, const int x, const int y, const int w, const int h) restrict2 A_INLINE
void void drawImageInline(const Image *restrict const image, int dstX, int dstY) restrict2 A_INLINE
void calcTileVertexesInline(ImageVertexes *restrict const vert, const Image *restrict const image, int x, int y) const restrict2 A_INLINE A_NONNULL(2
void calcImageRect(ImageVertexes *restrict const vert, int x, int y, int w, int h, const ImageRect &restrict imgRect) restrict2 A_INLINE
GraphicsManager graphicsManager
std::vector< ImageVertexes * > ImageVertexesVector
ImageVertexesVector::const_iterator ImageCollectionCIter
ImageVertexesVector::iterator ImageCollectionIter
#define mglDrawArrays(...)
#define mglBindTexture(...)
#define mglGetIntegerv(...)
#define isGLNotNull(func)
#define GL_ELEMENT_ARRAY_BUFFER
static void drawQuad(const Image *const image, const int srcX, const int srcY, const int dstX, const int dstY, const int width, const int height) A_INLINE
static void drawRescaledQuad(const Image *const image, const int srcX, const int srcY, const int dstX, const int dstY, const int width, const int height, const int desiredWidth, const int desiredHeight) A_INLINE
#define vertFill2D(var, x1, y1, x2, y2, dstX, dstY, w, h)
void makeCurrentContext(void *const context)
void * createGLContext(SDL_Surface *const window, const int major, const int minor, const int profile)
void enableTexturingAndBlending() restrict2
static GLuint mTextureBinded
void disableTexturingAndBlending() restrict2
static void dumpSettings()
static void bindTexture(const GLenum target, const GLuint texture)
void setColorAlpha(const float alpha) restrict2 A_INLINE
void deleteArraysInternal() restrict2
void drawVertexes(const OpenGLGraphicsVertexes &restrict ogl) restrict2 A_INLINE
void debugBindTexture(const Image *restrict const image) restrict2
unsigned int vertexBufSize
#define FUNC_BLOCK(name, id)
#define BLOCK_START(name)