summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/render/graphics.h9
-rw-r--r--src/render/mobileopenglgraphics.cpp222
-rw-r--r--src/render/mobileopenglgraphics.h16
-rw-r--r--src/render/normalopenglgraphics.cpp294
-rw-r--r--src/render/normalopenglgraphics.h19
-rw-r--r--src/render/nullopenglgraphics.cpp15
-rw-r--r--src/render/nullopenglgraphics.h9
-rw-r--r--src/render/safeopenglgraphics.cpp61
-rw-r--r--src/render/safeopenglgraphics.h9
-rw-r--r--src/render/sdl2graphics.cpp83
-rw-r--r--src/render/sdl2graphics.h9
-rw-r--r--src/render/sdl2softwaregraphics.cpp202
-rw-r--r--src/render/sdl2softwaregraphics.h9
-rw-r--r--src/render/sdlgraphics.cpp202
-rw-r--r--src/render/sdlgraphics.h9
-rw-r--r--src/render/surfacegraphics.cpp38
-rw-r--r--src/render/surfacegraphics.h10
17 files changed, 1214 insertions, 2 deletions
diff --git a/src/render/graphics.h b/src/render/graphics.h
index 2aa850d41..82bf220ab 100644
--- a/src/render/graphics.h
+++ b/src/render/graphics.h
@@ -385,6 +385,15 @@ class Graphics : public gcn::Graphics
const int width, const int height,
const bool useColor) = 0;
+ virtual void drawImageCached(const Image *const image,
+ int srcX, int srcY) = 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;
+
int mWidth;
int mHeight;
diff --git a/src/render/mobileopenglgraphics.cpp b/src/render/mobileopenglgraphics.cpp
index a56510871..df11dae0a 100644
--- a/src/render/mobileopenglgraphics.cpp
+++ b/src/render/mobileopenglgraphics.cpp
@@ -49,9 +49,14 @@ MobileOpenGLGraphics::MobileOpenGLGraphics():
mIntTexArray(nullptr),
mIntVertArray(nullptr),
mShortVertArray(nullptr),
+ mFloatTexArrayCached(nullptr),
+ mShortVertArrayCached(nullptr),
+ mAlphaCached(1.0F),
+ mVpCached(0),
mTexture(false),
mIsByteColor(false),
mByteColor(),
+ mImageCached(0),
mFloatColor(1.0F),
mMaxVertices(500),
mColorAlpha(false),
@@ -71,6 +76,8 @@ MobileOpenGLGraphics::~MobileOpenGLGraphics()
delete [] mIntTexArray;
delete [] mIntVertArray;
delete [] mShortVertArray;
+ delete [] mFloatTexArrayCached;
+ delete [] mShortVertArrayCached;
}
void MobileOpenGLGraphics::initArrays()
@@ -88,6 +95,8 @@ void MobileOpenGLGraphics::initArrays()
mIntTexArray = new GLint[sz];
mIntVertArray = new GLint[sz];
mShortVertArray = new GLshort[sz];
+ mFloatTexArrayCached = new GLfloat[sz];
+ mShortVertArrayCached = new GLshort[sz];
}
bool MobileOpenGLGraphics::setVideoMode(const int w, const int h,
@@ -216,6 +225,208 @@ bool MobileOpenGLGraphics::drawImage2(const Image *const image,
return true;
}
+void MobileOpenGLGraphics::drawImageCached(const Image *const image,
+ int x, int y)
+{
+ if (!image)
+ return;
+
+ if (image->mGLImage != mImageCached)
+ {
+ completeCache();
+ mImageCached = image->mGLImage;
+ mAlphaCached = image->mAlpha;
+ }
+
+ const SDL_Rect &imageRect = image->mBounds;
+ const int srcX = imageRect.x;
+ const int srcY = imageRect.y;
+ const int w = imageRect.w;
+ const int h = imageRect.h;
+
+ if (w == 0 || h == 0)
+ return;
+
+ const float tw = static_cast<float>(image->mTexWidth);
+ const float th = static_cast<float>(image->mTexHeight);
+
+ const unsigned int vLimit = mMaxVertices * 4;
+
+ unsigned int vp = mVpCached;
+
+ // Draw a set of textured rectangles
+// if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
+ {
+ float texX1 = static_cast<float>(srcX) / tw;
+ float texY1 = static_cast<float>(srcY) / th;
+ float texX2 = static_cast<float>(srcX + w) / tw;
+ float texY2 = static_cast<float>(srcY + h) / th;
+
+ mFloatTexArrayCached[vp + 0] = texX1;
+ mFloatTexArrayCached[vp + 1] = texY1;
+
+ mFloatTexArrayCached[vp + 2] = texX2;
+ mFloatTexArrayCached[vp + 3] = texY1;
+
+ mFloatTexArrayCached[vp + 4] = texX2;
+ mFloatTexArrayCached[vp + 5] = texY2;
+
+ mFloatTexArrayCached[vp + 6] = texX1;
+ mFloatTexArrayCached[vp + 7] = texY1;
+
+ mFloatTexArrayCached[vp + 8] = texX1;
+ mFloatTexArrayCached[vp + 9] = texY2;
+
+ mFloatTexArrayCached[vp + 10] = texX2;
+ mFloatTexArrayCached[vp + 11] = texY2;
+
+ mShortVertArray[vp + 0] = x;
+ mShortVertArray[vp + 1] = y;
+
+ mShortVertArray[vp + 2] = x + w;
+ mShortVertArray[vp + 3] = y;
+
+ mShortVertArray[vp + 4] = x + w;
+ mShortVertArray[vp + 5] = y + h;
+
+ mShortVertArray[vp + 6] = x;
+ mShortVertArray[vp + 7] = y;
+
+ mShortVertArray[vp + 8] = x;
+ mShortVertArray[vp + 9] = y + h;
+
+ mShortVertArray[vp + 10] = x + w;
+ mShortVertArray[vp + 11] = y + h;
+
+ vp += 12;
+ if (vp >= vLimit)
+ {
+ completeCache();
+ vp = 0;
+ }
+ else
+ {
+ mVpCached = vp;
+ }
+ }
+}
+
+void MobileOpenGLGraphics::drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h)
+{
+ if (!image)
+ return;
+
+ if (image->mGLImage != mImageCached)
+ {
+ completeCache();
+ mImageCached = image->mGLImage;
+ }
+
+ const SDL_Rect &imageRect = image->mBounds;
+ const int srcX = imageRect.x;
+ const int srcY = imageRect.y;
+ const int iw = imageRect.w;
+ const int ih = imageRect.h;
+
+ if (iw == 0 || ih == 0)
+ return;
+
+ const float tw = static_cast<float>(image->mTexWidth);
+ const float th = static_cast<float>(image->mTexHeight);
+
+ unsigned int vp = mVpCached;
+ const unsigned int vLimit = mMaxVertices * 4;
+ // Draw a set of textured rectangles
+// if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
+// {
+ const float texX1 = static_cast<float>(srcX) / tw;
+ const float texY1 = static_cast<float>(srcY) / th;
+
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const float texY2 = static_cast<float>(srcY + height) / th;
+ const int dstY = y + py;
+ for (int px = 0; px < w; px += iw)
+ {
+ const int width = (px + iw >= w) ? w - px : iw;
+ const int dstX = x + px;
+
+ const float texX2 = static_cast<float>(srcX + width) / tw;
+
+ mFloatTexArrayCached[vp + 0] = texX1; // 1
+ mFloatTexArrayCached[vp + 1] = texY1;
+
+ mFloatTexArrayCached[vp + 2] = texX2; // 2
+ mFloatTexArrayCached[vp + 3] = texY1;
+
+ mFloatTexArrayCached[vp + 4] = texX2; // 3
+ mFloatTexArrayCached[vp + 5] = texY2;
+
+ mFloatTexArrayCached[vp + 6] = texX1; // 1
+ mFloatTexArrayCached[vp + 7] = texY1;
+
+ mFloatTexArrayCached[vp + 8] = texX1; // 4
+ mFloatTexArrayCached[vp + 9] = texY2;
+
+ mFloatTexArrayCached[vp + 10] = texX2; // 3
+ mFloatTexArrayCached[vp + 11] = texY2;
+
+ mShortVertArrayCached[vp + 0] = static_cast<GLshort>(dstX);
+ mShortVertArrayCached[vp + 1] = static_cast<GLshort>(dstY);
+
+ mShortVertArrayCached[vp + 2] = static_cast<GLshort>(
+ dstX + width);
+ mShortVertArrayCached[vp + 3] = static_cast<GLshort>(dstY);
+
+ mShortVertArrayCached[vp + 4] = static_cast<GLshort>(
+ dstX + width);
+ mShortVertArrayCached[vp + 5] = static_cast<GLshort>(
+ dstY + height);
+
+ mShortVertArrayCached[vp + 6] = static_cast<GLshort>(dstX);
+ mShortVertArrayCached[vp + 7] = static_cast<GLshort>(dstY);
+
+ mShortVertArrayCached[vp + 8] = static_cast<GLshort>(dstX);
+ mShortVertArrayCached[vp + 9] = static_cast<GLshort>(
+ dstY + height);
+
+ mShortVertArrayCached[vp + 10] = static_cast<GLshort>(
+ dstX + width);
+ mShortVertArrayCached[vp + 11] = static_cast<GLshort>(
+ dstY + height);
+
+ vp += 12;
+ if (vp >= vLimit)
+ {
+ completeCache();
+ vp = 0;
+ }
+ }
+ }
+// }
+ mVpCached = vp;
+}
+
+void MobileOpenGLGraphics::completeCache()
+{
+ if (!mImageCached)
+ return;
+
+ setColorAlpha(mAlphaCached);
+#ifdef DEBUG_BIND_TEXTURE
+// debugBindTexture(image);
+#endif
+ bindTexture(OpenGLImageHelper::mTextureType, mImageCached);
+ setTexturingAndBlending(true);
+
+ drawTriangleArrayfsCached(mVpCached);
+ mImageCached = 0;
+ mVpCached = 0;
+}
+
bool MobileOpenGLGraphics::drawRescaledImage(const Image *const image,
int srcX, int srcY,
int dstX, int dstY,
@@ -1202,6 +1413,17 @@ inline void MobileOpenGLGraphics::drawTriangleArrayfs(const int size)
glDrawArrays(GL_TRIANGLES, 0, size / 2);
}
+inline void MobileOpenGLGraphics::drawTriangleArrayfsCached(const int size)
+{
+ glVertexPointer(2, GL_SHORT, 0, mShortVertArrayCached);
+ glTexCoordPointer(2, GL_FLOAT, 0, mFloatTexArrayCached);
+
+#ifdef DEBUG_DRAW_CALLS
+ mDrawCalls ++;
+#endif
+ glDrawArrays(GL_TRIANGLES, 0, size / 2);
+}
+
inline void MobileOpenGLGraphics::drawTriangleArrayfs(const GLshort *const
shortVertArray,
const GLfloat *const
diff --git a/src/render/mobileopenglgraphics.h b/src/render/mobileopenglgraphics.h
index 8a2469267..dbee649d0 100644
--- a/src/render/mobileopenglgraphics.h
+++ b/src/render/mobileopenglgraphics.h
@@ -165,6 +165,8 @@ class MobileOpenGLGraphics final : public Graphics
inline void drawTriangleArrayfs(const int size);
+ inline void drawTriangleArrayfsCached(const int size);
+
inline void drawLineArrays(const int size);
inline void drawVertexes(const NormalOpenGLGraphicsVertexes &ogl);
@@ -193,6 +195,15 @@ class MobileOpenGLGraphics final : public Graphics
const int width, const int height,
const bool useColor) override final;
+ void drawImageCached(const Image *const image,
+ int x, int y) override final;
+
+ void drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h) override final;
+
+ void completeCache() override final;
+
#ifdef DEBUG_DRAW_CALLS
unsigned int getDrawCalls() const
{ return mLastDrawCalls; }
@@ -220,10 +231,15 @@ class MobileOpenGLGraphics final : public Graphics
GLint *mIntTexArray;
GLint *mIntVertArray;
GLshort *mShortVertArray;
+ GLfloat *mFloatTexArrayCached;
+ GLshort *mShortVertArrayCached;
+ float mAlphaCached;
+ int mVpCached;
bool mTexture;
bool mIsByteColor;
gcn::Color mByteColor;
+ GLuint mImageCached;
float mFloatColor;
int mMaxVertices;
bool mColorAlpha;
diff --git a/src/render/normalopenglgraphics.cpp b/src/render/normalopenglgraphics.cpp
index 88a9f448f..018ade537 100644
--- a/src/render/normalopenglgraphics.cpp
+++ b/src/render/normalopenglgraphics.cpp
@@ -51,9 +51,15 @@ NormalOpenGLGraphics::NormalOpenGLGraphics():
mFloatTexArray(nullptr),
mIntTexArray(nullptr),
mIntVertArray(nullptr),
+ mFloatTexArrayCached(nullptr),
+ mIntTexArrayCached(nullptr),
+ mIntVertArrayCached(nullptr),
+ mAlphaCached(1.0F),
+ mVpCached(0),
mTexture(false),
mIsByteColor(false),
mByteColor(),
+ mImageCached(0),
mFloatColor(1.0F),
mMaxVertices(500),
mColorAlpha(false),
@@ -72,6 +78,9 @@ NormalOpenGLGraphics::~NormalOpenGLGraphics()
delete [] mFloatTexArray;
delete [] mIntTexArray;
delete [] mIntVertArray;
+ delete [] mFloatTexArrayCached;
+ delete [] mIntTexArrayCached;
+ delete [] mIntVertArrayCached;
}
void NormalOpenGLGraphics::initArrays()
@@ -88,6 +97,9 @@ void NormalOpenGLGraphics::initArrays()
mFloatTexArray = new GLfloat[sz];
mIntTexArray = new GLint[sz];
mIntVertArray = new GLint[sz];
+ mFloatTexArrayCached = new GLfloat[sz];
+ mIntTexArrayCached = new GLint[sz];
+ mIntVertArrayCached = new GLint[sz];
}
bool NormalOpenGLGraphics::setVideoMode(const int w, const int h,
@@ -263,6 +275,266 @@ bool NormalOpenGLGraphics::drawImage2(const Image *const image,
return true;
}
+void NormalOpenGLGraphics::drawImageCached(const Image *const image,
+ int x, int y)
+{
+ if (!image)
+ return;
+
+ if (image->mGLImage != mImageCached)
+ {
+ completeCache();
+ mImageCached = image->mGLImage;
+ mAlphaCached = image->mAlpha;
+ }
+
+ const SDL_Rect &imageRect = image->mBounds;
+ const int w = imageRect.w;
+ const int h = imageRect.h;
+
+ if (w == 0 || h == 0)
+ return;
+
+ const int srcX = imageRect.x;
+ const int srcY = imageRect.y;
+
+ const float tw = static_cast<float>(image->mTexWidth);
+ const float th = static_cast<float>(image->mTexHeight);
+
+ const unsigned int vLimit = mMaxVertices * 4;
+
+ unsigned int vp = mVpCached;
+
+ // Draw a set of textured rectangles
+ if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
+ {
+ const float texX1 = static_cast<float>(srcX) / tw;
+ const float texY1 = static_cast<float>(srcY) / th;
+
+ const float texX2 = static_cast<float>(srcX + w) / tw;
+ const float texY2 = static_cast<float>(srcY + h) / th;
+
+ mFloatTexArrayCached[vp + 0] = texX1;
+ mFloatTexArrayCached[vp + 1] = texY1;
+
+ mFloatTexArrayCached[vp + 2] = texX2;
+ mFloatTexArrayCached[vp + 3] = texY1;
+
+ mFloatTexArrayCached[vp + 4] = texX2;
+ mFloatTexArrayCached[vp + 5] = texY2;
+
+ mFloatTexArrayCached[vp + 6] = texX1;
+ mFloatTexArrayCached[vp + 7] = texY2;
+
+ mIntVertArrayCached[vp + 0] = x;
+ mIntVertArrayCached[vp + 1] = y;
+
+ mIntVertArrayCached[vp + 2] = x + w;
+ mIntVertArrayCached[vp + 3] = y;
+
+ mIntVertArrayCached[vp + 4] = x + w;
+ mIntVertArrayCached[vp + 5] = y + h;
+
+ mIntVertArrayCached[vp + 6] = x;
+ mIntVertArrayCached[vp + 7] = y + h;
+
+ vp += 8;
+ if (vp >= vLimit)
+ {
+ completeCache();
+ vp = 0;
+ }
+ else
+ {
+ mVpCached = vp;
+ }
+ }
+ else
+ {
+ mIntTexArrayCached[vp + 0] = srcX;
+ mIntTexArrayCached[vp + 1] = srcY;
+
+ mIntTexArrayCached[vp + 2] = srcX + w;
+ mIntTexArrayCached[vp + 3] = srcY;
+
+ mIntTexArrayCached[vp + 4] = srcX + w;
+ mIntTexArrayCached[vp + 5] = srcY + h;
+
+ mIntTexArrayCached[vp + 6] = srcX;
+ mIntTexArrayCached[vp + 7] = srcY + h;
+
+ mIntVertArrayCached[vp + 0] = x;
+ mIntVertArrayCached[vp + 1] = y;
+
+ mIntVertArrayCached[vp + 2] = x + w;
+ mIntVertArrayCached[vp + 3] = y;
+
+ mIntVertArrayCached[vp + 4] = x + w;
+ mIntVertArrayCached[vp + 5] = y + h;
+
+ mIntVertArrayCached[vp + 6] = x;
+ mIntVertArrayCached[vp + 7] = y + h;
+
+ vp += 8;
+ if (vp >= vLimit)
+ {
+ completeCache();
+ vp = 0;
+ }
+ else
+ {
+ mVpCached = vp;
+ }
+ }
+}
+
+void NormalOpenGLGraphics::drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h)
+{
+ FUNC_BLOCK("Graphics::drawPatternCached", 1)
+ if (!image)
+ return;
+
+ if (image->mGLImage != mImageCached)
+ {
+ completeCache();
+ mImageCached = image->mGLImage;
+ }
+
+ const SDL_Rect &imageRect = image->mBounds;
+ const int srcX = imageRect.x;
+ const int srcY = imageRect.y;
+ const int iw = imageRect.w;
+ const int ih = imageRect.h;
+
+ if (iw == 0 || ih == 0)
+ return;
+
+ const float tw = static_cast<float>(image->mTexWidth);
+ const float th = static_cast<float>(image->mTexHeight);
+
+ unsigned int vp = mVpCached;
+ const unsigned int vLimit = mMaxVertices * 4;
+ // Draw a set of textured rectangles
+ if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
+ {
+ const float texX1 = static_cast<float>(srcX) / tw;
+ const float texY1 = static_cast<float>(srcY) / th;
+
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const int dstY = y + py;
+ const float texY2 = static_cast<float>(srcY + height) / th;
+ for (int px = 0; px < w; px += iw)
+ {
+ const int width = (px + iw >= w) ? w - px : iw;
+ const int dstX = x + px;
+
+ const float texX2 = static_cast<float>(srcX + width) / tw;
+
+ mFloatTexArrayCached[vp + 0] = texX1;
+ mFloatTexArrayCached[vp + 1] = texY1;
+
+ mFloatTexArrayCached[vp + 2] = texX2;
+ mFloatTexArrayCached[vp + 3] = texY1;
+
+ mFloatTexArrayCached[vp + 4] = texX2;
+ mFloatTexArrayCached[vp + 5] = texY2;
+
+ mFloatTexArrayCached[vp + 6] = texX1;
+ mFloatTexArrayCached[vp + 7] = texY2;
+
+ mIntVertArrayCached[vp + 0] = dstX;
+ mIntVertArrayCached[vp + 1] = dstY;
+
+ mIntVertArrayCached[vp + 2] = dstX + width;
+ mIntVertArrayCached[vp + 3] = dstY;
+
+ mIntVertArrayCached[vp + 4] = dstX + width;
+ mIntVertArrayCached[vp + 5] = dstY + height;
+
+ mIntVertArrayCached[vp + 6] = dstX;
+ mIntVertArrayCached[vp + 7] = dstY + height;
+
+ vp += 8;
+ if (vp >= vLimit)
+ {
+ completeCache();
+ vp = 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const int dstY = y + py;
+ for (int px = 0; px < w; px += iw)
+ {
+ const int width = (px + iw >= w) ? w - px : iw;
+ const int dstX = x + px;
+
+ mIntTexArrayCached[vp + 0] = srcX;
+ mIntTexArrayCached[vp + 1] = srcY;
+
+ mIntTexArrayCached[vp + 2] = srcX + width;
+ mIntTexArrayCached[vp + 3] = srcY;
+
+ mIntTexArrayCached[vp + 4] = srcX + width;
+ mIntTexArrayCached[vp + 5] = srcY + height;
+
+ mIntTexArrayCached[vp + 6] = srcX;
+ mIntTexArrayCached[vp + 7] = srcY + height;
+
+ mIntVertArrayCached[vp + 0] = dstX;
+ mIntVertArrayCached[vp + 1] = dstY;
+
+ mIntVertArrayCached[vp + 2] = dstX + width;
+ mIntVertArrayCached[vp + 3] = dstY;
+
+ mIntVertArrayCached[vp + 4] = dstX + width;
+ mIntVertArrayCached[vp + 5] = dstY + height;
+
+ mIntVertArrayCached[vp + 6] = dstX;
+ mIntVertArrayCached[vp + 7] = dstY + height;
+
+ vp += 8;
+ if (vp >= vLimit)
+ {
+ completeCache();
+ vp = 0;
+ }
+ }
+ }
+ }
+ mVpCached = vp;
+}
+
+void NormalOpenGLGraphics::completeCache()
+{
+ if (!mImageCached)
+ return;
+
+ setColorAlpha(mAlphaCached);
+#ifdef DEBUG_BIND_TEXTURE
+// debugBindTexture(image);
+#endif
+ bindTexture(OpenGLImageHelper::mTextureType, mImageCached);
+ setTexturingAndBlending(true);
+
+ if (OpenGLImageHelper::mTextureType == GL_TEXTURE_2D)
+ drawQuadArrayfiCached(mVpCached);
+ else
+ drawQuadArrayiiCached(mVpCached);
+
+ mImageCached = 0;
+ mVpCached = 0;
+}
+
bool NormalOpenGLGraphics::drawRescaledImage(const Image *const image,
int srcX, int srcY,
int dstX, int dstY,
@@ -1391,6 +1663,17 @@ inline void NormalOpenGLGraphics::drawQuadArrayfi(const int size)
glDrawArrays(GL_QUADS, 0, size / 2);
}
+inline void NormalOpenGLGraphics::drawQuadArrayfiCached(const int size)
+{
+ glVertexPointer(2, GL_INT, 0, mIntVertArrayCached);
+ glTexCoordPointer(2, GL_FLOAT, 0, mFloatTexArrayCached);
+
+#ifdef DEBUG_DRAW_CALLS
+ mDrawCalls ++;
+#endif
+ glDrawArrays(GL_QUADS, 0, size / 2);
+}
+
inline void NormalOpenGLGraphics::drawQuadArrayfi(const GLint *const
intVertArray,
const GLfloat *const
@@ -1417,6 +1700,17 @@ inline void NormalOpenGLGraphics::drawQuadArrayii(const int size)
glDrawArrays(GL_QUADS, 0, size / 2);
}
+inline void NormalOpenGLGraphics::drawQuadArrayiiCached(const int size)
+{
+ glVertexPointer(2, GL_INT, 0, mIntVertArrayCached);
+ glTexCoordPointer(2, GL_INT, 0, mIntTexArrayCached);
+
+#ifdef DEBUG_DRAW_CALLS
+ mDrawCalls ++;
+#endif
+ glDrawArrays(GL_QUADS, 0, size / 2);
+}
+
inline void NormalOpenGLGraphics::drawQuadArrayii(const GLint *const
intVertArray,
const GLint *const
diff --git a/src/render/normalopenglgraphics.h b/src/render/normalopenglgraphics.h
index a62a97df7..73457ef0d 100644
--- a/src/render/normalopenglgraphics.h
+++ b/src/render/normalopenglgraphics.h
@@ -160,12 +160,16 @@ class NormalOpenGLGraphics final : public Graphics
inline void drawQuadArrayfi(const int size);
+ inline void drawQuadArrayfiCached(const int size);
+
inline void drawQuadArrayfi(const GLint *const intVertArray,
const GLfloat *const floatTexArray,
const int size);
inline void drawQuadArrayii(const int size);
+ inline void drawQuadArrayiiCached(const int size);
+
inline void drawQuadArrayii(const GLint *const intVertArray,
const GLint *const intTexArray,
const int size);
@@ -200,6 +204,15 @@ class NormalOpenGLGraphics final : public Graphics
const int width, const int height,
const bool useColor) override final;
+ void drawImageCached(const Image *const image,
+ int x, int y) override final;
+
+ void drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h) override final;
+
+ void completeCache() override final;
+
#ifdef DEBUG_DRAW_CALLS
unsigned int getDrawCalls() const
{ return mLastDrawCalls; }
@@ -229,10 +242,16 @@ class NormalOpenGLGraphics final : public Graphics
GLfloat *mFloatTexArray;
GLint *mIntTexArray;
GLint *mIntVertArray;
+ GLfloat *mFloatTexArrayCached;
+ GLint *mIntTexArrayCached;
+ GLint *mIntVertArrayCached;
+ float mAlphaCached;
+ int mVpCached;
bool mTexture;
bool mIsByteColor;
gcn::Color mByteColor;
+ GLuint mImageCached;
float mFloatColor;
int mMaxVertices;
bool mColorAlpha;
diff --git a/src/render/nullopenglgraphics.cpp b/src/render/nullopenglgraphics.cpp
index 0bee724ee..ab1291233 100644
--- a/src/render/nullopenglgraphics.cpp
+++ b/src/render/nullopenglgraphics.cpp
@@ -166,6 +166,21 @@ bool NullOpenGLGraphics::drawImage2(const Image *const image,
return true;
}
+void NullOpenGLGraphics::drawImageCached(const Image *const image,
+ int x, int y)
+{
+}
+
+void NullOpenGLGraphics::drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h)
+{
+}
+
+void NullOpenGLGraphics::completeCache()
+{
+}
+
bool NullOpenGLGraphics::drawRescaledImage(const Image *const image,
int srcX, int srcY,
int dstX, int dstY,
diff --git a/src/render/nullopenglgraphics.h b/src/render/nullopenglgraphics.h
index bf424bb8d..7b15cfbf5 100644
--- a/src/render/nullopenglgraphics.h
+++ b/src/render/nullopenglgraphics.h
@@ -200,6 +200,15 @@ class NullOpenGLGraphics final : public Graphics
const int width, const int height,
const bool useColor) override final;
+ void drawImageCached(const Image *const image,
+ int x, int y) override final;
+
+ void drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h) override final;
+
+ void completeCache() override final;
+
#ifdef DEBUG_DRAW_CALLS
unsigned int getDrawCalls() const
{ return mLastDrawCalls; }
diff --git a/src/render/safeopenglgraphics.cpp b/src/render/safeopenglgraphics.cpp
index e1540dbab..1170f0300 100644
--- a/src/render/safeopenglgraphics.cpp
+++ b/src/render/safeopenglgraphics.cpp
@@ -165,6 +165,67 @@ bool SafeOpenGLGraphics::drawImage2(const Image *const image,
return true;
}
+void SafeOpenGLGraphics::drawImageCached(const Image *const image,
+ int x, int y)
+{
+ FUNC_BLOCK("Graphics::drawImageCached", 1)
+ if (!image)
+ return;
+
+ setColorAlpha(image->mAlpha);
+ bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage);
+ setTexturingAndBlending(true);
+
+ const SDL_Rect &bounds = image->mBounds;
+ // Draw a textured quad.
+ glBegin(GL_QUADS);
+ drawQuad(image, bounds.x, bounds.y, x, y, bounds.w, bounds.h);
+ glEnd();
+}
+
+void SafeOpenGLGraphics::drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h)
+{
+ FUNC_BLOCK("Graphics::drawPatternCached", 1)
+ if (!image)
+ return;
+
+ const SDL_Rect &imageRect = image->mBounds;
+ const int iw = imageRect.w;
+ const int ih = imageRect.h;
+ if (iw == 0 || ih == 0)
+ return;
+
+ const int srcX = imageRect.x;
+ const int srcY = imageRect.y;
+
+ setColorAlpha(image->mAlpha);
+ bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage);
+ setTexturingAndBlending(true);
+
+ // Draw a set of textured rectangles
+ glBegin(GL_QUADS);
+
+ for (int py = 0; py < h; py += ih)
+ {
+ const int height = (py + ih >= h) ? h - py : ih;
+ const int dstY = y + py;
+ for (int px = 0; px < w; px += iw)
+ {
+ int width = (px + iw >= w) ? w - px : iw;
+ int dstX = x + px;
+ drawQuad(image, srcX, srcY, dstX, dstY, width, height);
+ }
+ }
+
+ glEnd();
+}
+
+void SafeOpenGLGraphics::completeCache()
+{
+}
+
bool SafeOpenGLGraphics::drawRescaledImage(const Image *const image, int srcX,
int srcY, int dstX, int dstY,
const int width, const int height,
diff --git a/src/render/safeopenglgraphics.h b/src/render/safeopenglgraphics.h
index 60a726845..dac61cb47 100644
--- a/src/render/safeopenglgraphics.h
+++ b/src/render/safeopenglgraphics.h
@@ -163,6 +163,15 @@ class SafeOpenGLGraphics final : public Graphics
const int width, const int height,
const bool useColor) override final;
+ void drawImageCached(const Image *const image,
+ int x, int y) override final;
+
+ void drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h) override final;
+
+ void completeCache() override final;
+
static void bindTexture(const GLenum target, const GLuint texture);
static GLuint mLastImage;
diff --git a/src/render/sdl2graphics.cpp b/src/render/sdl2graphics.cpp
index 6426506ee..00452d9c6 100644
--- a/src/render/sdl2graphics.cpp
+++ b/src/render/sdl2graphics.cpp
@@ -149,6 +149,89 @@ bool SDLGraphics::drawImage2(const Image *const image, int srcX, int srcY,
return !MSDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect);
}
+void SDLGraphics::drawImageCached(const Image *const image,
+ int x, int y)
+{
+ FUNC_BLOCK("Graphics::drawImageCached", 1)
+ // Check that preconditions for blitting are met.
+ if (!mWindow || !image || !image->mTexture)
+ return;
+
+ const gcn::ClipRectangle &top = mClipStack.top();
+ if (!top.width || !top.height)
+ return;
+
+ const SDL_Rect &bounds = image->mBounds;
+ const SDL_Rect srcRect =
+ {
+ static_cast<int32_t>(bounds.x),
+ static_cast<int32_t>(bounds.y),
+ static_cast<int32_t>(bounds.w),
+ static_cast<int32_t>(bounds.h)
+ };
+
+ const SDL_Rect dstRect =
+ {
+ static_cast<int32_t>(x + top.xOffset),
+ static_cast<int32_t>(y + top.yOffset),
+ static_cast<int32_t>(bounds.w),
+ static_cast<int32_t>(bounds.h)
+ };
+
+ MSDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect);
+}
+
+void SDLGraphics::drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h)
+{
+ FUNC_BLOCK("Graphics::drawPatternCached", 1)
+ // Check that preconditions for blitting are met.
+ if (!mWindow || !image)
+ return;
+ if (!image->mTexture)
+ return;
+
+ const gcn::ClipRectangle &top = mClipStack.top();
+ if (!top.width || !top.height)
+ return;
+
+ const SDL_Rect &bounds = image->mBounds;
+ const int iw = bounds.w;
+ const int ih = bounds.h;
+ if (iw == 0 || ih == 0)
+ return;
+
+ const int xOffset = top.xOffset + x;
+ const int yOffset = top.yOffset + y;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ srcRect.x = static_cast<int32_t>(bounds.x);
+ srcRect.y = static_cast<int32_t>(bounds.y);
+ for (int py = 0; py < h; py += ih)
+ {
+ const int dh = (py + ih >= h) ? h - py : ih;
+ dstRect.y = static_cast<int32_t>(py + yOffset);
+ srcRect.h = static_cast<int32_t>(dh);
+ dstRect.h = static_cast<int32_t>(dh);
+
+ for (int px = 0; px < w; px += iw)
+ {
+ const int dw = (px + iw >= w) ? w - px : iw;
+ dstRect.x = static_cast<int32_t>(px + xOffset);
+ srcRect.w = static_cast<int32_t>(dw);
+ dstRect.w = static_cast<int32_t>(dw);
+
+ MSDL_RenderCopy(mRenderer, image->mTexture, &srcRect, &dstRect);
+ }
+ }
+}
+
+void SDLGraphics::completeCache()
+{
+}
+
void SDLGraphics::drawPattern(const Image *const image,
const int x, const int y,
const int w, const int h)
diff --git a/src/render/sdl2graphics.h b/src/render/sdl2graphics.h
index cbb2ff901..f1960d358 100644
--- a/src/render/sdl2graphics.h
+++ b/src/render/sdl2graphics.h
@@ -142,6 +142,15 @@ class SDLGraphics final : public Graphics
const int width, const int height,
const bool useColor) override final;
+ void drawImageCached(const Image *const image,
+ int x, int y) override final;
+
+ void drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h) override final;
+
+ void completeCache() override final;
+
protected:
uint32_t mRendererFlags;
uint32_t mOldPixel;
diff --git a/src/render/sdl2softwaregraphics.cpp b/src/render/sdl2softwaregraphics.cpp
index e4e3d822f..b0d76bd57 100644
--- a/src/render/sdl2softwaregraphics.cpp
+++ b/src/render/sdl2softwaregraphics.cpp
@@ -125,7 +125,6 @@ bool SDL2SoftwareGraphics::drawImage2(const Image *const image,
const gcn::ClipRectangle &top = mClipStack.top();
const SDL_Rect &bounds = image->mBounds;
-
SDL_Surface *const src = image->mSDLSurface;
srcX += bounds.x;
@@ -203,6 +202,207 @@ bool SDL2SoftwareGraphics::drawImage2(const Image *const image,
return 0;
}
+void SDL2SoftwareGraphics::drawImageCached(const Image *const image,
+ int x, int y)
+{
+ FUNC_BLOCK("Graphics::drawImageCached", 1)
+ // Check that preconditions for blitting are met.
+ if (!mSurface || !image || !image->mSDLSurface)
+ return;
+
+ const gcn::ClipRectangle &top = mClipStack.top();
+ const SDL_Rect &bounds = image->mBounds;
+
+ SDL_Surface *const src = image->mSDLSurface;
+
+ int srcX = bounds.x;
+ const int srcY = bounds.y;
+ x += top.xOffset;
+ y += top.yOffset;
+
+ int w = bounds.w;
+ int h = bounds.h;
+ if (srcX < 0)
+ {
+ w += srcX;
+ x -= static_cast<int16_t>(srcX);
+ srcX = 0;
+ }
+ const int maxw = src->w - srcX;
+ if (maxw < w)
+ w = maxw;
+
+ if (srcY < 0)
+ {
+ h += srcY;
+ y -= static_cast<int16_t>(srcY);
+ srcY = 0;
+ }
+ const int maxh = src->h - srcY;
+ if (maxh < h)
+ h = maxh;
+
+ const SDL_Rect *const clip = &mSurface->clip_rect;
+ const int clipX = clip->x;
+ const int clipY = clip->y;
+ int dx = clipX - x;
+ if (dx > 0)
+ {
+ w -= dx;
+ x += static_cast<int16_t>(dx);
+ srcX += dx;
+ }
+ dx = x + w - clipX - clip->w;
+ if (dx > 0)
+ w -= dx;
+
+ int dy = clipY - y;
+ if (dy > 0)
+ {
+ h -= dy;
+ y += static_cast<int16_t>(dy);
+ srcY += dy;
+ }
+ dy = y + h - clipY - clip->h;
+ if (dy > 0)
+ h -= dy;
+
+ if (w > 0 && h > 0)
+ {
+ SDL_Rect srcRect =
+ {
+ static_cast<int16_t>(srcX),
+ static_cast<int16_t>(srcY),
+ static_cast<uint16_t>(w),
+ static_cast<uint16_t>(h)
+ };
+
+ SDL_Rect dstRect =
+ {
+ static_cast<int16_t>(x),
+ static_cast<int16_t>(y),
+ static_cast<uint16_t>(w),
+ static_cast<uint16_t>(h)
+ };
+
+ SDL_LowerBlit(src, &srcRect, mSurface, &dstRect);
+ }
+}
+
+void SDL2SoftwareGraphics::drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h)
+{
+ FUNC_BLOCK("Graphics::drawPatternCached", 1)
+ // Check that preconditions for blitting are met.
+ if (!mSurface || !image)
+ return;
+ if (!image->mSDLSurface)
+ return;
+
+ const SDL_Rect &bounds = image->mBounds;
+ const int iw = bounds.w;
+ const int ih = bounds.h;
+ if (iw == 0 || ih == 0)
+ return;
+
+ const gcn::ClipRectangle &top = mClipStack.top();
+ const int xOffset = top.xOffset + x;
+ const int yOffset = top.yOffset + y;
+ const int srcX = bounds.x;
+ const int srcY = bounds.y;
+ SDL_Surface *const src = image->mSDLSurface;
+ const SDL_Rect *const clip = &mSurface->clip_rect;
+ const int clipX = clip->x;
+ const int clipY = clip->y;
+
+ for (int py = 0; py < h; py += ih)
+ {
+ const int dh = (py + ih >= h) ? h - py : ih;
+ int dstY = py + yOffset;
+ int y2 = srcY;
+ int h2 = dh;
+ if (y2 < 0)
+ {
+ h2 += y2;
+ dstY -= static_cast<int16_t>(y2);
+ y2 = 0;
+ }
+ const int maxh = src->h - y2;
+ if (maxh < h2)
+ h2 = maxh;
+
+ int dy = clipY - dstY;
+ if (dy > 0)
+ {
+ h2 -= dy;
+ dstY += static_cast<int16_t>(dy);
+ y2 += dy;
+ }
+ dy = dstY + h2 - clipY - clip->h;
+ if (dy > 0)
+ h2 -= dy;
+
+ if (h2 > 0)
+ {
+ for (int px = 0; px < w; px += iw)
+ {
+ const int dw = (px + iw >= w) ? w - px : iw;
+ int dstX = px + xOffset;
+ int x2 = srcX;
+ int w2 = dw;
+ if (x2 < 0)
+ {
+ w2 += x2;
+ dstX -= static_cast<int16_t>(x2);
+ x2 = 0;
+ }
+ const int maxw = src->w - x2;
+ if (maxw < w2)
+ w2 = maxw;
+
+ int dx = clipX - dstX;
+ if (dx > 0)
+ {
+ w2 -= dx;
+ dstX += static_cast<int16_t>(dx);
+ x2 += dx;
+ }
+ dx = dstX + w2 - clipX - clip->w;
+ if (dx > 0)
+ w2 -= dx;
+
+ if (w2 > 0)
+ {
+ SDL_Rect srcRect =
+ {
+ static_cast<int16_t>(x2),
+ static_cast<int16_t>(y2),
+ static_cast<uint16_t>(w2),
+ static_cast<uint16_t>(h2)
+ };
+
+ SDL_Rect dstRect =
+ {
+ static_cast<int16_t>(dstX),
+ static_cast<int16_t>(dstY),
+ static_cast<uint16_t>(w2),
+ static_cast<uint16_t>(h2)
+ };
+
+ SDL_LowerBlit(src, &srcRect, mSurface, &dstRect);
+ }
+
+// SDL_BlitSurface(image->mSDLSurface, &srcRect, mWindow, &dstRect);
+ }
+ }
+ }
+}
+
+void SDL2SoftwareGraphics::completeCache()
+{
+}
+
void SDL2SoftwareGraphics::drawPattern(const Image *const image,
const int x, const int y,
const int w, const int h)
diff --git a/src/render/sdl2softwaregraphics.h b/src/render/sdl2softwaregraphics.h
index 609ef6cf5..ab9fb7ce4 100644
--- a/src/render/sdl2softwaregraphics.h
+++ b/src/render/sdl2softwaregraphics.h
@@ -145,6 +145,15 @@ class SDL2SoftwareGraphics final : public Graphics
const int width, const int height,
const bool useColor) override final;
+ void drawImageCached(const Image *const image,
+ int x, int y) override final;
+
+ void drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h) override final;
+
+ void completeCache() override final;
+
protected:
int SDL_FakeUpperBlit(const SDL_Surface *const src,
SDL_Rect *const srcrect,
diff --git a/src/render/sdlgraphics.cpp b/src/render/sdlgraphics.cpp
index f62d9dd56..c46b65000 100644
--- a/src/render/sdlgraphics.cpp
+++ b/src/render/sdlgraphics.cpp
@@ -116,7 +116,6 @@ bool SDLGraphics::drawImage2(const Image *const image, int srcX, int srcY,
const gcn::ClipRectangle &top = mClipStack.top();
const SDL_Rect &bounds = image->mBounds;
-
SDL_Surface *const src = image->mSDLSurface;
srcX += bounds.x;
@@ -194,6 +193,207 @@ bool SDLGraphics::drawImage2(const Image *const image, int srcX, int srcY,
return 0;
}
+void SDLGraphics::drawImageCached(const Image *const image,
+ int x, int y)
+{
+ FUNC_BLOCK("Graphics::drawImageCached", 1)
+ // Check that preconditions for blitting are met.
+ if (!mWindow || !image || !image->mSDLSurface)
+ return;
+
+ const gcn::ClipRectangle &top = mClipStack.top();
+ const SDL_Rect &bounds = image->mBounds;
+
+ SDL_Surface *const src = image->mSDLSurface;
+
+ int srcX = bounds.x;
+ int srcY = bounds.y;
+ x += top.xOffset;
+ y += top.yOffset;
+
+ int w = bounds.w;
+ int h = bounds.h;
+ if (srcX < 0)
+ {
+ w += srcX;
+ x -= static_cast<int16_t>(srcX);
+ srcX = 0;
+ }
+ const int maxw = src->w - srcX;
+ if (maxw < w)
+ w = maxw;
+
+ if (srcY < 0)
+ {
+ h += srcY;
+ y -= static_cast<int16_t>(srcY);
+ srcY = 0;
+ }
+ const int maxh = src->h - srcY;
+ if (maxh < h)
+ h = maxh;
+
+ const SDL_Rect *const clip = &mWindow->clip_rect;
+ const int clipX = clip->x;
+ const int clipY = clip->y;
+ int dx = clipX - x;
+ if (dx > 0)
+ {
+ w -= dx;
+ x += static_cast<int16_t>(dx);
+ srcX += dx;
+ }
+ dx = x + w - clipX - clip->w;
+ if (dx > 0)
+ w -= dx;
+
+ int dy = clipY - y;
+ if (dy > 0)
+ {
+ h -= dy;
+ y += static_cast<int16_t>(dy);
+ srcY += dy;
+ }
+ dy = y + h - clipY - clip->h;
+ if (dy > 0)
+ h -= dy;
+
+ if (w > 0 && h > 0)
+ {
+ SDL_Rect srcRect =
+ {
+ static_cast<int16_t>(srcX),
+ static_cast<int16_t>(srcY),
+ static_cast<uint16_t>(w),
+ static_cast<uint16_t>(h)
+ };
+
+ SDL_Rect dstRect =
+ {
+ static_cast<int16_t>(x),
+ static_cast<int16_t>(y),
+ static_cast<uint16_t>(w),
+ static_cast<uint16_t>(h)
+ };
+
+ SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
+ }
+}
+
+void SDLGraphics::drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h)
+{
+ FUNC_BLOCK("Graphics::drawPatternCached", 1)
+ // Check that preconditions for blitting are met.
+ if (!mWindow || !image)
+ return;
+ if (!image->mSDLSurface)
+ return;
+
+ const SDL_Rect &bounds = image->mBounds;
+ const int iw = bounds.w;
+ const int ih = bounds.h;
+ if (iw == 0 || ih == 0)
+ return;
+
+ const gcn::ClipRectangle &top = mClipStack.top();
+ const int xOffset = top.xOffset + x;
+ const int yOffset = top.yOffset + y;
+ const int srcX = bounds.x;
+ const int srcY = bounds.y;
+ SDL_Surface *const src = image->mSDLSurface;
+ const SDL_Rect *const clip = &mWindow->clip_rect;
+ const int clipX = clip->x;
+ const int clipY = clip->y;
+
+ for (int py = 0; py < h; py += ih)
+ {
+ const int dh = (py + ih >= h) ? h - py : ih;
+ int dstY = py + yOffset;
+ int y2 = srcY;
+ int h2 = dh;
+ if (y2 < 0)
+ {
+ h2 += y2;
+ dstY -= static_cast<int16_t>(y2);
+ y2 = 0;
+ }
+ const int maxh = src->h - y2;
+ if (maxh < h2)
+ h2 = maxh;
+
+ int dy = clipY - dstY;
+ if (dy > 0)
+ {
+ h2 -= dy;
+ dstY += static_cast<int16_t>(dy);
+ y2 += dy;
+ }
+ dy = dstY + h2 - clipY - clip->h;
+ if (dy > 0)
+ h2 -= dy;
+
+ if (h2 > 0)
+ {
+ for (int px = 0; px < w; px += iw)
+ {
+ const int dw = (px + iw >= w) ? w - px : iw;
+ int dstX = px + xOffset;
+ int x2 = srcX;
+ int w2 = dw;
+ if (x2 < 0)
+ {
+ w2 += x2;
+ dstX -= static_cast<int16_t>(x2);
+ x2 = 0;
+ }
+ const int maxw = src->w - x2;
+ if (maxw < w2)
+ w2 = maxw;
+
+ int dx = clipX - dstX;
+ if (dx > 0)
+ {
+ w2 -= dx;
+ dstX += static_cast<int16_t>(dx);
+ x2 += dx;
+ }
+ dx = dstX + w2 - clipX - clip->w;
+ if (dx > 0)
+ w2 -= dx;
+
+ if (w2 > 0)
+ {
+ SDL_Rect srcRect =
+ {
+ static_cast<int16_t>(x2),
+ static_cast<int16_t>(y2),
+ static_cast<uint16_t>(w2),
+ static_cast<uint16_t>(h2)
+ };
+
+ SDL_Rect dstRect =
+ {
+ static_cast<int16_t>(dstX),
+ static_cast<int16_t>(dstY),
+ static_cast<uint16_t>(w2),
+ static_cast<uint16_t>(h2)
+ };
+
+ SDL_LowerBlit(src, &srcRect, mWindow, &dstRect);
+ }
+
+// SDL_BlitSurface(image->mSDLSurface, &srcRect, mWindow, &dstRect);
+ }
+ }
+ }
+}
+
+void SDLGraphics::completeCache()
+{
+}
+
void SDLGraphics::drawPattern(const Image *const image,
const int x, const int y,
const int w, const int h)
diff --git a/src/render/sdlgraphics.h b/src/render/sdlgraphics.h
index b88a47dc4..aa7a250f8 100644
--- a/src/render/sdlgraphics.h
+++ b/src/render/sdlgraphics.h
@@ -139,6 +139,15 @@ class SDLGraphics final : public Graphics
const int width, const int height,
const bool useColor) override final;
+ void drawImageCached(const Image *const image,
+ int x, int y) override final;
+
+ void drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h) override final;
+
+ void completeCache() override final;
+
protected:
int SDL_FakeUpperBlit(const SDL_Surface *const src,
SDL_Rect *const srcrect,
diff --git a/src/render/surfacegraphics.cpp b/src/render/surfacegraphics.cpp
index 879d44f60..db2722164 100644
--- a/src/render/surfacegraphics.cpp
+++ b/src/render/surfacegraphics.cpp
@@ -80,3 +80,41 @@ bool SurfaceGraphics::drawImage2(const Image *const image, int srcX, int srcY,
}
#endif
}
+
+void SurfaceGraphics::drawImageCached(const Image *const image,
+ int x, int y)
+{
+ FUNC_BLOCK("Graphics::drawImageCached", 1)
+ // Check that preconditions for blitting are met.
+ if (!mTarget || !image || !image->mSDLSurface)
+ return;
+
+ const SDL_Rect &rect = image->mBounds;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ dstRect.x = static_cast<int16_t>(x);
+ dstRect.y = static_cast<int16_t>(y);
+ srcRect.x = static_cast<int16_t>(rect.x);
+ srcRect.y = static_cast<int16_t>(rect.y);
+ srcRect.w = static_cast<uint16_t>(rect.w);
+ srcRect.h = static_cast<uint16_t>(rect.h);
+
+#ifdef USE_SDL2
+ SDL_BlitSurface(image->mSDLSurface, &srcRect, mTarget, &dstRect);
+#else
+ if (mBlitMode == BLIT_NORMAL)
+ {
+ SDL_BlitSurface(image->mSDLSurface, &srcRect, mTarget, &dstRect);
+ }
+ else
+ {
+ SurfaceImageHelper::combineSurface(image->mSDLSurface, &srcRect,
+ mTarget, &dstRect);
+ }
+#endif
+}
+
+void SurfaceGraphics::completeCache()
+{
+}
diff --git a/src/render/surfacegraphics.h b/src/render/surfacegraphics.h
index b33fa0d63..6a2a7f3cb 100644
--- a/src/render/surfacegraphics.h
+++ b/src/render/surfacegraphics.h
@@ -188,6 +188,16 @@ class SurfaceGraphics final : public Graphics
const int width, const int height,
const bool useColor) override final;
+ void drawImageCached(const Image *const image,
+ int x, int y) override final;
+
+ void drawPatternCached(const Image *const image,
+ const int x, const int y,
+ const int w, const int h) override final
+ { }
+
+ void completeCache() override final;
+
protected:
BlitMode mBlitMode;
SDL_Surface *mTarget;