From 6afba95ef62b22c303336adba6d891eeffe66c49 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 17 Jul 2011 18:16:49 +0300 Subject: Add basic tiles caching for opengl. --- src/graphicsvertexes.cpp | 60 ++++++++++++++- src/graphicsvertexes.h | 14 +++- src/map.cpp | 61 +++++++++------- src/opengl1graphics.cpp | 10 +++ src/opengl1graphics.h | 4 + src/openglgraphics.cpp | 187 +++++++++++++++++++++++++++++++++++++++++++++++ src/openglgraphics.h | 4 + 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 *getVp() { return &mVp; } @@ -110,7 +118,9 @@ typedef std::vector 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 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(image->getTextureWidth()); + const float th = static_cast(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(srcX) / tw; + float texY1 = static_cast(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(srcX + width) / tw; + float texY2 = static_cast(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 *intVertPool = ogl->getIntVertPool(); + std::vector::iterator iv; + std::vector *vp = ogl->getVp(); + std::vector::iterator ivp; + + // Draw a set of textured rectangles + if (image->mTextureType == GL_TEXTURE_2D) + { + std::vector *floatTexPool = ogl->getFloatTexPool(); + std::vector::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 *intTexPool = ogl->getIntTexPool(); + std::vector::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(mColor.r), + static_cast(mColor.g), + static_cast(mColor.b), + static_cast(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(); -- cgit v1.2.3-60-g2f50