From 8403dcf857c9cc639e8162edd5d4df4af07274bc Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 26 Mar 2011 05:07:12 +0200 Subject: 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. --- src/openglgraphics.cpp | 212 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 211 insertions(+), 1 deletion(-) (limited to 'src/openglgraphics.cpp') 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(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 &intVertPool = ogl->getIntVertPool(); + std::vector::iterator iv; + std::vector &vp = ogl->getVp(); + std::vector::iterator ivp; + + // Draw a set of textured rectangles + if (image->getTextureType() == 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::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(image->getTextureWidth()); + const float th = static_cast(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(srcX) / tw; + float texY1 = static_cast(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(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->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); -- cgit v1.2.3-60-g2f50