diff options
author | Andrei Karas <akaras@inbox.ru> | 2011-07-17 18:16:49 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2011-07-17 20:08:12 +0300 |
commit | 6afba95ef62b22c303336adba6d891eeffe66c49 (patch) | |
tree | 2e395c216f22479064ad5cf2bda612d8ecb9f201 /src/openglgraphics.cpp | |
parent | b83bca17d42761c41f097ea315d01bb89105f618 (diff) | |
download | manaplus-6afba95ef62b22c303336adba6d891eeffe66c49.tar.gz manaplus-6afba95ef62b22c303336adba6d891eeffe66c49.tar.bz2 manaplus-6afba95ef62b22c303336adba6d891eeffe66c49.tar.xz manaplus-6afba95ef62b22c303336adba6d891eeffe66c49.zip |
Add basic tiles caching for opengl.
Diffstat (limited to 'src/openglgraphics.cpp')
-rw-r--r-- | src/openglgraphics.cpp | 187 |
1 files changed, 187 insertions, 0 deletions
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(); |