diff --git a/TODO b/TODO index 1f448fd0..3e235b7e 100644 --- a/TODO +++ b/TODO @@ -31,4 +31,9 @@ restore win32 platform set special types for g_configs like lists/point/size restore ctrl+g and keybindings create a class for reading binary files -handle corrupt errors in dat/spr \ No newline at end of file +handle corrupt errors in dat/spr + +use CoordsBuffer in font +cache into framebuffers +implement glbuffer for CoordsBuffer +use indices in CoordsBuffer \ No newline at end of file diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index ae51645f..4f55c7c0 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -146,6 +146,7 @@ SET(framework_SOURCES ${framework_SOURCES} ${CMAKE_CURRENT_LIST_DIR}/graphics/shader.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/shaderprogram.cpp ${CMAKE_CURRENT_LIST_DIR}/graphics/paintershaderprogram.cpp + ${CMAKE_CURRENT_LIST_DIR}/graphics/coordsbuffer.cpp # framework otml ${CMAKE_CURRENT_LIST_DIR}/otml/otmldocument.cpp diff --git a/src/framework/graphics/borderimage.cpp b/src/framework/graphics/borderimage.cpp index 9e5dd228..1f547c2b 100644 --- a/src/framework/graphics/borderimage.cpp +++ b/src/framework/graphics/borderimage.cpp @@ -133,67 +133,72 @@ BorderImagePtr BorderImage::loadFromOTML(const OTMLNodePtr& borderImageNode) void BorderImage::draw(const Rect& screenCoords) { //TODO: borderimage drawing could be optimized by caching the render into a texture - - Rect rectCoords; - Size centerSize = screenCoords.size() - m_bordersSize; - - // first the center - if(centerSize.area() > 0) { - rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width(), - screenCoords.top() + m_topBorderTexCoords.height(), - centerSize); - g_painter.drawRepeatedTexturedRect(rectCoords, m_texture, m_centerTexCoords); + if(screenCoords != m_cachedScreenCoords) { + m_cachedScreenCoords = screenCoords; + m_coordsBuffer.clear(); + + Rect rectCoords; + Size centerSize = screenCoords.size() - m_bordersSize; + + // first the center + if(centerSize.area() > 0) { + rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width(), + screenCoords.top() + m_topBorderTexCoords.height(), + centerSize); + m_coordsBuffer.addRepeatedRects(rectCoords, m_centerTexCoords); + } + + // top left corner + rectCoords = Rect(screenCoords.topLeft(), + m_topLeftCornerTexCoords.size()); + m_coordsBuffer.addRepeatedRects(rectCoords, m_topLeftCornerTexCoords); + + // top + rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width(), + screenCoords.topLeft().y, + centerSize.width(), + m_topBorderTexCoords.height()); + m_coordsBuffer.addRepeatedRects(rectCoords, m_topBorderTexCoords); + + + // top right corner + rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width() + centerSize.width(), + screenCoords.top(), + m_topRightCornerTexCoords.size()); + m_coordsBuffer.addRepeatedRects(rectCoords, m_topRightCornerTexCoords); + + // left + rectCoords = Rect(screenCoords.left(), + screenCoords.top() + m_topLeftCornerTexCoords.height(), + m_leftBorderTexCoords.width(), + centerSize.height()); + m_coordsBuffer.addRepeatedRects(rectCoords, m_leftBorderTexCoords); + + // right + rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width() + centerSize.width(), + screenCoords.top() + m_topRightCornerTexCoords.height(), + m_rightBorderTexCoords.width(), + centerSize.height()); + m_coordsBuffer.addRepeatedRects(rectCoords, m_rightBorderTexCoords); + + // bottom left corner + rectCoords = Rect(screenCoords.left(), + screenCoords.top() + m_topLeftCornerTexCoords.height() + centerSize.height(), + m_bottomLeftCornerTexCoords.size()); + m_coordsBuffer.addRepeatedRects(rectCoords, m_bottomLeftCornerTexCoords); + + // bottom + rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width(), + screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(), + centerSize.width(), + m_bottomBorderTexCoords.height()); + m_coordsBuffer.addRepeatedRects(rectCoords, m_bottomBorderTexCoords); + + // bottom right corner + rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width() + centerSize.width(), + screenCoords.top() + m_topRightCornerTexCoords.height() + centerSize.height(), + m_bottomRightCornerTexCoords.size()); + m_coordsBuffer.addRepeatedRects(rectCoords, m_bottomRightCornerTexCoords); } - - // top left corner - rectCoords = Rect(screenCoords.topLeft(), - m_topLeftCornerTexCoords.size()); - g_painter.drawTexturedRect(rectCoords, m_texture, m_topLeftCornerTexCoords); - - // top - rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width(), - screenCoords.topLeft().y, - centerSize.width(), - m_topBorderTexCoords.height()); - g_painter.drawRepeatedTexturedRect(rectCoords, m_texture, m_topBorderTexCoords); - - - // top right corner - rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width() + centerSize.width(), - screenCoords.top(), - m_topRightCornerTexCoords.size()); - g_painter.drawTexturedRect(rectCoords, m_texture, m_topRightCornerTexCoords); - - // left - rectCoords = Rect(screenCoords.left(), - screenCoords.top() + m_topLeftCornerTexCoords.height(), - m_leftBorderTexCoords.width(), - centerSize.height()); - g_painter.drawRepeatedTexturedRect(rectCoords, m_texture, m_leftBorderTexCoords); - - // right - rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width() + centerSize.width(), - screenCoords.top() + m_topRightCornerTexCoords.height(), - m_rightBorderTexCoords.width(), - centerSize.height()); - g_painter.drawRepeatedTexturedRect(rectCoords, m_texture, m_rightBorderTexCoords); - - // bottom left corner - rectCoords = Rect(screenCoords.left(), - screenCoords.top() + m_topLeftCornerTexCoords.height() + centerSize.height(), - m_bottomLeftCornerTexCoords.size()); - g_painter.drawTexturedRect(rectCoords, m_texture, m_bottomLeftCornerTexCoords); - - // bottom - rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width(), - screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(), - centerSize.width(), - m_bottomBorderTexCoords.height()); - g_painter.drawRepeatedTexturedRect(rectCoords, m_texture, m_bottomBorderTexCoords); - - // bottom right corner - rectCoords = Rect(screenCoords.left() + m_bottomLeftCornerTexCoords.width() + centerSize.width(), - screenCoords.top() + m_topRightCornerTexCoords.height() + centerSize.height(), - m_bottomRightCornerTexCoords.size()); - g_painter.drawTexturedRect(rectCoords, m_texture, m_bottomRightCornerTexCoords); + g_painter.drawTextureCoords(m_coordsBuffer, m_texture); } \ No newline at end of file diff --git a/src/framework/graphics/coordsbuffer.cpp b/src/framework/graphics/coordsbuffer.cpp new file mode 100644 index 00000000..a3068aa9 --- /dev/null +++ b/src/framework/graphics/coordsbuffer.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2010-2011 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "coordsbuffer.h" + +void CoordsBuffer::clear() +{ + m_destRects.reset(); + m_srcRects.reset(); + m_textureCoords.clear(); + m_vertexCoords.clear(); + m_updateCache = true; +} + +void CoordsBuffer::addRect(const Rect& dest) +{ + m_destRects << dest; + m_updateCache = true; +} + +void CoordsBuffer::addRect(const Rect& dest, const Rect& src) +{ + m_destRects << dest; + m_srcRects << src; + m_updateCache = true; +} + +void CoordsBuffer::addBoudingRect(const Rect& dest, int innerLineWidth) +{ + int left = dest.left(); + int right = dest.right(); + int top = dest.top(); + int bottom = dest.bottom(); + int width = dest.width(); + int height = dest.height(); + int w = innerLineWidth; + + addRect(Rect(left, top, width - w, w)); // top + addRect(Rect(right - w + 1, top, w, height - w)); // right + addRect(Rect(left + w, bottom - w + 1, width - w, w)); // bottom + addRect(Rect(left, top + w, w, height - w)); // left + m_updateCache = true; +} + +void CoordsBuffer::addRepeatedRects(const Rect& dest, const Rect& src) +{ + if(dest.isEmpty() || src.isEmpty()) + return; + + Rect virtualDest(0, 0, dest.size()); + for(int y = 0; y <= virtualDest.height(); y += src.height()) { + for(int x = 0; x <= virtualDest.width(); x += src.width()) { + Rect partialDest(x, y, src.size()); + Rect partialSrc(src); + + // partialCoords to screenCoords bottomRight + if(partialDest.bottom() > virtualDest.bottom()) { + partialSrc.setBottom(partialSrc.bottom() + (virtualDest.bottom() - partialDest.bottom())); + partialDest.setBottom(virtualDest.bottom()); + } + if(partialDest.right() > virtualDest.right()) { + partialSrc.setRight(partialSrc.right() + (virtualDest.right() - partialDest.right())); + partialDest.setRight(virtualDest.right()); + } + + partialDest.translate(dest.topLeft()); + m_destRects << partialDest; + m_srcRects << partialSrc; + } + } + m_updateCache = true; +} + +void CoordsBuffer::cacheVertexArrays() +{ + if(!m_updateCache) + return; + + int numDestRects = m_destRects.size(); + int numSrcRects = m_srcRects.size(); + m_vertexCoords.clear(); + m_textureCoords.clear(); + + for(int i=0;i + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef COORDSBUFFER_H +#define COORDSBUFFER_H + +#include "vertexarray.h" + +class CoordsBuffer +{ +public: + void clear(); + + // no texture + void addRect(const Rect& dest); + void addBoudingRect(const Rect& dest, int innerLineWidth); + + // textured + void addRect(const Rect& dest, const Rect& src); + void addRepeatedRects(const Rect& dest, const Rect& src); + + void cacheVertexArrays(); + + GLfloat *getVertexCoords() const { return m_vertexCoords.vertexArray(); } + GLfloat *getTextureCoords() const { return m_textureCoords.vertexArray(); } + int getVertexCount() const { return m_vertexCoords.vertexCount(); } + +private: + DataBuffer m_destRects; + DataBuffer m_srcRects; + VertexArray m_vertexCoords; + VertexArray m_textureCoords; + Boolean m_updateCache; +}; + +#endif diff --git a/src/framework/graphics/glbuffer.cpp b/src/framework/graphics/glbuffer.cpp new file mode 100644 index 00000000..7d6ddcc4 --- /dev/null +++ b/src/framework/graphics/glbuffer.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2010-2011 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "glbuffer.h" + diff --git a/src/framework/graphics/glbuffer.h b/src/framework/graphics/glbuffer.h new file mode 100644 index 00000000..ba31f943 --- /dev/null +++ b/src/framework/graphics/glbuffer.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2010-2011 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef GLBUFFER_H +#define GLBUFFER_H + +class GLBuffer +{ +}; + +#endif diff --git a/src/framework/graphics/image.cpp b/src/framework/graphics/image.cpp index e3e04fd0..fce2d55b 100644 --- a/src/framework/graphics/image.cpp +++ b/src/framework/graphics/image.cpp @@ -52,7 +52,13 @@ void Image::loadFromOTML(const OTMLNodePtr& imageNode) void Image::draw(const Rect& screenCoords) { - if(m_texture) { + if(!m_texture) + return; + + if(m_cachedScreenCoords != screenCoords) { + m_cachedScreenCoords = screenCoords; + m_coordsBuffer.clear(); + if(m_fixedRatio) { const Size& texSize = m_texture->getSize(); Size texCoordsSize = screenCoords.size(); @@ -63,12 +69,14 @@ void Image::draw(const Rect& screenCoords) else if(texSize.width() > texCoordsSize.width()) texCoordsOffset.x = (texSize.width() - texCoordsSize.width())/2; - g_painter.drawTexturedRect(screenCoords, m_texture, Rect(texCoordsOffset, texCoordsSize)); + m_coordsBuffer.addRect(screenCoords, Rect(texCoordsOffset, texCoordsSize)); } else { if(m_repeated) - g_painter.drawRepeatedTexturedRect(screenCoords, m_texture, m_textureCoords); + m_coordsBuffer.addRepeatedRects(screenCoords, m_textureCoords); else - g_painter.drawTexturedRect(screenCoords, m_texture, m_textureCoords); + m_coordsBuffer.addRect(screenCoords, m_textureCoords); } } + + g_painter.drawTextureCoords(m_coordsBuffer, m_texture); } diff --git a/src/framework/graphics/image.h b/src/framework/graphics/image.h index 61b884d4..ee09cf3e 100644 --- a/src/framework/graphics/image.h +++ b/src/framework/graphics/image.h @@ -24,6 +24,7 @@ #define IMAGE_H #include "declarations.h" +#include "coordsbuffer.h" #include @@ -41,6 +42,9 @@ protected: Rect m_textureCoords; bool m_fixedRatio; bool m_repeated; + + Rect m_cachedScreenCoords; + CoordsBuffer m_coordsBuffer; }; #endif diff --git a/src/framework/graphics/painter.cpp b/src/framework/graphics/painter.cpp index 207f2da4..f156bcd7 100644 --- a/src/framework/graphics/painter.cpp +++ b/src/framework/graphics/painter.cpp @@ -26,6 +26,7 @@ #include "paintershaderprogram.h" #include "shaderprogram.h" #include "graphics.h" +#include "vertexarray.h" Painter g_painter; @@ -94,63 +95,63 @@ void Painter::updateProjectionMatrix(const Size& viewportSize, bool inverseYAxis } } -void Painter::drawTexturedRect(const Rect& dest, const TexturePtr& texture) +void Painter::drawCoords(CoordsBuffer& coordsBuffer) { - drawTexturedRect(dest, texture, Rect(Point(0,0), texture->getSize())); -} + coordsBuffer.cacheVertexArrays(); -void Painter::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) -{ - if(dest.isEmpty() || src.isEmpty() || !texture->getId()) + if(coordsBuffer.getVertexCount() < 3) return; - GLfloat vertexCoords[] = { (float)dest.left(), (float)dest.top(), - (float)dest.right()+1, (float)dest.top(), - (float)dest.left(), (float)dest.bottom()+1, - (float)dest.right()+1, (float)dest.bottom()+1 }; + m_drawSolidColorProgram->prepareForDraw(); + m_drawSolidColorProgram->setProjectionMatrix(m_projectionMatrix); + m_drawSolidColorProgram->setOpacity(m_currentOpacity); + m_drawSolidColorProgram->setColor(m_currentColor); + m_drawSolidColorProgram->setVertexCoords(coordsBuffer.getVertexCoords()); + m_drawSolidColorProgram->drawTriangles(coordsBuffer.getVertexCount()); + m_drawSolidColorProgram->releaseFromDraw(); +} - GLfloat textureCoords[] = { (float)src.left(), (float)src.top(), - (float)src.right()+1, (float)src.top(), - (float)src.left(), (float)src.bottom()+1, - (float)src.right()+1, (float)src.bottom()+1 }; +void Painter::drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture) +{ + coordsBuffer.cacheVertexArrays(); + + if(coordsBuffer.getVertexCount() < 3) + return; m_drawTexturedProgram->prepareForDraw(); m_drawTexturedProgram->setProjectionMatrix(m_projectionMatrix); m_drawTexturedProgram->setOpacity(m_currentOpacity); m_drawTexturedProgram->setColor(m_currentColor); m_drawTexturedProgram->setTexture(texture); - m_drawTexturedProgram->setVertexCoords(vertexCoords); - m_drawTexturedProgram->setTextureCoords(textureCoords); - m_drawTexturedProgram->drawTriangleStrip(4); + m_drawTexturedProgram->setVertexCoords(coordsBuffer.getVertexCoords()); + m_drawTexturedProgram->setTextureCoords(coordsBuffer.getTextureCoords()); + m_drawTexturedProgram->drawTriangles(coordsBuffer.getVertexCount()); m_drawTexturedProgram->releaseFromDraw(); } +void Painter::drawTexturedRect(const Rect& dest, const TexturePtr& texture) +{ + drawTexturedRect(dest, texture, Rect(Point(0,0), texture->getSize())); +} + +void Painter::drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) +{ + if(dest.isEmpty() || src.isEmpty() || !texture->getId()) + return; + + m_coordsBuffer.clear(); + m_coordsBuffer.addRect(dest, src); + drawTextureCoords(m_coordsBuffer, texture); +} + void Painter::drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src) { if(dest.isEmpty() || src.isEmpty() || !texture->getId()) return; - //TODO: use vertex arrays.. - Rect virtualDest(0, 0, dest.size()); - for(int y = 0; y <= virtualDest.height(); y += src.height()) { - for(int x = 0; x <= virtualDest.width(); x += src.width()) { - Rect partialDest(x, y, src.size()); - Rect partialSrc = src; - - // partialCoords to screenCoords bottomRight - if(partialDest.bottom() > virtualDest.bottom()) { - partialSrc.setBottom(partialSrc.bottom() + (virtualDest.bottom() - partialDest.bottom())); - partialDest.setBottom(virtualDest.bottom()); - } - if(partialDest.right() > virtualDest.right()) { - partialSrc.setRight(partialSrc.right() + (virtualDest.right() - partialDest.right())); - partialDest.setRight(virtualDest.right()); - } - - partialDest.translate(dest.topLeft()); - drawTexturedRect(partialDest, texture, partialSrc); - } - } + m_coordsBuffer.clear(); + m_coordsBuffer.addRepeatedRects(dest, src); + drawTextureCoords(m_coordsBuffer, texture); } void Painter::drawFilledRect(const Rect& dest) @@ -158,23 +159,9 @@ void Painter::drawFilledRect(const Rect& dest) if(dest.isEmpty()) return; - GLfloat right = dest.right()+1; - GLfloat bottom = dest.bottom()+1; - GLfloat top = dest.top(); - GLfloat left = dest.left(); - - GLfloat vertexCoords[] = { left, top, - right, top, - left, bottom, - right, bottom }; - - m_drawSolidColorProgram->prepareForDraw(); - m_drawSolidColorProgram->setProjectionMatrix(m_projectionMatrix); - m_drawSolidColorProgram->setOpacity(m_currentOpacity); - m_drawSolidColorProgram->setColor(m_currentColor); - m_drawSolidColorProgram->setVertexCoords(vertexCoords); - m_drawSolidColorProgram->drawTriangleStrip(4); - m_drawSolidColorProgram->releaseFromDraw(); + m_coordsBuffer.clear(); + m_coordsBuffer.addRect(dest); + drawCoords(m_coordsBuffer); } void Painter::drawBoundingRect(const Rect& dest, int innerLineWidth) @@ -182,33 +169,9 @@ void Painter::drawBoundingRect(const Rect& dest, int innerLineWidth) if(dest.isEmpty() || innerLineWidth == 0) return; - GLfloat right = dest.right()+1; - GLfloat bottom = dest.bottom()+1; - GLfloat top = dest.top(); - GLfloat left = dest.left(); - GLfloat w = innerLineWidth; - - GLfloat vertexCoords[] = { left, top, - right, top, - left, top+w, - right, top+w, - right-w, top+w, - right, bottom, - right-w, bottom, - right-w, bottom-w, - left, bottom, - left, bottom-w, - left+w, bottom-w, - left, top+w, - left+w, top+w }; - - m_drawSolidColorProgram->prepareForDraw(); - m_drawSolidColorProgram->setProjectionMatrix(m_projectionMatrix); - m_drawSolidColorProgram->setOpacity(m_currentOpacity); - m_drawSolidColorProgram->setColor(m_currentColor); - m_drawSolidColorProgram->setVertexCoords(vertexCoords); - m_drawSolidColorProgram->drawTriangleStrip(13); - m_drawSolidColorProgram->releaseFromDraw(); + m_coordsBuffer.clear(); + m_coordsBuffer.addBoudingRect(dest, innerLineWidth); + drawCoords(m_coordsBuffer); } void Painter::setCompositionMode(Painter::CompositionMode compositionMode) diff --git a/src/framework/graphics/painter.h b/src/framework/graphics/painter.h index b336d90c..10652974 100644 --- a/src/framework/graphics/painter.h +++ b/src/framework/graphics/painter.h @@ -24,6 +24,8 @@ #define PAINTER_H #include "declarations.h" +#include +#include "coordsbuffer.h" class Painter { @@ -37,6 +39,10 @@ public: void terminate(); void updateProjectionMatrix(const Size& viewportSize, bool inverseYAxis = false); + + void drawCoords(CoordsBuffer& coordsBuffer); + void drawTextureCoords(CoordsBuffer& coordsBuffer, const TexturePtr& texture); + void drawTexturedRect(const Rect& dest, const TexturePtr& texture); void drawTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); void drawRepeatedTexturedRect(const Rect& dest, const TexturePtr& texture, const Rect& src); @@ -57,6 +63,7 @@ private: GLfloat m_projectionMatrix[3][3]; Color m_currentColor; GLfloat m_currentOpacity; + CoordsBuffer m_coordsBuffer; }; extern Painter g_painter; diff --git a/src/framework/graphics/paintershaderprogram.cpp b/src/framework/graphics/paintershaderprogram.cpp index 645078e2..2fd9fa6f 100644 --- a/src/framework/graphics/paintershaderprogram.cpp +++ b/src/framework/graphics/paintershaderprogram.cpp @@ -83,6 +83,11 @@ void PainterShaderProgram::drawTriangleStrip(int numVertices) glDrawArrays(GL_TRIANGLE_STRIP, 0, numVertices); } +void PainterShaderProgram::drawTriangles(int numVertices) +{ + glDrawArrays(GL_TRIANGLES, 0, numVertices); +} + void PainterShaderProgram::releaseFromDraw() { if(m_mustDisableTexCoordsArray) { diff --git a/src/framework/graphics/paintershaderprogram.h b/src/framework/graphics/paintershaderprogram.h index 74bb728e..f7d9d409 100644 --- a/src/framework/graphics/paintershaderprogram.h +++ b/src/framework/graphics/paintershaderprogram.h @@ -47,6 +47,7 @@ public: void prepareForDraw(); void drawTriangleStrip(int numVertices); + void drawTriangles(int numVertices); void releaseFromDraw(); private: diff --git a/src/framework/graphics/texture.cpp b/src/framework/graphics/texture.cpp index acb1034e..2ce5dc7c 100644 --- a/src/framework/graphics/texture.cpp +++ b/src/framework/graphics/texture.cpp @@ -132,7 +132,7 @@ std::vector Texture::getPixels() // copy pixels from opengl memory std::vector pixels(m_glSize.area()*4, 0); glBindTexture(GL_TEXTURE_2D, m_textureId); - //glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]); + glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]); // convert pixels to the real texture size if(m_size != m_glSize) diff --git a/src/framework/graphics/textureglyphcache.cpp b/src/framework/graphics/textureglyphcache.cpp new file mode 100644 index 00000000..6a5c7d47 --- /dev/null +++ b/src/framework/graphics/textureglyphcache.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2010-2011 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "textureglyphcache.h" + diff --git a/src/framework/graphics/textureglyphcache.h b/src/framework/graphics/textureglyphcache.h new file mode 100644 index 00000000..15833249 --- /dev/null +++ b/src/framework/graphics/textureglyphcache.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2010-2011 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef TEXTUREGLYPHCACHE_H +#define TEXTUREGLYPHCACHE_H + +class TextureGlyphCache +{ +}; + +#endif diff --git a/src/framework/graphics/vertexarray.h b/src/framework/graphics/vertexarray.h new file mode 100644 index 00000000..ce31ff34 --- /dev/null +++ b/src/framework/graphics/vertexarray.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2010-2011 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef VERTEXARRAY_H +#define VERTEXARRAY_H + +#include "declarations.h" +#include + +class VertexArray +{ +public: + inline void addVertex(GLfloat x, GLfloat y) { m_buffer << x << y; } + inline void addRect(const Rect& rect) { + GLfloat top = rect.top(); + GLfloat right = rect.right()+1; + GLfloat bottom = rect.bottom()+1; + GLfloat left = rect.left(); + + addVertex(left, top); + addVertex(right, top); + addVertex(left, bottom); + addVertex(left, bottom); + addVertex(right, top); + addVertex(right, bottom); + } + + inline void addQuad(const Rect& rect) { + GLfloat top = rect.top(); + GLfloat right = rect.right()+1; + GLfloat bottom = rect.bottom()+1; + GLfloat left = rect.left(); + + addVertex(left, top); + addVertex(right, top); + addVertex(left, bottom); + addVertex(right, bottom); + } + + void clear() { m_buffer.reset(); } + GLfloat *vertexArray() const { return m_buffer.data(); } + int vertexCount() const { return m_buffer.size() / 2; } + +private: + DataBuffer m_buffer; +}; + +#endif diff --git a/src/framework/util/databuffer.h b/src/framework/util/databuffer.h new file mode 100644 index 00000000..56b88a44 --- /dev/null +++ b/src/framework/util/databuffer.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2010-2011 OTClient + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef DATABUFFER_H +#define DATABUFFER_H + +template +class DataBuffer +{ +public: + DataBuffer(int res = 64) { + m_capacity = res; + m_buffer = new T[m_capacity]; + m_size = 0; + } + ~DataBuffer() { delete[] m_buffer; } + + inline void reset() { m_size = 0; } + inline bool isEmpty() const { return m_size == 0; } + + inline int size() const { return m_size; } + inline T *data() const { return m_buffer; } + + inline const T& at(int i) const { return m_buffer[i]; } + inline const T& last() const { return m_buffer[m_size-1]; } + inline const T& first() const { return m_buffer[0]; } + inline const T& operator[](int i) const { return m_buffer[i]; } + inline T& operator[](int i) { return m_buffer[i]; } + + inline void add(const T &t) { + if(m_size >= m_capacity) { + m_capacity *= 2; + T *buffer = new T[m_capacity]; + for(int i=0;i