summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2012-11-21 21:13:31 +0300
committerAndrei Karas <akaras@inbox.ru>2012-12-01 22:58:18 +0300
commit04916c1b451e4400a496ae210b3faa10154c65ac (patch)
treefe7414434dcb6bcc1405b0d608d82348bc3ca466
parentd48e360ea40536e9f3e7fb4ce381b7fdc2ee5954 (diff)
downloadplus-04916c1b451e4400a496ae210b3faa10154c65ac.tar.gz
plus-04916c1b451e4400a496ae210b3faa10154c65ac.tar.bz2
plus-04916c1b451e4400a496ae210b3faa10154c65ac.tar.xz
plus-04916c1b451e4400a496ae210b3faa10154c65ac.zip
Add batch drawing for any images.
Add this drawing to Button.
-rw-r--r--src/client.cpp7
-rw-r--r--src/graphics.cpp203
-rw-r--r--src/graphics.h35
-rw-r--r--src/graphicsvertexes.cpp27
-rw-r--r--src/graphicsvertexes.h22
-rw-r--r--src/gui/widgets/button.cpp65
-rw-r--r--src/gui/widgets/button.h4
-rw-r--r--src/gui/widgets/widget2.h1
-rw-r--r--src/mobileopenglgraphics.cpp183
-rw-r--r--src/mobileopenglgraphics.h20
-rw-r--r--src/normalopenglgraphics.cpp219
-rw-r--r--src/normalopenglgraphics.h20
-rw-r--r--src/safeopenglgraphics.cpp6
-rw-r--r--src/safeopenglgraphics.h3
14 files changed, 783 insertions, 32 deletions
diff --git a/src/client.cpp b/src/client.cpp
index 0ec0647cb..6ea0ad11f 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -147,6 +147,7 @@ UserPalette *userPalette = nullptr;
Graphics *mainGraphics = nullptr;
Sound sound;
+int openGLMode = 0;
static uint32_t nextTick(uint32_t interval, void *param A_UNUSED);
static uint32_t nextSecond(uint32_t interval, void *param A_UNUSED);
@@ -538,12 +539,14 @@ void Client::gameInit()
#endif
#ifdef USE_OPENGL
+ openGLMode = config.getIntValue("opengl");
OpenGLImageHelper::setBlur(config.getBoolValue("blur"));
SDLImageHelper::SDLSetEnableAlphaCache(config.getBoolValue("alphaCache")
- && !config.getIntValue("opengl"));
+ && !openGLMode);
ImageHelper::setEnableAlpha(config.getFloatValue("guialpha") != 1.0f
- || config.getIntValue("opengl"));
+ || openGLMode);
#else
+ openGLMode = 0;
SDLImageHelper::SDLSetEnableAlphaCache(config.getBoolValue("alphaCache"));
ImageHelper::setEnableAlpha(config.getFloatValue("guialpha") != 1.0f);
#endif
diff --git a/src/graphics.cpp b/src/graphics.cpp
index 16a1de4a2..ec1de72e4 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -590,7 +590,6 @@ void Graphics::drawImageRect(const int x, const int y,
right->getWidth(),
h - top->getHeight() - bottom->getHeight());
}
-
// Draw the corners
if (drawMain)
{
@@ -739,6 +738,67 @@ bool Graphics::calcImageRect(GraphicsVertexes *const vert,
return 0;
}
+bool Graphics::calcImageRect(ImageVertexes *const vert,
+ const int x, const int y,
+ const int w, const int h,
+ const Image *const topLeft,
+ const Image *const topRight,
+ const Image *const bottomLeft,
+ const Image *const bottomRight,
+ const Image *const top,
+ const Image *const right,
+ const Image *const bottom,
+ const Image *const left,
+ const Image *const center)
+{
+ if (!vert)
+ return false;
+
+ BLOCK_START("Graphics::calcImageRect")
+ const bool drawMain = center && topLeft && topRight
+ && bottomLeft && bottomRight;
+
+// pushClipArea(gcn::Rectangle(x, y, w, h));
+
+ // Draw the center area
+ if (center && drawMain)
+ {
+ calcImagePattern(vert, center,
+ topLeft->getWidth() + x, topLeft->getHeight() + y,
+ w - topLeft->getWidth() - topRight->getWidth(),
+ h - topLeft->getHeight() - bottomLeft->getHeight());
+ }
+ // Draw the sides
+ if (top && left && bottom && right)
+ {
+ calcImagePattern(vert, top,
+ x + left->getWidth(), y,
+ w - left->getWidth() - right->getWidth(), top->getHeight());
+ calcImagePattern(vert, bottom,
+ x + left->getWidth(), y + h - bottom->getHeight(),
+ w - left->getWidth() - right->getWidth(),
+ bottom->getHeight());
+ calcImagePattern(vert, left,
+ x, y + top->getHeight(),
+ left->getWidth(),
+ h - top->getHeight() - bottom->getHeight());
+ calcImagePattern(vert, right,
+ x + w - right->getWidth(), y + top->getHeight(),
+ right->getWidth(),
+ h - top->getHeight() - bottom->getHeight());
+ }
+
+ calcTile(vert, topLeft, x, y);
+ calcTile(vert, topRight, x + w - topRight->getWidth(), y);
+ calcTile(vert, bottomLeft, x, y + h - bottomLeft->getHeight());
+ calcTile(vert, bottomRight, x + w - bottomRight->getWidth(),
+ y + h - bottomRight->getHeight());
+
+// popClipArea();
+ BLOCK_END("Graphics::calcImageRect")
+ return 0;
+}
+
void Graphics::calcImagePattern(GraphicsVertexes* const vert,
const Image *const image,
const int x, const int y,
@@ -792,10 +852,119 @@ void Graphics::calcImagePattern(GraphicsVertexes* const vert,
vert->incPtr(1);
}
-void Graphics::calcTile(ImageVertexes *const vert A_UNUSED,
- const Image *const image A_UNUSED,
- int x A_UNUSED, int y A_UNUSED) const
+void Graphics::calcImagePattern(ImageVertexes* const vert,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const
+{
+ // Check that preconditions for blitting are met.
+ if (!vert || !mTarget || !image || !image->mSDLSurface)
+ return;
+
+ const int iw = image->mBounds.w;
+ const int ih = image->mBounds.h;
+
+ if (iw == 0 || ih == 0)
+ return;
+
+ for (int py = 0; py < h; py += ih) // Y position on pattern plane
+ {
+ const int dh = (py + ih >= h) ? h - py : ih;
+ const int srcY = image->mBounds.y;
+ const int dstY = y + py + mClipStack.top().yOffset;
+
+ for (int px = 0; px < w; px += iw) // X position on pattern plane
+ {
+ const int dw = (px + iw >= w) ? w - px : iw;
+ const int srcX = image->mBounds.x;
+ const int dstX = x + px + mClipStack.top().xOffset;
+
+ DoubleRect *const r = new DoubleRect();
+ SDL_Rect &dstRect = r->dst;
+ SDL_Rect &srcRect = r->src;
+ dstRect.x = static_cast<short>(dstX);
+ dstRect.y = static_cast<short>(dstY);
+ srcRect.x = static_cast<short>(srcX);
+ srcRect.y = static_cast<short>(srcY);
+ srcRect.w = static_cast<uint16_t>(dw);
+ srcRect.h = static_cast<uint16_t>(dh);
+
+ if (SDL_FakeUpperBlit(image->mSDLSurface, &srcRect,
+ mTarget, &dstRect) == 1)
+ {
+ vert->sdl.push_back(r);
+ }
+ }
+ }
+}
+
+void Graphics::calcImagePattern(ImageCollection* const vertCol,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const
{
+ ImageVertexes *vert = nullptr;
+ if (vertCol->currentImage != image)
+ {
+ vert = new ImageVertexes();
+ vertCol->currentImage = image;
+ vertCol->currentVert = vert;
+ vert->image = image;
+ vertCol->draws.push_back(vert);
+ }
+ else
+ {
+ vert = vertCol->currentVert;
+ }
+
+ calcImagePattern(vert, image, x, y, w, h);
+}
+
+void Graphics::calcTile(ImageVertexes *const vert,
+ const Image *const image,
+ int x, int y) const
+{
+ vert->image = image;
+ calcTile(vert, x, y);
+}
+
+void Graphics::calcTile(ImageCollection *const vertCol,
+ const Image *const image,
+ int x, int y)
+{
+ if (vertCol->currentImage != image)
+ {
+ ImageVertexes *const vert = new ImageVertexes();
+ vertCol->currentImage = image;
+ vertCol->currentVert = vert;
+ vert->image = image;
+ vertCol->draws.push_back(vert);
+ calcTile(vert, x, y);
+ }
+ else
+ {
+ calcTile(vertCol->currentVert, x, y);
+ }
+}
+
+void Graphics::drawTile(const ImageCollection *const vertCol)
+{
+ const ImageVertexesVector &draws = vertCol->draws;
+ const ImageCollectionCIter it_end = draws.end();
+ for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
+ {
+ const ImageVertexes *const vert = *it;
+ const Image *const img = vert->image;
+ const DoubleRects *const rects = &vert->sdl;
+ DoubleRects::const_iterator it2 = rects->begin();
+ const DoubleRects::const_iterator it2_end = rects->end();
+ while (it2 != it2_end)
+ {
+ SDL_LowerBlit(img->mSDLSurface, &(*it2)->src,
+ mTarget, &(*it2)->dst);
+ ++ it2;
+ }
+ }
}
void Graphics::calcTile(ImageVertexes *const vert, int x, int y) const
@@ -901,6 +1070,32 @@ bool Graphics::calcWindow(GraphicsVertexes *const vert,
imgRect.grid[4]);
}
+bool Graphics::calcWindow(ImageCollection *const vertCol,
+ const int x, const int y, const int w, const int h,
+ const ImageRect &imgRect)
+{
+ ImageVertexes *vert = nullptr;
+ Image *const image = imgRect.grid[4];
+ if (vertCol->currentImage != image)
+ {
+ vert = new ImageVertexes();
+ vertCol->currentImage = image;
+ vertCol->currentVert = vert;
+ vert->image = image;
+ vertCol->draws.push_back(vert);
+// calcTile(vert, x, y);
+ }
+ else
+ {
+ vert = vertCol->currentVert;
+ }
+
+ return calcImageRect(vert, x, y, w, h,
+ imgRect.grid[0], imgRect.grid[2], imgRect.grid[6], imgRect.grid[8],
+ imgRect.grid[1], imgRect.grid[5], imgRect.grid[7], imgRect.grid[3],
+ imgRect.grid[4]);
+}
+
int Graphics::SDL_FakeUpperBlit(const SDL_Surface *const src,
SDL_Rect *const srcrect,
const SDL_Surface *const dst,
diff --git a/src/graphics.h b/src/graphics.h
index 7a5dc41a5..141de7456 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -29,6 +29,7 @@
class GraphicsVertexes;
class Image;
+class ImageCollection;
class ImageVertexes;
class MapLayer;
@@ -211,11 +212,34 @@ class Graphics : public gcn::SDLGraphics
const Image *const left,
const Image *const center);
+ virtual bool calcImageRect(ImageVertexes *const vert,
+ const int x, const int y,
+ const int w, const int h,
+ const Image *const topLeft,
+ const Image *const topRight,
+ const Image *const bottomLeft,
+ const Image *const bottomRight,
+ const Image *const top,
+ const Image *const right,
+ const Image *const bottom,
+ const Image *const left,
+ const Image *const center);
+
virtual void calcImagePattern(GraphicsVertexes *const vert,
const Image *const image,
const int x, const int y,
const int w, const int h) const;
+ virtual void calcImagePattern(ImageVertexes *const vert,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const;
+
+ virtual void calcImagePattern(ImageCollection *const vert,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const;
+
virtual void calcTile(ImageVertexes *const vert,
const Image *const image, int x, int y) const;
@@ -223,6 +247,12 @@ class Graphics : public gcn::SDLGraphics
virtual void drawTile(const ImageVertexes *const vert);
+ virtual void drawTile(const ImageCollection *const vertCol);
+
+ virtual void calcTile(ImageCollection *const vertCol,
+ const Image *const image,
+ int x, int y);
+
virtual void drawImageRect2(GraphicsVertexes *const vert,
const ImageRect &imgRect);
@@ -233,6 +263,11 @@ class Graphics : public gcn::SDLGraphics
const int x, const int y, const int w, const int h,
const ImageRect &imgRect);
+ virtual bool calcWindow(ImageCollection *const vertCol,
+ const int x, const int y,
+ const int w, const int h,
+ const ImageRect &imgRect);
+
/**
* Draws a rectangle using images. 4 corner images, 4 side images and 1
* image for the inside.
diff --git a/src/graphicsvertexes.cpp b/src/graphicsvertexes.cpp
index 3574ffe27..3ad522d79 100644
--- a/src/graphicsvertexes.cpp
+++ b/src/graphicsvertexes.cpp
@@ -286,3 +286,30 @@ ImageVertexes::~ImageVertexes()
delete_all(sdl);
sdl.clear();
}
+
+ImageCollection::ImageCollection() :
+#ifdef USE_OPENGL
+ currentGLImage(0),
+#endif
+ currentImage(nullptr),
+ currentVert(nullptr)
+{
+
+}
+
+ImageCollection::~ImageCollection()
+{
+ clear();
+}
+
+void ImageCollection::clear()
+{
+#ifdef USE_OPENGL
+ currentGLImage = 0;
+#endif
+ currentImage = nullptr;
+ currentVert = nullptr;
+
+ delete_all(draws);
+ draws.clear();
+}
diff --git a/src/graphicsvertexes.h b/src/graphicsvertexes.h
index cce9491c1..8a8c1133e 100644
--- a/src/graphicsvertexes.h
+++ b/src/graphicsvertexes.h
@@ -154,6 +154,28 @@ class ImageVertexes final
#endif
};
+typedef std::vector<ImageVertexes*> ImageVertexesVector;
+typedef ImageVertexesVector::const_iterator ImageCollectionCIter;
+
+class ImageCollection final
+{
+ public:
+ ImageCollection();
+
+ ~ImageCollection();
+
+ void clear();
+
+#ifdef USE_OPENGL
+ GLuint currentGLImage;
+#endif
+ const Image *currentImage;
+
+ ImageVertexes *currentVert;
+
+ ImageVertexesVector draws;
+};
+
class GraphicsVertexes final
{
public:
diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp
index 5a12893a6..5de5f01b5 100644
--- a/src/gui/widgets/button.cpp
+++ b/src/gui/widgets/button.cpp
@@ -65,7 +65,7 @@ Button::Button(const Widget2 *const widget) :
gcn::WidgetListener(),
mDescription(""), mClickCount(0),
mTag(0),
- mVertexes(new GraphicsVertexes()),
+ mVertexes2(new ImageCollection()),
mRedraw(true),
mMode(0),
mXOffset(0),
@@ -90,7 +90,7 @@ Button::Button(const Widget2 *const widget,
mDescription(""),
mClickCount(0),
mTag(0),
- mVertexes(new GraphicsVertexes()),
+ mVertexes2(new ImageCollection()),
mRedraw(true),
mMode(0),
mXOffset(0),
@@ -121,7 +121,7 @@ Button::Button(const Widget2 *const widget,
mDescription(""),
mClickCount(0),
mTag(0),
- mVertexes(new GraphicsVertexes()),
+ mVertexes2(new ImageCollection()),
mRedraw(true),
mMode(0),
mXOffset(0),
@@ -152,7 +152,7 @@ Button::Button(const Widget2 *const widget, const std::string &imageName,
mDescription(""),
mClickCount(0),
mTag(0),
- mVertexes(new GraphicsVertexes()),
+ mVertexes2(new ImageCollection()),
mRedraw(true),
mMode(0),
mXOffset(0),
@@ -210,8 +210,8 @@ Button::~Button()
for (int mode = 0; mode < BUTTON_COUNT; mode ++)
theme->unload(button[mode]);
}
- delete mVertexes;
- mVertexes = nullptr;
+ delete mVertexes2;
+ mVertexes2 = nullptr;
if (mImageSet)
{
mImageSet->decRef();
@@ -326,18 +326,6 @@ void Button::draw(gcn::Graphics *graphics)
}
}
- if (recalc)
- {
- mRedraw = false;
- mMode = mode;
- g2->calcWindow(mVertexes, 0, 0, getWidth(), getHeight(),
- skin->getBorder());
- }
-
- g2->drawImageRect2(mVertexes, skin->getBorder());
-
-// g2->drawImageRect(0, 0, getWidth(), getHeight(), button[mode]);
-
const int padding = skin->getPadding();
const int spacing = skin->getOption("spacing");
@@ -401,18 +389,47 @@ void Button::draw(gcn::Graphics *graphics)
graphics->setFont(getFont());
- if (isPressed())
+ if (openGLMode != 2)
{
- if (mImages)
- g2->drawImage(mImages[mode], imageX + 1, imageY + 1);
- g2->drawText(getCaption(), textX + 1, textY + 1, getAlignment());
+ if (recalc)
+ {
+ mRedraw = false;
+ mMode = mode;
+ mVertexes2->clear();
+ g2->calcWindow(mVertexes2, 0, 0, getWidth(), getHeight(),
+ skin->getBorder());
+
+ if (mImages)
+ {
+ if (isPressed())
+ {
+ g2->calcTile(mVertexes2, mImages[mode],
+ imageX + 1, imageY + 1);
+ }
+ else
+ {
+ g2->calcTile(mVertexes2, mImages[mode], imageX, imageY);
+ }
+ }
+ }
+ g2->drawTile(mVertexes2);
}
else
{
+ g2->drawImageRect(0, 0, getWidth(), getHeight(), skin->getBorder());
if (mImages)
- g2->drawImage(mImages[mode], imageX, imageY);
- g2->drawText(getCaption(), textX, textY, getAlignment());
+ {
+ if (isPressed())
+ g2->drawImage(mImages[mode], imageX + 1, imageY + 1);
+ else
+ g2->drawImage(mImages[mode], imageX, imageY);
+ }
}
+
+ if (isPressed())
+ g2->drawText(getCaption(), textX + 1, textY + 1, getAlignment());
+ else
+ g2->drawText(getCaption(), textX, textY, getAlignment());
BLOCK_END("Button::draw")
}
diff --git a/src/gui/widgets/button.h b/src/gui/widgets/button.h
index 25fa0da02..3e84eeafe 100644
--- a/src/gui/widgets/button.h
+++ b/src/gui/widgets/button.h
@@ -31,8 +31,8 @@
#include "localconsts.h"
-class GraphicsVertexes;
class Image;
+class ImageCollection;
class ImageSet;
class ImageRect;
class Skin;
@@ -147,7 +147,7 @@ class Button final : public gcn::Button,
std::string mDescription;
unsigned mClickCount;
int mTag;
- GraphicsVertexes *mVertexes;
+ ImageCollection *mVertexes2;
bool mRedraw;
int mMode;
int mXOffset;
diff --git a/src/gui/widgets/widget2.h b/src/gui/widgets/widget2.h
index 3b4060899..f2eb9bbb1 100644
--- a/src/gui/widgets/widget2.h
+++ b/src/gui/widgets/widget2.h
@@ -84,4 +84,5 @@ class Widget2
int mPaletteOffset;
};
+extern int openGLMode;
#endif
diff --git a/src/mobileopenglgraphics.cpp b/src/mobileopenglgraphics.cpp
index 52e013f41..92afbc741 100644
--- a/src/mobileopenglgraphics.cpp
+++ b/src/mobileopenglgraphics.cpp
@@ -654,6 +654,163 @@ void MobileOpenGLGraphics::calcImagePattern(GraphicsVertexes *const vert,
vert->incPtr(1);
}
+void MobileOpenGLGraphics::calcImagePattern(ImageVertexes *const vert,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const
+{
+ if (!image)
+ return;
+
+ const int srcX = image->mBounds.x;
+ const int srcY = image->mBounds.y;
+
+ const int iw = image->mBounds.w;
+ const int ih = image->mBounds.h;
+
+ if (iw == 0 || ih == 0)
+ return;
+
+ const float tw = static_cast<float>(image->mTexWidth);
+ const float th = static_cast<float>(image->mTexHeight);
+
+ const unsigned int vLimit = mMaxVertices * 4;
+
+ NormalOpenGLGraphicsVertexes &ogl = vert->ogl;
+ unsigned int vp = ogl.continueVp();
+
+ // 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;
+
+ GLfloat *floatTexArray = ogl.continueFloatTexArray();
+ GLshort *shortVertArray = ogl.continueShortVertArray();
+
+ 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;
+
+ float texX2 = static_cast<float>(srcX + width) / tw;
+ float texY2 = static_cast<float>(srcY + height) / th;
+
+ floatTexArray[vp + 0] = texX1;
+ floatTexArray[vp + 1] = texY1;
+
+ floatTexArray[vp + 2] = texX2;
+ floatTexArray[vp + 3] = texY1;
+
+ floatTexArray[vp + 4] = texX2;
+ floatTexArray[vp + 5] = texY2;
+
+ floatTexArray[vp + 6] = texX1;
+ floatTexArray[vp + 7] = texY1;
+
+ floatTexArray[vp + 8] = texX1;
+ floatTexArray[vp + 9] = texY2;
+
+ floatTexArray[vp + 10] = texX2;
+ floatTexArray[vp + 11] = texY2;
+
+
+ shortVertArray[vp + 0] = dstX;
+ shortVertArray[vp + 1] = dstY;
+
+ shortVertArray[vp + 2] = dstX + width;
+ shortVertArray[vp + 3] = dstY;
+
+ shortVertArray[vp + 4] = dstX + width;
+ shortVertArray[vp + 5] = dstY + height;
+
+ shortVertArray[vp + 6] = dstX;
+ shortVertArray[vp + 7] = dstY;
+
+ shortVertArray[vp + 8] = dstX;
+ shortVertArray[vp + 9] = dstY + height;
+
+ shortVertArray[vp + 10] = dstX + width;
+ shortVertArray[vp + 11] = dstY + height;
+
+ vp += 12;
+ if (vp >= vLimit)
+ {
+ floatTexArray = ogl.switchFloatTexArray();
+ shortVertArray = ogl.switchShortVertArray();
+ ogl.switchVp(vp);
+ vp = 0;
+ }
+ }
+ }
+ }
+ ogl.switchVp(vp);
+}
+
+void MobileOpenGLGraphics::calcTile(ImageCollection *const vertCol,
+ const Image *const image,
+ int x, int y)
+{
+ if (vertCol->currentGLImage != image->mGLImage)
+ {
+ ImageVertexes *const vert = new ImageVertexes();
+ vertCol->currentGLImage = image->mGLImage;
+ vertCol->currentVert = vert;
+ vert->image = image;
+ vertCol->draws.push_back(vert);
+ calcTile(vert, image, x, y);
+ }
+ else
+ {
+ calcTile(vertCol->currentVert, image, x, y);
+ }
+}
+
+void MobileOpenGLGraphics::drawTile(const ImageCollection *const vertCol)
+{
+ const ImageVertexesVector &draws = vertCol->draws;
+ const ImageCollectionCIter it_end = draws.end();
+ for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
+ {
+ const ImageVertexes *const vert = *it;
+ const Image *const image = vert->image;
+
+ setColorAlpha(image->mAlpha);
+#ifdef DEBUG_BIND_TEXTURE
+ debugBindTexture(image);
+#endif
+ bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage);
+ setTexturingAndBlending(true);
+ drawVertexes(vert->ogl);
+ }
+}
+
+void MobileOpenGLGraphics::calcImagePattern(ImageCollection* const vertCol,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const
+{
+ ImageVertexes *vert = nullptr;
+ if (vertCol->currentGLImage != image->mGLImage)
+ {
+ vert = new ImageVertexes();
+ vertCol->currentGLImage = image->mGLImage;
+ vertCol->currentVert = vert;
+ vert->image = image;
+ vertCol->draws.push_back(vert);
+ }
+ else
+ {
+ vert = vertCol->currentVert;
+ }
+
+ calcImagePattern(vert, image, x, y, w, h);
+}
+
void MobileOpenGLGraphics::calcTile(ImageVertexes *const vert,
const Image *const image,
int dstX, int dstY) const
@@ -755,6 +912,32 @@ void MobileOpenGLGraphics::drawTile(const ImageVertexes *const vert)
drawVertexes(vert->ogl);
}
+bool MobileOpenGLGraphics::calcWindow(ImageCollection *const vertCol,
+ const int x, const int y,
+ const int w, const int h,
+ const ImageRect &imgRect)
+{
+ ImageVertexes *vert = nullptr;
+ Image *const image = imgRect.grid[4];
+ if (vertCol->currentGLImage != image->mGLImage)
+ {
+ vert = new ImageVertexes();
+ vertCol->currentGLImage = image->mGLImage;
+ vertCol->currentVert = vert;
+ vert->image = image;
+ vertCol->draws.push_back(vert);
+ }
+ else
+ {
+ vert = vertCol->currentVert;
+ }
+
+ return calcImageRect(vert, x, y, w, h,
+ imgRect.grid[0], imgRect.grid[2], imgRect.grid[6], imgRect.grid[8],
+ imgRect.grid[1], imgRect.grid[5], imgRect.grid[7], imgRect.grid[3],
+ imgRect.grid[4]);
+}
+
void MobileOpenGLGraphics::updateScreen()
{
BLOCK_START("Graphics::updateScreen")
diff --git a/src/mobileopenglgraphics.h b/src/mobileopenglgraphics.h
index 78d24d5fc..ad630c6b7 100644
--- a/src/mobileopenglgraphics.h
+++ b/src/mobileopenglgraphics.h
@@ -95,14 +95,34 @@ class MobileOpenGLGraphics final : public Graphics
const int x, const int y,
const int w, const int h) const override;
+ void calcImagePattern(ImageVertexes *const vert,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const override;
+
+ void calcImagePattern(ImageCollection *const vert,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const override;
+
void calcTile(ImageVertexes *const vert, const Image *const image,
int x, int y) const override;
+ void drawTile(const ImageCollection *const vertCol);
+
+ void calcTile(ImageCollection *const vertCol,
+ const Image *const image, int x, int y) override;
+
void drawTile(const ImageVertexes *const vert) override;
void drawImagePattern2(const GraphicsVertexes *const vert,
const Image *const image) override;
+ bool calcWindow(ImageCollection *const vertCol,
+ const int x, const int y,
+ const int w, const int h,
+ const ImageRect &imgRect);
+
void updateScreen() override;
void _beginDraw();
diff --git a/src/normalopenglgraphics.cpp b/src/normalopenglgraphics.cpp
index 11cc8ab5f..f7ca7b802 100644
--- a/src/normalopenglgraphics.cpp
+++ b/src/normalopenglgraphics.cpp
@@ -823,6 +823,199 @@ void NormalOpenGLGraphics::calcImagePattern(GraphicsVertexes *const vert,
vert->incPtr(1);
}
+void NormalOpenGLGraphics::calcImagePattern(ImageVertexes* const vert,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const
+{
+ if (!image)
+ return;
+
+ const int srcX = image->mBounds.x;
+ const int srcY = image->mBounds.y;
+
+ const int iw = image->mBounds.w;
+ const int ih = image->mBounds.h;
+
+ if (iw == 0 || ih == 0)
+ return;
+
+ const float tw = static_cast<float>(image->mTexWidth);
+ const float th = static_cast<float>(image->mTexHeight);
+
+ const unsigned int vLimit = mMaxVertices * 4;
+
+ NormalOpenGLGraphicsVertexes &ogl = vert->ogl;
+ unsigned int vp = ogl.continueVp();
+
+ // 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;
+
+ GLfloat *floatTexArray = ogl.continueFloatTexArray();
+ GLint *intVertArray = ogl.continueIntVertArray();
+
+ 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;
+
+ float texX2 = static_cast<float>(srcX + width) / tw;
+ float texY2 = static_cast<float>(srcY + height) / th;
+
+ floatTexArray[vp + 0] = texX1;
+ floatTexArray[vp + 1] = texY1;
+
+ floatTexArray[vp + 2] = texX2;
+ floatTexArray[vp + 3] = texY1;
+
+ floatTexArray[vp + 4] = texX2;
+ floatTexArray[vp + 5] = texY2;
+
+ floatTexArray[vp + 6] = texX1;
+ floatTexArray[vp + 7] = texY2;
+
+ intVertArray[vp + 0] = dstX;
+ intVertArray[vp + 1] = dstY;
+
+ intVertArray[vp + 2] = dstX + width;
+ intVertArray[vp + 3] = dstY;
+
+ intVertArray[vp + 4] = dstX + width;
+ intVertArray[vp + 5] = dstY + height;
+
+ intVertArray[vp + 6] = dstX;
+ intVertArray[vp + 7] = dstY + height;
+
+ vp += 8;
+ if (vp >= vLimit)
+ {
+ floatTexArray = ogl.switchFloatTexArray();
+ intVertArray = ogl.switchIntVertArray();
+ ogl.switchVp(vp);
+ vp = 0;
+ }
+ }
+ }
+ }
+ else
+ {
+ GLint *intTexArray = ogl.continueIntTexArray();
+ GLint *intVertArray = ogl.continueIntVertArray();
+
+ 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;
+
+ intTexArray[vp + 0] = srcX;
+ intTexArray[vp + 1] = srcY;
+
+ intTexArray[vp + 2] = srcX + width;
+ intTexArray[vp + 3] = srcY;
+
+ intTexArray[vp + 4] = srcX + width;
+ intTexArray[vp + 5] = srcY + height;
+
+ intTexArray[vp + 6] = srcX;
+ intTexArray[vp + 7] = srcY + height;
+
+ intVertArray[vp + 0] = dstX;
+ intVertArray[vp + 1] = dstY;
+
+ intVertArray[vp + 2] = dstX + width;
+ intVertArray[vp + 3] = dstY;
+
+ intVertArray[vp + 4] = dstX + width;
+ intVertArray[vp + 5] = dstY + height;
+
+ intVertArray[vp + 6] = dstX;
+ intVertArray[vp + 7] = dstY + height;
+
+ vp += 8;
+ if (vp >= vLimit)
+ {
+ intTexArray = ogl.switchIntTexArray();
+ intVertArray = ogl.switchIntVertArray();
+ ogl.switchVp(vp);
+ vp = 0;
+ }
+ }
+ }
+ }
+ ogl.switchVp(vp);
+}
+
+void NormalOpenGLGraphics::calcTile(ImageCollection *const vertCol,
+ const Image *const image,
+ int x, int y)
+{
+ if (vertCol->currentGLImage != image->mGLImage)
+ {
+ ImageVertexes *const vert = new ImageVertexes();
+ vertCol->currentGLImage = image->mGLImage;
+ vertCol->currentVert = vert;
+ vert->image = image;
+ vertCol->draws.push_back(vert);
+ calcTile(vert, image, x, y);
+ }
+ else
+ {
+ calcTile(vertCol->currentVert, image, x, y);
+ }
+}
+
+void NormalOpenGLGraphics::drawTile(const ImageCollection *const vertCol)
+{
+ const ImageVertexesVector &draws = vertCol->draws;
+ const ImageCollectionCIter it_end = draws.end();
+ for (ImageCollectionCIter it = draws.begin(); it != it_end; ++ it)
+ {
+ const ImageVertexes *const vert = *it;
+ const Image *const image = vert->image;
+
+ setColorAlpha(image->mAlpha);
+#ifdef DEBUG_BIND_TEXTURE
+ debugBindTexture(image);
+#endif
+ bindTexture(OpenGLImageHelper::mTextureType, image->mGLImage);
+ setTexturingAndBlending(true);
+ drawVertexes(vert->ogl);
+ }
+}
+
+void NormalOpenGLGraphics::calcImagePattern(ImageCollection* const vertCol,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const
+{
+ ImageVertexes *vert = nullptr;
+ if (vertCol->currentGLImage != image->mGLImage)
+ {
+ vert = new ImageVertexes();
+ vertCol->currentGLImage = image->mGLImage;
+ vertCol->currentVert = vert;
+ vert->image = image;
+ vertCol->draws.push_back(vert);
+ }
+ else
+ {
+ vert = vertCol->currentVert;
+ }
+
+ calcImagePattern(vert, image, x, y, w, h);
+}
+
void NormalOpenGLGraphics::calcTile(ImageVertexes *const vert,
const Image *const image,
int dstX, int dstY) const
@@ -950,6 +1143,32 @@ void NormalOpenGLGraphics::drawTile(const ImageVertexes *const vert)
drawVertexes(vert->ogl);
}
+bool NormalOpenGLGraphics::calcWindow(ImageCollection *const vertCol,
+ const int x, const int y,
+ const int w, const int h,
+ const ImageRect &imgRect)
+{
+ ImageVertexes *vert = nullptr;
+ Image *const image = imgRect.grid[4];
+ if (vertCol->currentGLImage != image->mGLImage)
+ {
+ vert = new ImageVertexes();
+ vertCol->currentGLImage = image->mGLImage;
+ vertCol->currentVert = vert;
+ vert->image = image;
+ vertCol->draws.push_back(vert);
+ }
+ else
+ {
+ vert = vertCol->currentVert;
+ }
+
+ return calcImageRect(vert, x, y, w, h,
+ imgRect.grid[0], imgRect.grid[2], imgRect.grid[6], imgRect.grid[8],
+ imgRect.grid[1], imgRect.grid[5], imgRect.grid[7], imgRect.grid[3],
+ imgRect.grid[4]);
+}
+
void NormalOpenGLGraphics::updateScreen()
{
BLOCK_START("Graphics::updateScreen")
diff --git a/src/normalopenglgraphics.h b/src/normalopenglgraphics.h
index 0c5bb40ac..2c70a0fbe 100644
--- a/src/normalopenglgraphics.h
+++ b/src/normalopenglgraphics.h
@@ -95,14 +95,34 @@ class NormalOpenGLGraphics final : public Graphics
const int x, const int y,
const int w, const int h) const override;
+ void calcImagePattern(ImageVertexes* const vert,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const override;
+
+ void calcImagePattern(ImageCollection* const vert,
+ const Image *const image,
+ const int x, const int y,
+ const int w, const int h) const override;
+
void calcTile(ImageVertexes *const vert, const Image *const image,
int x, int y) const override;
+ void calcTile(ImageCollection *const vertCol,
+ const Image *const image, int x, int y) override;
+
+ void drawTile(const ImageCollection *const vertCol) override;
+
void drawTile(const ImageVertexes *const vert) override;
void drawImagePattern2(const GraphicsVertexes *const vert,
const Image *const image) override;
+ bool calcWindow(ImageCollection *const vertCol,
+ const int x, const int y,
+ const int w, const int h,
+ const ImageRect &imgRect) override;
+
void updateScreen() override;
void _beginDraw();
diff --git a/src/safeopenglgraphics.cpp b/src/safeopenglgraphics.cpp
index 6142627f1..6b6c80116 100644
--- a/src/safeopenglgraphics.cpp
+++ b/src/safeopenglgraphics.cpp
@@ -353,6 +353,12 @@ bool SafeOpenGLGraphics::calcImageRect(GraphicsVertexes *const vert,
return true;
}
+void SafeOpenGLGraphics::calcTile(ImageCollection *const vertCol A_UNUSED,
+ const Image *const image A_UNUSED,
+ int x A_UNUSED, int y A_UNUSED)
+{
+}
+
void SafeOpenGLGraphics::calcTile(ImageVertexes *const vert A_UNUSED,
const Image *const image A_UNUSED,
int x A_UNUSED, int y A_UNUSED) const
diff --git a/src/safeopenglgraphics.h b/src/safeopenglgraphics.h
index 1b84689df..cd79f213f 100644
--- a/src/safeopenglgraphics.h
+++ b/src/safeopenglgraphics.h
@@ -102,6 +102,9 @@ class SafeOpenGLGraphics final : public Graphics
void calcTile(ImageVertexes *const vert, const Image *const image,
int x, int y) const override;
+ void calcTile(ImageCollection *const vertCol,
+ const Image *const image, int x, int y) override;
+
void drawTile(const ImageVertexes *const vert) override;
void updateScreen() override;