summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2011-03-26 05:07:12 +0200
committerAndrei Karas <akaras@inbox.ru>2011-03-26 05:50:44 +0200
commit8403dcf857c9cc639e8162edd5d4df4af07274bc (patch)
tree2f127213e0df4691b06c549a8f20b3d5225b9220 /src
parentfc24490f1ecd186f3c294915fadee62c3053d841 (diff)
downloadmv-8403dcf857c9cc639e8162edd5d4df4af07274bc.tar.gz
mv-8403dcf857c9cc639e8162edd5d4df4af07274bc.tar.bz2
mv-8403dcf857c9cc639e8162edd5d4df4af07274bc.tar.xz
mv-8403dcf857c9cc639e8162edd5d4df4af07274bc.zip
Precalculation vertexes for improving draw speed.
Implemented in Software and fast OpenGL backends. Not all controls using this mode because some limitations. Known issue: impossible compile without opengl. Will be fixed in next commits.
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/client.cpp2
-rw-r--r--src/graphics.cpp217
-rw-r--r--src/graphics.h29
-rw-r--r--src/graphicsvertexes.cpp144
-rw-r--r--src/graphicsvertexes.h155
-rw-r--r--src/gui/widgets/button.cpp64
-rw-r--r--src/gui/widgets/button.h13
-rw-r--r--src/gui/widgets/popup.cpp39
-rw-r--r--src/gui/widgets/popup.h11
-rw-r--r--src/gui/widgets/progressbar.cpp68
-rw-r--r--src/gui/widgets/progressbar.h19
-rw-r--r--src/gui/widgets/scrollarea.cpp56
-rw-r--r--src/gui/widgets/scrollarea.h7
-rw-r--r--src/gui/widgets/tab.cpp34
-rw-r--r--src/gui/widgets/tab.h11
-rw-r--r--src/gui/widgets/window.cpp28
-rw-r--r--src/gui/widgets/window.h5
-rw-r--r--src/opengl1graphics.cpp27
-rw-r--r--src/opengl1graphics.h10
-rw-r--r--src/openglgraphics.cpp212
-rw-r--r--src/openglgraphics.h11
23 files changed, 1138 insertions, 28 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 262475989..873638df1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -492,6 +492,8 @@ SET(SRCS
game.h
graphics.cpp
graphics.h
+ graphicsvertexes.cpp
+ graphicsvertexes.h
guichanfwd.h
guild.cpp
guild.h
diff --git a/src/Makefile.am b/src/Makefile.am
index ac89d665f..825b40718 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -385,6 +385,8 @@ manaplus_SOURCES = gui/widgets/avatarlistbox.cpp \
game.h \
graphics.cpp \
graphics.h \
+ graphicsvertexes.cpp \
+ graphicsvertexes.h \
guichanfwd.h \
guild.cpp \
guild.h \
diff --git a/src/client.cpp b/src/client.cpp
index 0179c0f51..8fa9a1c8c 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -28,6 +28,7 @@
#include "emoteshortcut.h"
#include "event.h"
#include "game.h"
+#include "graphicsvertexes.h"
#include "itemshortcut.h"
#include "dropshortcut.h"
#include "keyboardconfig.h"
@@ -399,6 +400,7 @@ Client::Client(const Options &options):
// Setup image loading for the right image format
Image::setLoadAsOpenGL(useOpenGL);
+ GraphicsVertexes::setLoadAsOpenGL(useOpenGL);
// Create the graphics context
switch(useOpenGL)
diff --git a/src/graphics.cpp b/src/graphics.cpp
index 5bc909c8e..e221f9fdb 100644
--- a/src/graphics.cpp
+++ b/src/graphics.cpp
@@ -23,6 +23,8 @@
#include <cassert>
#include "graphics.h"
+
+#include "graphicsvertexes.h"
#include "log.h"
#include "resources/image.h"
@@ -152,8 +154,6 @@ bool Graphics::drawRescaledImage(Image *image, int srcX, int srcY,
return false;
Image *tmpImage = image->SDLgetScaledImage(desiredWidth, desiredHeight);
-// logger->log("SDLgetScaledImage " + tmpImage->getIdPath()
-// + toString(desiredWidth) + "," + toString(desiredHeight));
bool returnValue = false;
@@ -269,6 +269,53 @@ void Graphics::drawImagePattern(Image *image, int x, int y, int w, int h)
}
}
+void Graphics::drawImagePatternDebug(GraphicsVertexes* vert, Image *image, int x, int y, int w, int h)
+{
+ // Check that preconditions for blitting are met.
+ if (!mTarget || !image)
+ return;
+ if (!image->mSDLSurface)
+ return;
+
+ const int iw = image->getWidth();
+ const int ih = image->getHeight();
+
+ if (iw == 0 || ih == 0)
+ return;
+
+ std::list<DoubleRect*> *arr = vert->getRectsSDL();
+ std::list<DoubleRect*>::iterator it;
+ it = arr->begin();
+
+ for (int py = 0; py < h; py += ih) // Y position on pattern plane
+ {
+ int dh = (py + ih >= h) ? h - py : ih;
+ int srcY = image->mBounds.y;
+ int dstY = y + py + mClipStack.top().yOffset;
+
+ for (int px = 0; px < w; px += iw) // X position on pattern plane
+ {
+ int dw = (px + iw >= w) ? w - px : iw;
+ int srcX = image->mBounds.x;
+ int dstX = x + px + mClipStack.top().xOffset;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ 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>(dw);
+ srcRect.h = static_cast<Uint16>(dh);
+
+ SDL_BlitSurface(image->mSDLSurface, &srcRect, mTarget, &dstRect);
+
+ ++it;
+ }
+ }
+}
+
+
void Graphics::drawRescaledImagePattern(Image *image, int x, int y,
int w, int h, int scaledWidth,
int scaledHeight)
@@ -286,9 +333,6 @@ void Graphics::drawRescaledImagePattern(Image *image, int x, int y,
if (!tmpImage)
return;
-// logger->log("SDLgetScaledImageS " + tmpImage->getIdPath()
-// + toString(scaledWidth) + "," + toString(scaledHeight));
-
const int iw = tmpImage->getWidth();
const int ih = tmpImage->getHeight();
@@ -388,6 +432,159 @@ void Graphics::drawImageRect(int x, int y, int w, int h,
imgRect.grid[4]);
}
+void Graphics::drawImageRect2(GraphicsVertexes* vert, const ImageRect &imgRect)
+{
+ vert->setPtr(0);
+
+ const bool drawMain = imgRect.grid[4] && imgRect.grid[0] && imgRect.grid[2]
+ && imgRect.grid[6] && imgRect.grid[8];
+
+ if (drawMain)
+ {
+ // center
+ drawImagePattern2(vert, imgRect.grid[4]);
+ }
+ vert->incPtr();
+
+ // top
+ drawImagePattern2(vert, imgRect.grid[1]);
+ vert->incPtr();
+
+ // bottom
+ drawImagePattern2(vert, imgRect.grid[7]);
+ vert->incPtr();
+
+ // left
+ drawImagePattern2(vert, imgRect.grid[3]);
+ vert->incPtr();
+
+ // right
+ drawImagePattern2(vert, imgRect.grid[5]);
+ vert->incPtr();
+
+ // Draw the corners
+ if (drawMain)
+ {
+ drawImage(imgRect.grid[0], 0, 0);
+ drawImage(imgRect.grid[2], vert->mW - imgRect.grid[2]->getWidth(), 0);
+ drawImage(imgRect.grid[6], 0, vert->mH - imgRect.grid[6]->getHeight());
+ drawImage(imgRect.grid[8],
+ vert->mW - imgRect.grid[8]->getWidth(),
+ vert->mH - imgRect.grid[8]->getHeight());
+ }
+}
+
+void Graphics::drawImagePattern2(GraphicsVertexes *vert, Image *img)
+{
+ std::list<DoubleRect*> *arr = vert->getRectsSDL();
+ std::list<DoubleRect*>::iterator it;
+
+ for (it = arr->begin(); it != arr->end(); ++it)
+ SDL_BlitSurface(img->mSDLSurface, &(*it)->src, mTarget, &(*it)->dst);
+}
+
+bool Graphics::calcImageRect(GraphicsVertexes* vert,
+ int x, int y, int w, int h,
+ Image *topLeft, Image *topRight,
+ Image *bottomLeft, Image *bottomRight,
+ Image *top, Image *right,
+ Image *bottom, Image *left,
+ Image *center)
+{
+ const bool drawMain = center && topLeft && topRight
+ && bottomLeft && bottomRight;
+
+ vert->init(x, y, w, h);
+ pushClipArea(gcn::Rectangle(vert->mX, vert->mY, vert->mW, vert->mH));
+
+ // Draw the center area
+ if (center && drawMain)
+ {
+ calcImagePattern(vert, center,
+ topLeft->getWidth(), topLeft->getHeight(),
+ w - topLeft->getWidth() - topRight->getWidth(),
+ h - topLeft->getHeight() - bottomLeft->getHeight());
+ }
+ else
+ {
+ vert->incPtr(1);
+ }
+
+ // Draw the sides
+ if (top && left && bottom && right)
+ {
+ calcImagePattern(vert, top,
+ left->getWidth(), 0,
+ w - left->getWidth() - right->getWidth(), top->getHeight());
+ calcImagePattern(vert, bottom,
+ left->getWidth(), h - bottom->getHeight(),
+ w - left->getWidth() - right->getWidth(),
+ bottom->getHeight());
+ calcImagePattern(vert, left,
+ 0, top->getHeight(),
+ left->getWidth(),
+ h - top->getHeight() - bottom->getHeight());
+ calcImagePattern(vert, right,
+ w - right->getWidth(), top->getHeight(),
+ right->getWidth(),
+ h - top->getHeight() - bottom->getHeight());
+ }
+ else
+ {
+ vert->incPtr(4);
+ }
+
+ popClipArea();
+ return 0;
+}
+
+void Graphics::calcImagePattern(GraphicsVertexes* vert,
+ Image *image, int x, int y, int w, int h)
+{
+ // Check that preconditions for blitting are met.
+ if (!vert || !mTarget || !image || !image->mSDLSurface || !vert->sdl)
+ {
+ vert->incPtr(1);
+ return;
+ }
+ vert->clearSDL();
+
+ const int iw = image->getWidth();
+ const int ih = image->getHeight();
+
+ if (iw == 0 || ih == 0)
+ {
+ vert->incPtr(1);
+ return;
+ }
+
+ for (int py = 0; py < h; py += ih) // Y position on pattern plane
+ {
+ int dh = (py + ih >= h) ? h - py : ih;
+ int srcY = image->mBounds.y;
+ int dstY = y + py + mClipStack.top().yOffset;
+
+ for (int px = 0; px < w; px += iw) // X position on pattern plane
+ {
+ int dw = (px + iw >= w) ? w - px : iw;
+ int srcX = image->mBounds.x;
+ int dstX = x + px + mClipStack.top().xOffset;
+
+ SDL_Rect dstRect;
+ SDL_Rect srcRect;
+ 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>(dw);
+ srcRect.h = static_cast<Uint16>(dh);
+
+ vert->pushSDL(srcRect, dstRect);
+ }
+ }
+ vert->incPtr(1);
+}
+
void Graphics::updateScreen()
{
SDL_Flip(mTarget);
@@ -425,3 +622,13 @@ bool Graphics::drawNet(int x1, int y1, int x2, int y2, int width, int height)
return true;
}
+
+bool Graphics::calcWindow(GraphicsVertexes* vert,
+ int x, int y, int w, int h,
+ const ImageRect &imgRect)
+{
+ 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]);
+}
diff --git a/src/graphics.h b/src/graphics.h
index a8e593ba1..23ce0bb91 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -25,12 +25,15 @@
#include <guichan/sdl/sdlgraphics.hpp>
+//include "graphicsvertexes.h"
+
#ifdef __GNUC__
#define _UNUSED_ __attribute__ ((unused))
#else
#define _UNUSED_
#endif
+class GraphicsVertexes;
class Image;
class ImageRect;
@@ -161,6 +164,8 @@ class Graphics : public gcn::SDLGraphics
int x, int y,
int w, int h);
+ void drawImagePatternDebug(GraphicsVertexes* vert, Image *image, int x, int y, int w, int h);
+
/**
* Draw a pattern based on a rescaled version of the given image...
*/
@@ -187,6 +192,27 @@ class Graphics : public gcn::SDLGraphics
void drawImageRect(int x, int y, int w, int h,
const ImageRect &imgRect);
+ virtual bool calcImageRect(GraphicsVertexes* vert,
+ int x, int y, int w, int h,
+ Image *topLeft, Image *topRight,
+ Image *bottomLeft, Image *bottomRight,
+ Image *top, Image *right,
+ Image *bottom, Image *left,
+ Image *center);
+
+ virtual void calcImagePattern(GraphicsVertexes* vert, Image *image,
+ int x, int y,
+ int w, int h);
+
+ virtual void drawImageRect2(GraphicsVertexes* vert,
+ const ImageRect &imgRect);
+
+ virtual void drawImagePattern2(GraphicsVertexes *vert, Image *img);
+
+ bool calcWindow(GraphicsVertexes* vert,
+ int x, int y, int w, int h,
+ const ImageRect &imgRect);
+
/**
* Draws a rectangle using images. 4 corner images, 4 side images and 1
* image for the inside.
@@ -228,6 +254,9 @@ class Graphics : public gcn::SDLGraphics
gcn::Font *getFont() const
{ return mFont; }
+ gcn::ClipRectangle &getTopClip()
+ { return mClipStack.top(); }
+
protected:
int mWidth;
int mHeight;
diff --git a/src/graphicsvertexes.cpp b/src/graphicsvertexes.cpp
new file mode 100644
index 000000000..1170d55fd
--- /dev/null
+++ b/src/graphicsvertexes.cpp
@@ -0,0 +1,144 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "graphicsvertexes.h"
+
+#include "main.h"
+
+#include "utils/dtor.h"
+
+#ifdef USE_OPENGL
+int GraphicsVertexes::mUseOpenGL = 0;
+const unsigned int vertexBufSize = 500;
+#endif
+
+
+SDLGraphicsVertexes::SDLGraphicsVertexes()
+{
+
+}
+
+SDLGraphicsVertexes::~SDLGraphicsVertexes()
+{
+ delete_all(mList);
+}
+
+
+OpenGLGraphicsVertexes::OpenGLGraphicsVertexes() :
+ mFloatTexArray(0),
+ mIntTexArray(0),
+ mIntVertArray(0)
+{
+}
+
+OpenGLGraphicsVertexes::~OpenGLGraphicsVertexes()
+{
+ clear();
+}
+
+void OpenGLGraphicsVertexes::clear()
+{
+ delete_all(mFloatTexPool);
+ mFloatTexPool.clear();
+ delete_all(mIntVertPool);
+ mIntVertPool.clear();
+ delete_all(mIntTexPool);
+ mIntTexPool.clear();
+ mVp.clear();
+}
+
+void OpenGLGraphicsVertexes::init()
+{
+ clear();
+}
+
+GLfloat *OpenGLGraphicsVertexes::switchFloatTexArray()
+{
+ mFloatTexArray = new GLfloat[vertexBufSize * 4 + 30];
+ mFloatTexPool.push_back(mFloatTexArray);
+ return mFloatTexArray;
+}
+
+GLint *OpenGLGraphicsVertexes::switchIntVertArray()
+{
+ mIntVertArray = new GLint[vertexBufSize * 4 + 30];
+ mIntVertPool.push_back(mIntVertArray);
+ return mIntVertArray;
+}
+
+GLint *OpenGLGraphicsVertexes::switchIntTexArray()
+{
+ mIntTexArray = new GLint[vertexBufSize * 4 + 30];
+ mIntTexPool.push_back(mIntTexArray);
+ return mIntTexArray;
+}
+
+void OpenGLGraphicsVertexes::switchVp(int n)
+{
+ mVp.push_back(n);
+}
+
+GraphicsVertexes::GraphicsVertexes() :
+ mX(0), mY(0),
+ mW(0), mH(0),
+ mPtr(0)
+{
+}
+
+GraphicsVertexes::~GraphicsVertexes()
+{
+}
+
+void GraphicsVertexes::init(int x, int y, int w, int h)
+{
+ mPtr = 0;
+ mX = x;
+ mY = y;
+ mW = w;
+ mH = h;
+ for (int f = 0; f < 10; f ++)
+ {
+ sdl[mPtr].mList.clear();
+ ogl[mPtr].init();
+ }
+}
+
+void GraphicsVertexes::setLoadAsOpenGL(int useOpenGL)
+{
+ mUseOpenGL = useOpenGL;
+}
+
+void GraphicsVertexes::pushSDL(SDL_Rect r1, SDL_Rect r2)
+{
+ DoubleRect *r = new DoubleRect();
+ r->src = r1;
+ r->dst = r2;
+ sdl[mPtr].mList.push_back(r);
+}
+
+void GraphicsVertexes::clearSDL()
+{
+ sdl[mPtr].mList.clear();
+}
+
+std::list<DoubleRect*> *GraphicsVertexes::getRectsSDL()
+{
+ return &sdl[mPtr].mList;
+}
diff --git a/src/graphicsvertexes.h b/src/graphicsvertexes.h
new file mode 100644
index 000000000..1efb74f01
--- /dev/null
+++ b/src/graphicsvertexes.h
@@ -0,0 +1,155 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2011 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRAPHICSVERTEXES_H
+#define GRAPHICSVERTEXES_H
+
+
+#include "main.h"
+
+#include "graphics.h"
+
+#ifdef USE_OPENGL
+#define NO_SDL_GLEXT
+
+#include <SDL_opengl.h>
+#endif
+
+#include <string>
+#include <list>
+#include <vector>
+
+//include <guichan/sdl/sdlgraphics.hpp>
+
+
+struct DoubleRect
+{
+ SDL_Rect src;
+ SDL_Rect dst;
+};
+
+class SDLGraphicsVertexes
+{
+ public:
+ SDLGraphicsVertexes();
+
+ ~SDLGraphicsVertexes();
+
+ std::list<DoubleRect*> mList;
+};
+
+
+class OpenGL1GraphicsVertexes
+{
+};
+
+class OpenGLGraphicsVertexes
+{
+ public:
+ OpenGLGraphicsVertexes();
+
+ ~OpenGLGraphicsVertexes();
+
+ GLfloat *switchFloatTexArray();
+
+ GLint *switchIntVertArray();
+
+ GLint *switchIntTexArray();
+
+ void init();
+
+ void clear();
+
+ std::vector<GLfloat*> &getFloatTexPool()
+ { return mFloatTexPool; }
+
+ std::vector<GLint*> &getIntVertPool()
+ { return mIntVertPool; }
+
+ std::vector<GLint*> &getIntTexPool()
+ { return mIntTexPool; }
+
+ void switchVp(int n);
+
+ std::vector<int> &getVp()
+ { return mVp; }
+
+ private:
+ GLfloat *mFloatTexArray;
+ GLint *mIntTexArray;
+ GLint *mIntVertArray;
+ std::vector<GLfloat*> mFloatTexPool;
+ std::vector<GLint*> mIntVertPool;
+ std::vector<GLint*> mIntTexPool;
+ std::vector<int> mVp;
+};
+
+class GraphicsVertexes
+{
+ public:
+ GraphicsVertexes();
+
+ ~GraphicsVertexes();
+
+ static void setLoadAsOpenGL(int useOpenGL);
+
+ SDLGraphicsVertexes sdl[5];
+
+ OpenGL1GraphicsVertexes ogl1[5];
+
+ OpenGLGraphicsVertexes ogl[5];
+
+ void init(int x, int y, int w, int h);
+
+ void pushSDL(SDL_Rect r1, SDL_Rect r2);
+
+ void clearSDL();
+
+ std::list<DoubleRect*> *getRectsSDL();
+
+ void incPtr(int num = 1)
+ { mPtr += num; }
+
+ void setPtr(int num)
+ { mPtr = num; }
+
+ OpenGLGraphicsVertexes* getOGL()
+ { return &ogl[mPtr]; }
+
+ int getX()
+ { return mX; }
+
+ int getY()
+ { return mY; }
+
+ int getW()
+ { return mW; }
+
+ int getH()
+ { return mH; }
+
+ int mX, mY, mW, mH;
+ int mPtr;
+
+ private:
+ static int mUseOpenGL;
+};
+
+#endif // GRAPHICSVERTEXES_H
diff --git a/src/gui/widgets/button.cpp b/src/gui/widgets/button.cpp
index 89e270595..a8e8b656d 100644
--- a/src/gui/widgets/button.cpp
+++ b/src/gui/widgets/button.cpp
@@ -25,6 +25,7 @@
#include "client.h"
#include "configuration.h"
#include "graphics.h"
+#include "graphicsvertexes.h"
#include "log.h"
#include "gui/palette.h"
@@ -67,7 +68,12 @@ static ButtonData const data[BUTTON_COUNT] =
ImageRect Button::button[BUTTON_COUNT];
Button::Button():
- mDescription(""), mClickCount(0)
+ mDescription(""), mClickCount(0),
+ mVertexes(new GraphicsVertexes()),
+ mRedraw(true),
+ mMode(0),
+ mXOffset(0),
+ mYOffset(0)
{
init();
}
@@ -75,7 +81,9 @@ Button::Button():
Button::Button(const std::string &caption, const std::string &actionEventId,
gcn::ActionListener *listener):
gcn::Button(caption),
- mDescription(""), mClickCount(0)
+ mDescription(""), mClickCount(0),
+ mVertexes(new GraphicsVertexes()),
+ mRedraw(true)
{
init();
setActionEventId(actionEventId);
@@ -88,6 +96,8 @@ void Button::init()
{
setFrameSize(0);
+ addWidgetListener(this);
+
if (mInstances == 0)
{
// Load the skin
@@ -175,8 +185,44 @@ void Button::draw(gcn::Graphics *graphics)
updateAlpha();
- static_cast<Graphics*>(graphics)->
- drawImageRect(0, 0, getWidth(), getHeight(), button[mode]);
+
+ bool recalc = false;
+ if (mRedraw)
+ {
+ recalc = true;
+ }
+ else
+ {
+ // because we dont know where parent windows was moved,
+ // need recalc vertexes
+ gcn::ClipRectangle &rect = static_cast<Graphics*>(
+ graphics)->getTopClip();
+ if (rect.xOffset != mXOffset || rect.yOffset != mYOffset)
+ {
+ recalc = true;
+ mXOffset = rect.xOffset;
+ mYOffset = rect.yOffset;
+ }
+ else if (mMode != mode)
+ {
+ recalc = true;
+ mMode = mode;
+ }
+ }
+
+ if (recalc)
+ {
+ mRedraw = false;
+ mMode = mode;
+ static_cast<Graphics*>(graphics)->calcWindow(mVertexes, 0, 0,
+ getWidth(), getHeight(), button[mode]);
+ }
+
+ static_cast<Graphics*>(graphics)->drawImageRect2(
+ mVertexes, button[mode]);
+
+// static_cast<Graphics*>(graphics)->
+// drawImageRect(0, 0, getWidth(), getHeight(), button[mode]);
if (mode == BUTTON_DISABLED)
graphics->setColor(Theme::getThemeColor(Theme::BUTTON_DISABLED));
@@ -226,3 +272,13 @@ void Button::mouseReleased(gcn::MouseEvent& mouseEvent)
mouseEvent.consume();
}
}
+
+void Button::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ mRedraw = true;
+}
+
+void Button::widgetMoved(const gcn::Event &event _UNUSED_)
+{
+ mRedraw = true;
+}
diff --git a/src/gui/widgets/button.h b/src/gui/widgets/button.h
index e7446cd26..8c43b6ddd 100644
--- a/src/gui/widgets/button.h
+++ b/src/gui/widgets/button.h
@@ -25,7 +25,9 @@
#include <guichan/widgets/button.hpp>
#include <guichan/mouseevent.hpp>
+#include <guichan/widgetlistener.hpp>
+class GraphicsVertexes;
class ImageRect;
/**
@@ -33,7 +35,7 @@ class ImageRect;
*
* \ingroup GUI
*/
-class Button : public gcn::Button
+class Button : public gcn::Button, public gcn::WidgetListener
{
public:
/**
@@ -80,6 +82,10 @@ class Button : public gcn::Button
int getTag()
{ return mTag; }
+ void widgetResized(const gcn::Event &event);
+
+ void widgetMoved(const gcn::Event &event);
+
private:
void init();
@@ -90,6 +96,11 @@ class Button : public gcn::Button
std::string mDescription;
unsigned mClickCount;
int mTag;
+ GraphicsVertexes *mVertexes;
+ bool mRedraw;
+ int mMode;
+ int mXOffset;
+ int mYOffset;
};
#endif
diff --git a/src/gui/widgets/popup.cpp b/src/gui/widgets/popup.cpp
index 3d9c3b449..7519d1583 100644
--- a/src/gui/widgets/popup.cpp
+++ b/src/gui/widgets/popup.cpp
@@ -25,12 +25,14 @@
#include "configuration.h"
#include "graphics.h"
+#include "graphicsvertexes.h"
#include "log.h"
#include "gui/theme.h"
#include "gui/viewport.h"
#include "gui/widgets/windowcontainer.h"
+#include "gui/widgets/window.h"
#include "resources/image.h"
@@ -41,13 +43,17 @@ Popup::Popup(const std::string &name, const std::string &skin):
mMinWidth(100),
mMinHeight(40),
mMaxWidth(graphics->getWidth()),
- mMaxHeight(graphics->getHeight())
+ mMaxHeight(graphics->getHeight()),
+ mVertexes(new GraphicsVertexes()),
+ mRedraw(true)
{
logger->log("Popup::Popup(\"%s\")", name.c_str());
if (!windowContainer)
throw GCN_EXCEPTION("Popup::Popup(): no windowContainer set");
+ addWidgetListener(this);
+
setPadding(3);
// Loads the skin
@@ -64,6 +70,9 @@ Popup::~Popup()
{
logger->log("Popup::~Popup(\"%s\")", mPopupName.c_str());
+ delete mVertexes;
+ mVertexes = 0;
+
if (mSkin)
mSkin->instances--;
}
@@ -77,7 +86,16 @@ void Popup::draw(gcn::Graphics *graphics)
{
Graphics *g = static_cast<Graphics*>(graphics);
- g->drawImageRect(0, 0, getWidth(), getHeight(), mSkin->getBorder());
+ if (mRedraw)
+ {
+ mRedraw = false;
+ g->calcWindow(mVertexes, 0, 0, getWidth(),
+ getHeight(), mSkin->getBorder());
+ }
+
+ g->drawImageRect2(mVertexes, mSkin->getBorder());
+
+// g->drawImageRect(0, 0, getWidth(), getHeight(), mSkin->getBorder());
drawChildren(graphics);
}
@@ -103,6 +121,7 @@ void Popup::setContentSize(int width, int height)
height = getMaxHeight();
setSize(width, height);
+ mRedraw = true;
}
void Popup::setLocationRelativeTo(gcn::Widget *widget)
@@ -118,6 +137,7 @@ void Popup::setLocationRelativeTo(gcn::Widget *widget)
setPosition(getX() + (wx + (widget->getWidth() - getWidth()) / 2 - x),
getY() + (wy + (widget->getHeight() - getHeight()) / 2 - y));
+ mRedraw = true;
}
void Popup::setMinWidth(int width)
@@ -161,15 +181,28 @@ void Popup::position(int x, int y)
setPosition(posX, posY);
setVisible(true);
requestMoveToTop();
+ mRedraw = true;
}
void Popup::mouseMoved(gcn::MouseEvent &event _UNUSED_)
{
if (viewport)
viewport->hideBeingPopup();
+ mRedraw = true;
}
void Popup::hide()
{
setVisible(false);
-} \ No newline at end of file
+ mRedraw = true;
+}
+
+void Popup::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ mRedraw = true;
+}
+
+void Popup::widgetMoved(const gcn::Event &event _UNUSED_)
+{
+ mRedraw = true;
+}
diff --git a/src/gui/widgets/popup.h b/src/gui/widgets/popup.h
index 302e55656..963477fbb 100644
--- a/src/gui/widgets/popup.h
+++ b/src/gui/widgets/popup.h
@@ -30,6 +30,7 @@
#include "gui/widgets/container.h"
#include <guichan/mouselistener.hpp>
+#include <guichan/widgetlistener.hpp>
#ifdef __GNUC__
#define _UNUSED_ __attribute__ ((unused))
@@ -37,6 +38,7 @@
#define _UNUSED_
#endif
+class GraphicsVertexes;
class Skin;
class WindowContainer;
@@ -52,7 +54,8 @@ class WindowContainer;
*
* \ingroup GUI
*/
-class Popup : public Container, public gcn::MouseListener
+class Popup : public Container, public gcn::MouseListener,
+ public gcn::WidgetListener
{
public:
/**
@@ -161,6 +164,10 @@ class Popup : public Container, public gcn::MouseListener
void hide();
+ void widgetResized(const gcn::Event &event);
+
+ void widgetMoved(const gcn::Event &event);
+
private:
std::string mPopupName; /**< Name of the popup */
int mMinWidth; /**< Minimum popup width */
@@ -170,6 +177,8 @@ class Popup : public Container, public gcn::MouseListener
int mPadding; /**< Holds the padding of the popup. */
Skin *mSkin; /**< Skin in use by this popup */
+ GraphicsVertexes *mVertexes;
+ bool mRedraw;
};
#endif
diff --git a/src/gui/widgets/progressbar.cpp b/src/gui/widgets/progressbar.cpp
index c612ed36a..0916d9976 100644
--- a/src/gui/widgets/progressbar.cpp
+++ b/src/gui/widgets/progressbar.cpp
@@ -25,6 +25,7 @@
#include "client.h"
#include "configuration.h"
#include "graphics.h"
+#include "graphicsvertexes.h"
#include "textrenderer.h"
#include "gui/gui.h"
@@ -47,7 +48,9 @@ ProgressBar::ProgressBar(float progress,
gcn::Widget(),
mSmoothProgress(true),
mProgressPalette(color),
- mSmoothColorChange(true)
+ mSmoothColorChange(true),
+ mVertexes(new GraphicsVertexes()),
+ mRedraw(true)
{
// The progress value is directly set at load time:
if (progress > 1.0f || progress < 0.0f)
@@ -59,6 +62,8 @@ ProgressBar::ProgressBar(float progress,
mColor = Theme::getProgressColor(color >= 0 ? color : 0, mProgress);
mColorToGo = mColor;
+ addWidgetListener(this);
+
setSize(width, height);
if (mInstances == 0)
@@ -98,6 +103,8 @@ ProgressBar::~ProgressBar()
if (mInstances == 0)
for_each(mBorder.grid, mBorder.grid + 9, dtor<Image*>());
+ delete mVertexes;
+ mVertexes = 0;
}
void ProgressBar::logic()
@@ -157,7 +164,7 @@ void ProgressBar::draw(gcn::Graphics *graphics)
rect.y = 0;
render(static_cast<Graphics*>(graphics), rect, mColor,
- mProgress, mText);
+ mProgress, mText, mVertexes, &mRedraw);
}
void ProgressBar::setProgress(float progress)
@@ -191,6 +198,53 @@ void ProgressBar::setColor(const gcn::Color &color)
void ProgressBar::render(Graphics *graphics, const gcn::Rectangle &area,
const gcn::Color &color, float progress,
+ const std::string &text, GraphicsVertexes *vert,
+ bool *redraw)
+{
+ gcn::Font *oldFont = graphics->getFont();
+ gcn::Color oldColor = graphics->getColor();
+
+ if (*redraw)
+ {
+ *redraw = false;
+ static_cast<Graphics*>(graphics)->calcWindow(vert,
+ area.x, area.y, area.width, area.height, mBorder);
+ }
+
+ static_cast<Graphics*>(graphics)->drawImageRect2(vert, mBorder);
+
+// graphics->drawImageRect(area.x, area.y, area.width, area.height, mBorder);
+// graphics->drawImageRect(area, mBorder);
+
+ // The bar
+ if (progress > 0)
+ {
+ graphics->setColor(color);
+ graphics->fillRectangle(gcn::Rectangle(static_cast<int>(area.x + 4),
+ static_cast<int>(area.y + 4),
+ static_cast<int>(static_cast<float>(progress)
+ * static_cast<float>(area.width - 8)),
+ static_cast<int>(area.height - 8)));
+ }
+
+ // The label
+ if (!text.empty())
+ {
+ const int textX = area.x + area.width / 2;
+ const int textY = area.y + (area.height - boldFont->getHeight()) / 2;
+
+ TextRenderer::renderText(graphics, text, textX, textY,
+ gcn::Graphics::CENTER,
+ Theme::getThemeColor(Theme::PROGRESS_BAR),
+ gui->getFont(), true, false);
+ }
+
+ graphics->setFont(oldFont);
+ graphics->setColor(oldColor);
+}
+
+void ProgressBar::render(Graphics *graphics, const gcn::Rectangle &area,
+ const gcn::Color &color, float progress,
const std::string &text)
{
gcn::Font *oldFont = graphics->getFont();
@@ -224,3 +278,13 @@ void ProgressBar::render(Graphics *graphics, const gcn::Rectangle &area,
graphics->setFont(oldFont);
graphics->setColor(oldColor);
}
+
+void ProgressBar::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ mRedraw = true;
+}
+
+void ProgressBar::widgetMoved(const gcn::Event &event _UNUSED_)
+{
+ mRedraw = true;
+}
diff --git a/src/gui/widgets/progressbar.h b/src/gui/widgets/progressbar.h
index ba10f3027..52a26ddac 100644
--- a/src/gui/widgets/progressbar.h
+++ b/src/gui/widgets/progressbar.h
@@ -27,7 +27,10 @@
#include <string>
+#include <guichan/widgetlistener.hpp>
+
class Graphics;
+class GraphicsVertexes;
class ImageRect;
/**
@@ -35,7 +38,7 @@ class ImageRect;
*
* \ingroup GUI
*/
-class ProgressBar : public gcn::Widget
+class ProgressBar : public gcn::Widget, public gcn::WidgetListener
{
public:
/**
@@ -117,8 +120,20 @@ class ProgressBar : public gcn::Widget
*/
static void render(Graphics *graphics, const gcn::Rectangle &area,
const gcn::Color &color, float progress,
+ const std::string &text,
+ GraphicsVertexes *vert, bool *redraw);
+
+ /**
+ * Renders a progressbar with the given properties.
+ */
+ static void render(Graphics *graphics, const gcn::Rectangle &area,
+ const gcn::Color &color, float progress,
const std::string &text = "");
+ void widgetResized(const gcn::Event &event);
+
+ void widgetMoved(const gcn::Event &event);
+
private:
float mProgress, mProgressToGo;
bool mSmoothProgress;
@@ -129,6 +144,8 @@ class ProgressBar : public gcn::Widget
bool mSmoothColorChange;
std::string mText;
+ GraphicsVertexes *mVertexes;
+ bool mRedraw;
static ImageRect mBorder;
static int mInstances;
diff --git a/src/gui/widgets/scrollarea.cpp b/src/gui/widgets/scrollarea.cpp
index b11213239..2cc745ccd 100644
--- a/src/gui/widgets/scrollarea.cpp
+++ b/src/gui/widgets/scrollarea.cpp
@@ -25,6 +25,7 @@
#include "client.h"
#include "configuration.h"
#include "graphics.h"
+#include "graphicsvertexes.h"
#include "log.h"
#include "gui/theme.h"
@@ -45,7 +46,11 @@ ScrollArea::ScrollArea():
mX(0),
mY(0),
mHasMouse(false),
- mOpaque(true)
+ mOpaque(true),
+ mVertexes(new GraphicsVertexes()),
+ mRedraw(true),
+ mXOffset(0),
+ mYOffset(0)
{
addWidgetListener(this);
init();
@@ -56,8 +61,13 @@ ScrollArea::ScrollArea(gcn::Widget *widget):
mX(0),
mY(0),
mHasMouse(false),
- mOpaque(true)
+ mOpaque(true),
+ mVertexes(new GraphicsVertexes()),
+ mRedraw(true),
+ mXOffset(0),
+ mYOffset(0)
{
+ addWidgetListener(this);
init();
}
@@ -91,6 +101,8 @@ ScrollArea::~ScrollArea()
if (buttons[RIGHT][1])
buttons[RIGHT][1]->decRef();
}
+ delete mVertexes;
+ mVertexes = 0;
}
void ScrollArea::init()
@@ -286,6 +298,7 @@ void ScrollArea::draw(gcn::Graphics *graphics)
drawHMarker(graphics);
}
+
if (mHBarVisible && mVBarVisible)
{
graphics->setColor(getBaseColor());
@@ -300,6 +313,7 @@ void ScrollArea::draw(gcn::Graphics *graphics)
drawChildren(graphics);
}
+//void ScrollArea::drawFrame(gcn::Graphics *graphics _UNUSED_)
void ScrollArea::drawFrame(gcn::Graphics *graphics)
{
if (mOpaque)
@@ -308,8 +322,38 @@ void ScrollArea::drawFrame(gcn::Graphics *graphics)
const int w = getWidth() + bs * 2;
const int h = getHeight() + bs * 2;
+ bool recalc = false;
+ if (mRedraw)
+ {
+ recalc = true;
+ }
+ else
+ {
+ // because we dont know where parent windows was moved,
+ // need recalc vertexes
+ gcn::ClipRectangle &rect = static_cast<Graphics*>(
+ graphics)->getTopClip();
+ if (rect.xOffset != mXOffset || rect.yOffset != mYOffset)
+ {
+ recalc = true;
+ mXOffset = rect.xOffset;
+ mYOffset = rect.yOffset;
+ }
+ }
+
+ if (recalc)
+ {
+ mRedraw = false;
+ static_cast<Graphics*>(graphics)->calcWindow(
+ mVertexes, 0, 0, w, h, background);
+ }
+
+
static_cast<Graphics*>(graphics)->
- drawImageRect(0, 0, w, h, background);
+ drawImageRect2(mVertexes, background);
+
+// static_cast<Graphics*>(graphics)->
+// drawImageRect(0, 0, w, h, background);
}
}
@@ -441,6 +485,12 @@ void ScrollArea::mouseExited(gcn::MouseEvent& event _UNUSED_)
void ScrollArea::widgetResized(const gcn::Event &event _UNUSED_)
{
+ mRedraw = true;
getContent()->setSize(getWidth() - 2 * getFrameSize(),
getHeight() - 2 * getFrameSize());
}
+
+void ScrollArea::widgetMoved(const gcn::Event& event _UNUSED_)
+{
+ mRedraw = true;
+}
diff --git a/src/gui/widgets/scrollarea.h b/src/gui/widgets/scrollarea.h
index 49d5e7f28..e613170fa 100644
--- a/src/gui/widgets/scrollarea.h
+++ b/src/gui/widgets/scrollarea.h
@@ -32,6 +32,7 @@
#define _UNUSED_
#endif
+class GraphicsVertexes;
class Image;
class ImageRect;
@@ -113,6 +114,8 @@ class ScrollArea : public gcn::ScrollArea, public gcn::WidgetListener
void widgetResized(const gcn::Event &event);
+ void widgetMoved(const gcn::Event &event);
+
protected:
enum BUTTON_DIR
{
@@ -147,6 +150,10 @@ class ScrollArea : public gcn::ScrollArea, public gcn::WidgetListener
int mX, mY;
bool mHasMouse;
bool mOpaque;
+ GraphicsVertexes *mVertexes;
+ bool mRedraw;
+ int mXOffset;
+ int mYOffset;
};
#endif
diff --git a/src/gui/widgets/tab.cpp b/src/gui/widgets/tab.cpp
index 6a2b05cd4..78165dc18 100644
--- a/src/gui/widgets/tab.cpp
+++ b/src/gui/widgets/tab.cpp
@@ -25,6 +25,7 @@
#include "client.h"
#include "configuration.h"
#include "graphics.h"
+#include "graphicsvertexes.h"
#include "log.h"
#include "gui/palette.h"
@@ -68,7 +69,10 @@ static TabData const data[TAB_COUNT] =
ImageRect Tab::tabImg[TAB_COUNT];
Tab::Tab() : gcn::Tab(),
- mTabColor(&Theme::getThemeColor(Theme::TAB))
+ mTabColor(&Theme::getThemeColor(Theme::TAB)),
+ mVertexes(new GraphicsVertexes()),
+ mRedraw(true),
+ mMode(0)
{
init();
}
@@ -82,6 +86,8 @@ Tab::~Tab()
for (int mode = 0; mode < TAB_COUNT; mode++)
for_each(tabImg[mode].grid, tabImg[mode].grid + 9, dtor<Image*>());
}
+ delete mVertexes;
+ mVertexes = 0;
}
void Tab::init()
@@ -90,6 +96,8 @@ void Tab::init()
setFrameSize(0);
mFlash = 0;
+ addWidgetListener(this);
+
if (mInstances == 0)
{
// Load the skin
@@ -179,8 +187,18 @@ void Tab::draw(gcn::Graphics *graphics)
updateAlpha();
// draw tab
- static_cast<Graphics*>(graphics)->
- drawImageRect(0, 0, getWidth(), getHeight(), tabImg[mode]);
+ if (mRedraw || mode != mMode)
+ {
+ mMode = mode;
+ mRedraw = false;
+ static_cast<Graphics*>(graphics)->calcWindow(mVertexes, 0, 0, getWidth(),
+ getHeight(), tabImg[mode]);
+ }
+
+ static_cast<Graphics*>(graphics)->drawImageRect2(mVertexes, tabImg[mode]);
+
+// static_cast<Graphics*>(graphics)->
+// drawImageRect(0, 0, getWidth(), getHeight(), tabImg[mode]);
// draw label
drawChildren(graphics);
@@ -195,3 +213,13 @@ void Tab::setFlash(int flash)
{
mFlash = flash;
}
+
+void Tab::widgetResized(const gcn::Event &event _UNUSED_)
+{
+ mRedraw = true;
+}
+
+void Tab::widgetMoved(const gcn::Event &event _UNUSED_)
+{
+ mRedraw = true;
+}
diff --git a/src/gui/widgets/tab.h b/src/gui/widgets/tab.h
index 637234c89..f9f1fa4da 100644
--- a/src/gui/widgets/tab.h
+++ b/src/gui/widgets/tab.h
@@ -24,7 +24,9 @@
#define TAB_H
#include <guichan/widgets/tab.hpp>
+#include <guichan/widgetlistener.hpp>
+class GraphicsVertexes;
class ImageRect;
class TabbedArea;
@@ -32,7 +34,7 @@ class TabbedArea;
* A tab, the same as the Guichan tab in 0.8, but extended to allow
* transparency.
*/
-class Tab : public gcn::Tab
+class Tab : public gcn::Tab, public gcn::WidgetListener
{
public:
Tab();
@@ -61,6 +63,10 @@ class Tab : public gcn::Tab
int getFlash()
{ return mFlash; }
+ void widgetResized(const gcn::Event &event);
+
+ void widgetMoved(const gcn::Event &event);
+
protected:
friend class TabbedArea;
virtual void setCurrent()
@@ -76,6 +82,9 @@ class Tab : public gcn::Tab
const gcn::Color *mTabColor;
int mFlash;
+ GraphicsVertexes *mVertexes;
+ bool mRedraw;
+ int mMode;
};
#endif
diff --git a/src/gui/widgets/window.cpp b/src/gui/widgets/window.cpp
index 1037296b6..8c33b4787 100644
--- a/src/gui/widgets/window.cpp
+++ b/src/gui/widgets/window.cpp
@@ -24,6 +24,7 @@
#include "client.h"
#include "configuration.h"
+#include "graphicsvertexes.h"
#include "log.h"
#include "gui/gui.h"
@@ -60,7 +61,9 @@ Window::Window(const std::string &caption, bool modal, Window *parent,
mMinWinWidth(100),
mMinWinHeight(40),
mMaxWinWidth(graphics->getWidth()),
- mMaxWinHeight(graphics->getHeight())
+ mMaxWinHeight(graphics->getHeight()),
+ mVertexes(new GraphicsVertexes()),
+ mRedraw(true)
{
logger->log("Window::Window(\"%s\")", caption.c_str());
@@ -106,6 +109,8 @@ Window::~Window()
// need mWidgets.clean ?
removeWidgetListener(this);
+ delete mVertexes;
+ mVertexes = 0;
instances--;
@@ -125,7 +130,19 @@ void Window::draw(gcn::Graphics *graphics)
Graphics *g = static_cast<Graphics*>(graphics);
- g->drawImageRect(0, 0, getWidth(), getHeight(), mSkin->getBorder());
+ if (mRedraw)
+ {
+ mRedraw = false;
+ g->calcWindow(mVertexes, 0, 0, getWidth(),
+ getHeight(), mSkin->getBorder());
+ }
+
+ g->drawImageRect2(mVertexes, mSkin->getBorder());
+
+/*
+ g->drawImageRect(0, 0, getWidth(),
+ getHeight(), mSkin->getBorder());
+*/
// Draw title
if (mShowTitle)
@@ -303,12 +320,19 @@ void Window::widgetResized(const gcn::Event &event _UNUSED_)
getHeight() - mGrip->getHeight() - area.y);
}
+
if (mLayout)
{
int w = area.width;
int h = area.height;
mLayout->reflow(w, h);
}
+ mRedraw = true;
+}
+
+void Window::widgetMoved(const gcn::Event& event _UNUSED_)
+{
+ mRedraw = true;
}
void Window::widgetHidden(const gcn::Event &event _UNUSED_)
diff --git a/src/gui/widgets/window.h b/src/gui/widgets/window.h
index 4125f1986..6f856fc62 100644
--- a/src/gui/widgets/window.h
+++ b/src/gui/widgets/window.h
@@ -37,6 +37,7 @@
#endif
class ContainerPlacer;
+class GraphicsVertexes;
class Layout;
class LayoutCell;
class ResizeGrip;
@@ -114,6 +115,8 @@ class Window : public gcn::Window, gcn::WidgetListener
*/
void widgetResized(const gcn::Event &event);
+ virtual void widgetMoved(const gcn::Event& event);
+
/**
* Called whenever the widget is hidden.
*/
@@ -437,6 +440,8 @@ class Window : public gcn::Window, gcn::WidgetListener
* where two borders are moved at the same time.
*/
static const int resizeBorderWidth = 10;
+ GraphicsVertexes *mVertexes;
+ bool mRedraw;
};
#endif
diff --git a/src/opengl1graphics.cpp b/src/opengl1graphics.cpp
index 3dfe06ecf..e1d44de23 100644
--- a/src/opengl1graphics.cpp
+++ b/src/opengl1graphics.cpp
@@ -20,9 +20,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "log.h"
#include "opengl1graphics.h"
+#include "graphicsvertexes.h"
+#include "log.h"
+
#include "resources/image.h"
#ifdef USE_OPENGL
@@ -391,6 +393,29 @@ void OpenGL1Graphics::drawRescaledImagePattern(Image *image, int x, int y,
static_cast<GLubyte>(mColor.b), static_cast<GLubyte>(mColor.a));
}
+bool OpenGL1Graphics::calcImageRect(GraphicsVertexes* vert,
+ int x, int y, int w, int h,
+ Image *topLeft _UNUSED_,
+ Image *topRight _UNUSED_,
+ Image *bottomLeft _UNUSED_,
+ Image *bottomRight _UNUSED_,
+ Image *top _UNUSED_, Image *right _UNUSED_,
+ Image *bottom _UNUSED_,
+ Image *left _UNUSED_,
+ Image *center _UNUSED_)
+{
+ vert->init(x, y, w, h);
+ return true;
+}
+
+void OpenGL1Graphics::drawImageRect2(GraphicsVertexes* vert, const ImageRect &imgRect)
+{
+ drawImageRect(vert->getX(), vert->getY(), vert->getW(), vert->getH(),
+ 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 OpenGL1Graphics::updateScreen()
{
glFlush();
diff --git a/src/opengl1graphics.h b/src/opengl1graphics.h
index 04555e589..0c29ec1ca 100644
--- a/src/opengl1graphics.h
+++ b/src/opengl1graphics.h
@@ -91,6 +91,16 @@ class OpenGL1Graphics : public Graphics
int x, int y, int w, int h,
int scaledWidth, int scaledHeight);
+ bool calcImageRect(GraphicsVertexes* vert,
+ int x, int y, int w, int h,
+ Image *topLeft, Image *topRight,
+ Image *bottomLeft, Image *bottomRight,
+ Image *top, Image *right,
+ Image *bottom, Image *left,
+ Image *center);
+
+ void drawImageRect2(GraphicsVertexes* vert, const ImageRect &imgRect);
+
void updateScreen();
void _beginDraw();
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
index 302c895d0..f30d20666 100644
--- a/src/openglgraphics.cpp
+++ b/src/openglgraphics.cpp
@@ -24,8 +24,8 @@
#ifdef USE_OPENGL
+#include "graphicsvertexes.h"
#include "openglgraphics.h"
-
#include "log.h"
#include "resources/image.h"
@@ -617,6 +617,198 @@ void OpenGLGraphics::drawRescaledImagePattern(Image *image, int x, int y,
static_cast<GLubyte>(mColor.a));
}
+void OpenGLGraphics::drawImagePattern2(GraphicsVertexes *vert, Image *image)
+{
+ if (!image)
+ return;
+
+ OpenGLGraphicsVertexes *ogl = vert->getOGL();
+
+ glColor4f(1.0f, 1.0f, 1.0f, image->mAlpha);
+ bindTexture(Image::mTextureType, image->mGLImage);
+ setTexturingAndBlending(true);
+
+ std::vector<GLint*> &intVertPool = ogl->getIntVertPool();
+ std::vector<GLint*>::iterator iv;
+ std::vector<int> &vp = ogl->getVp();
+ std::vector<int>::iterator ivp;
+
+ // Draw a set of textured rectangles
+ if (image->getTextureType() == GL_TEXTURE_2D)
+ {
+ std::vector<GLfloat*> &floatTexPool = ogl->getFloatTexPool();
+ std::vector<GLfloat*>::iterator ft;
+
+ for (iv = intVertPool.begin(), ft = floatTexPool.begin(),
+ ivp = vp.begin();
+ iv != intVertPool.end(), ft != floatTexPool.end(),
+ ivp != vp.end();
+ ++ iv, ++ ft, ++ ivp)
+ {
+ drawQuadArrayfi(*iv, *ft, *ivp);
+ }
+ }
+ else
+ {
+ std::vector<GLint*> &intTexPool = ogl->getIntTexPool();
+ std::vector<GLint*>::iterator it;
+
+ for (iv = intVertPool.begin(), it = intTexPool.begin(),
+ ivp = vp.begin();
+ iv != intVertPool.end(), it != intTexPool.end(),
+ ivp != vp.end();
+ ++ iv, ++ it, ++ ivp)
+ {
+ drawQuadArrayii(*iv, *it, *ivp);
+ }
+ }
+
+ glColor4ub(static_cast<GLubyte>(mColor.r),
+ static_cast<GLubyte>(mColor.g),
+ static_cast<GLubyte>(mColor.b),
+ static_cast<GLubyte>(mColor.a));
+
+}
+
+void OpenGLGraphics::calcImagePattern(GraphicsVertexes* vert, Image *image,
+ int x, int y, int w, int h)
+{
+ if (!image)
+ {
+ vert->incPtr(1);
+ return;
+ }
+
+ const int srcX = image->mBounds.x;
+ const int srcY = image->mBounds.y;
+
+ const int iw = image->getWidth();
+ const int ih = image->getHeight();
+
+ if (iw == 0 || ih == 0)
+ {
+ vert->incPtr(1);
+ return;
+ }
+
+ const float tw = static_cast<float>(image->getTextureWidth());
+ const float th = static_cast<float>(image->getTextureHeight());
+
+ unsigned int vp = 0;
+ const unsigned int vLimit = vertexBufSize * 4;
+
+ OpenGLGraphicsVertexes *ogl = vert->getOGL();
+ ogl->init();
+
+ // Draw a set of textured rectangles
+ if (image->getTextureType() == GL_TEXTURE_2D)
+ {
+ float texX1 = static_cast<float>(srcX) / tw;
+ float texY1 = static_cast<float>(srcY) / th;
+
+ GLfloat *floatTexArray = ogl->switchFloatTexArray();
+ GLint *intVertArray = ogl->switchIntVertArray();
+
+ 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->switchIntTexArray();
+ GLint *intVertArray = ogl->switchIntVertArray();
+
+ 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);
+ vert->incPtr(1);
+}
+
void OpenGLGraphics::updateScreen()
{
glFlush();
@@ -930,6 +1122,15 @@ inline void OpenGLGraphics::drawQuadArrayfi(int size)
glDrawArrays(GL_QUADS, 0, size / 2);
}
+inline void OpenGLGraphics::drawQuadArrayfi(GLint *intVertArray,
+ GLfloat *floatTexArray, int size)
+{
+ glVertexPointer(2, GL_INT, 0, intVertArray);
+ glTexCoordPointer(2, GL_FLOAT, 0, floatTexArray);
+
+ glDrawArrays(GL_QUADS, 0, size / 2);
+}
+
inline void OpenGLGraphics::drawQuadArrayii(int size)
{
glVertexPointer(2, GL_INT, 0, mIntVertArray);
@@ -938,6 +1139,15 @@ inline void OpenGLGraphics::drawQuadArrayii(int size)
glDrawArrays(GL_QUADS, 0, size / 2);
}
+inline void OpenGLGraphics::drawQuadArrayii(GLint *intVertArray,
+ GLint *intTexArray, int size)
+{
+ glVertexPointer(2, GL_INT, 0, intVertArray);
+ glTexCoordPointer(2, GL_INT, 0, intTexArray);
+
+ glDrawArrays(GL_QUADS, 0, size / 2);
+}
+
inline void OpenGLGraphics::drawLineArrayi(int size)
{
glVertexPointer(2, GL_INT, 0, mIntVertArray);
diff --git a/src/openglgraphics.h b/src/openglgraphics.h
index 0eaaf0f18..c06f36228 100644
--- a/src/openglgraphics.h
+++ b/src/openglgraphics.h
@@ -91,6 +91,11 @@ class OpenGLGraphics : public Graphics
int x, int y, int w, int h,
int scaledWidth, int scaledHeight);
+ void calcImagePattern(GraphicsVertexes* vert, Image *image,
+ int x, int y, int w, int h);
+
+ void drawImagePattern2(GraphicsVertexes *vert, Image *image);
+
void updateScreen();
void _beginDraw();
@@ -115,8 +120,14 @@ class OpenGLGraphics : public Graphics
void drawQuadArrayfi(int size);
+ void drawQuadArrayfi(GLint *intVertArray, GLfloat *floatTexArray,
+ int size);
+
void drawQuadArrayii(int size);
+ void drawQuadArrayii(GLint *intVertArray, GLint *intTexArray,
+ int size);
+
void drawLineArrayi(int size);
void drawLineArrayf(int size);