From c9f8bba932022ffd90031713c51861587f86b244 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 28 Dec 2013 23:06:17 +0300 Subject: Add cached draw methods into renderers. --- src/render/normalopenglgraphics.cpp | 294 ++++++++++++++++++++++++++++++++++++ 1 file changed, 294 insertions(+) (limited to 'src/render/normalopenglgraphics.cpp') 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(image->mTexWidth); + const float th = static_cast(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(srcX) / tw; + const float texY1 = static_cast(srcY) / th; + + const float texX2 = static_cast(srcX + w) / tw; + const float texY2 = static_cast(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(image->mTexWidth); + const float th = static_cast(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(srcX) / tw; + const float texY1 = static_cast(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(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(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 -- cgit v1.2.3-70-g09d2