summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2011-07-17 18:16:49 +0300
committerAndrei Karas <akaras@inbox.ru>2011-07-17 20:08:12 +0300
commit6afba95ef62b22c303336adba6d891eeffe66c49 (patch)
tree2e395c216f22479064ad5cf2bda612d8ecb9f201
parentb83bca17d42761c41f097ea315d01bb89105f618 (diff)
downloadmv-6afba95ef62b22c303336adba6d891eeffe66c49.tar.gz
mv-6afba95ef62b22c303336adba6d891eeffe66c49.tar.bz2
mv-6afba95ef62b22c303336adba6d891eeffe66c49.tar.xz
mv-6afba95ef62b22c303336adba6d891eeffe66c49.zip
Add basic tiles caching for opengl.
-rw-r--r--src/graphicsvertexes.cpp60
-rw-r--r--src/graphicsvertexes.h14
-rw-r--r--src/map.cpp61
-rw-r--r--src/opengl1graphics.cpp10
-rw-r--r--src/opengl1graphics.h4
-rw-r--r--src/openglgraphics.cpp187
-rw-r--r--src/openglgraphics.h4
7 files changed, 310 insertions, 30 deletions
diff --git a/src/graphicsvertexes.cpp b/src/graphicsvertexes.cpp
index d905b8b64..b8e236310 100644
--- a/src/graphicsvertexes.cpp
+++ b/src/graphicsvertexes.cpp
@@ -110,6 +110,62 @@ void OpenGLGraphicsVertexes::switchVp(int n)
{
mVp.push_back(n);
}
+
+int OpenGLGraphicsVertexes::continueVp()
+{
+ if (mVp.empty())
+ {
+ return 0;
+ }
+ else
+ {
+ const int val = mVp.back();
+ mVp.pop_back();
+ return val;
+ }
+}
+
+GLfloat *OpenGLGraphicsVertexes::continueFloatTexArray()
+{
+ if (mFloatTexPool.empty())
+ {
+ mFloatTexArray = new GLfloat[vertexBufSize * 4 + 30];
+ mFloatTexPool.push_back(mFloatTexArray);
+ }
+ else
+ {
+ mFloatTexArray = mFloatTexPool.back();
+ }
+ return mFloatTexArray;
+}
+
+GLint *OpenGLGraphicsVertexes::continueIntVertArray()
+{
+ if (mIntVertPool.empty())
+ {
+ mIntVertArray = new GLint[vertexBufSize * 4 + 30];
+ mIntVertPool.push_back(mIntVertArray);
+ }
+ else
+ {
+ mIntVertArray = mIntVertPool.back();
+ }
+ return mIntVertArray;
+}
+
+GLint *OpenGLGraphicsVertexes::continueIntTexArray()
+{
+ if (mIntTexPool.empty())
+ {
+ mIntTexArray = new GLint[vertexBufSize * 4 + 30];
+ mIntTexPool.push_back(mIntTexArray);
+ }
+ else
+ {
+ mIntTexArray = mIntTexPool.back();
+ }
+ return mIntTexArray;
+}
#endif
GraphicsVertexes::GraphicsVertexes() :
@@ -171,7 +227,7 @@ ImageVertexes::~ImageVertexes()
delete_all(sdl);
sdl.clear();
#ifdef USE_OPENGL
- delete_all(ogl);
- ogl.clear();
+ delete ogl;
+ ogl = 0;
#endif
}
diff --git a/src/graphicsvertexes.h b/src/graphicsvertexes.h
index 73346d08c..55740ac98 100644
--- a/src/graphicsvertexes.h
+++ b/src/graphicsvertexes.h
@@ -87,6 +87,14 @@ class OpenGLGraphicsVertexes
void switchVp(int n);
+ GLfloat *continueFloatTexArray();
+
+ GLint *continueIntVertArray();
+
+ GLint *continueIntTexArray();
+
+ int continueVp();
+
std::vector<int> *getVp()
{ return &mVp; }
@@ -110,7 +118,9 @@ typedef std::vector<DoubleRect*> DoubleRects;
class ImageVertexes
{
public:
- ImageVertexes() : image(0)
+ ImageVertexes() :
+ image(0),
+ ogl(new OpenGLGraphicsVertexes())
{ }
~ImageVertexes();
@@ -119,7 +129,7 @@ class ImageVertexes
DoubleRects sdl;
#ifdef USE_OPENGL
- std::vector<OpenGLGraphicsVertexes*> ogl;
+ OpenGLGraphicsVertexes *ogl;
#endif
};
diff --git a/src/map.cpp b/src/map.cpp
index c5a7a8816..d5d74f4df 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -239,13 +239,9 @@ void MapLayer::updateOGL(Graphics *graphics, int startX, int startY,
int endX, int endY, int scrollX, int scrollY,
int debugFlags)
{
+ delete_all(mTempRows);
+ mTempRows.clear();
-}
-
-void MapLayer::drawOGL(Graphics *graphics, int startX, int startY,
- int endX, int endY, int scrollX, int scrollY,
- int debugFlags)
-{
startX -= mX;
startY -= mY;
endX -= mX;
@@ -267,42 +263,56 @@ void MapLayer::drawOGL(Graphics *graphics, int startX, int startY,
for (int y = startY; y < endY; y++)
{
- const int y32 = y * 32;
- const int yWidth = y * mWidth;
+ MapRowVertexes *row = new MapRowVertexes();
+ mTempRows.push_back(row);
- const int py0 = y32 + dy;
+ Image *lastImage = 0;
+ ImageVertexes *imgVert = 0;
+
+ const int yWidth = y * mWidth;
+ const int py0 = y * 32 + dy;
for (int x = startX; x < endX; x++)
{
- const int x32 = x * 32;
-
const int tilePtr = x + yWidth;
- int c = 0;
Image *img = mTiles[tilePtr];
if (img)
{
- const int px = x32 + dx;
+ const int px = x * 32 + dx;
const int py = py0 - img->mBounds.h;
if (flag || img->mBounds.h <= 32)
{
- int width = 0;
- // here need not draw over player position
- c = getTileDrawWidth(tilePtr, endX - x, width);
-
- if (!c)
- {
- graphics->drawImage(img, px, py);
- }
- else
+ if (lastImage != img)
{
- graphics->drawImagePattern(img, px, py,
- width, img->mBounds.h);
+ imgVert = new ImageVertexes();
+ imgVert->image = img;
+ row->images.push_back(imgVert);
+ lastImage = img;
}
+ graphics->calcTile(imgVert, px, py);
}
}
+ }
+ }
+}
- x += c;
+void MapLayer::drawOGL(Graphics *graphics, int startX, int startY,
+ int endX, int endY, int scrollX, int scrollY,
+ int debugFlags)
+{
+ MapRows::iterator rit = mTempRows.begin();
+ MapRows::iterator rit_end = mTempRows.end();
+ while (rit != rit_end)
+ {
+ MepRowImages *images = &(*rit)->images;
+ MepRowImages::iterator iit = images->begin();
+ MepRowImages::iterator iit_end = images->end();
+ while (iit != iit_end)
+ {
+ graphics->drawTile(*iit);
+ ++ iit;
}
+ ++ rit;
}
}
@@ -743,7 +753,6 @@ void Map::draw(Graphics *graphics, int scrollX, int scrollY)
mLastScrollX = scrollX;
mLastScrollY = scrollY;
updateFlag = 2;
-// updateMapLayer(this, endX, endY, debugFlags);
}
if (mDebugFlags == MAP_SPECIAL3 || mDebugFlags == MAP_BLACKWHITE)
diff --git a/src/opengl1graphics.cpp b/src/opengl1graphics.cpp
index 0bba38522..beffb462e 100644
--- a/src/opengl1graphics.cpp
+++ b/src/opengl1graphics.cpp
@@ -414,6 +414,16 @@ bool OpenGL1Graphics::calcImageRect(GraphicsVertexes* vert,
return true;
}
+void OpenGL1Graphics::calcTile(ImageVertexes *vert, int x, int y)
+{
+
+}
+
+void OpenGL1Graphics::drawTile(ImageVertexes *vert)
+{
+
+}
+
void OpenGL1Graphics::drawImageRect2(GraphicsVertexes* vert,
const ImageRect &imgRect)
{
diff --git a/src/opengl1graphics.h b/src/opengl1graphics.h
index 05ec9f79b..3943a82fb 100644
--- a/src/opengl1graphics.h
+++ b/src/opengl1graphics.h
@@ -101,6 +101,10 @@ class OpenGL1Graphics : public Graphics
void drawImageRect2(GraphicsVertexes* vert, const ImageRect &imgRect);
+ void calcTile(ImageVertexes *vert, int x, int y);
+
+ void drawTile(ImageVertexes *vert);
+
void updateScreen();
void _beginDraw();
diff --git a/src/openglgraphics.cpp b/src/openglgraphics.cpp
index e27de66c5..5406f6040 100644
--- a/src/openglgraphics.cpp
+++ b/src/openglgraphics.cpp
@@ -811,6 +811,193 @@ void OpenGLGraphics::calcImagePattern(GraphicsVertexes* vert, Image *image,
vert->incPtr(1);
}
+void OpenGLGraphics::calcTile(ImageVertexes *vert, int x, int y)
+{
+ if (!vert)
+ return;
+
+ Image *image = vert->image;
+ const int srcX = image->mBounds.x;
+ const int srcY = image->mBounds.y;
+
+ const int iw = image->mBounds.w;
+ const int ih = image->mBounds.h;
+ const int w = iw;
+ const int h = ih;
+
+ if (iw == 0 || ih == 0)
+ return;
+
+ const float tw = static_cast<float>(image->getTextureWidth());
+ const float th = static_cast<float>(image->getTextureHeight());
+
+ const unsigned int vLimit = vertexBufSize * 4;
+
+ OpenGLGraphicsVertexes *ogl = vert->ogl;
+
+ unsigned int vp = ogl->continueVp();
+
+ // Draw a set of textured rectangles
+ if (image->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 OpenGLGraphics::drawTile(ImageVertexes *vert)
+{
+ if (!vert)
+ return;
+ Image *image = vert->image;
+
+ OpenGLGraphicsVertexes *ogl = vert->ogl;
+
+ 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->mTextureType == 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::updateScreen()
{
// glFlush();
diff --git a/src/openglgraphics.h b/src/openglgraphics.h
index 3fa08f290..12eb2d9f8 100644
--- a/src/openglgraphics.h
+++ b/src/openglgraphics.h
@@ -94,6 +94,10 @@ class OpenGLGraphics : public Graphics
void calcImagePattern(GraphicsVertexes* vert, Image *image,
int x, int y, int w, int h);
+ void calcTile(ImageVertexes *vert, int x, int y);
+
+ void drawTile(ImageVertexes *vert);
+
void drawImagePattern2(GraphicsVertexes *vert, Image *image);
void updateScreen();