many graphics performance tweaks
* use hardware vertex buffers (video memory) * cache text drawing with vertex buffers instead of framebuffers * avoid recalculating texture transformation matrix
This commit is contained in:
parent
b4261a8c7b
commit
5c35938a92
|
@ -22,26 +22,21 @@
|
|||
|
||||
#include "coordsbuffer.h"
|
||||
|
||||
void CoordsBuffer::clear()
|
||||
CoordsBuffer::CoordsBuffer()
|
||||
{
|
||||
m_destRects.reset();
|
||||
m_srcRects.reset();
|
||||
m_textureCoords.clear();
|
||||
m_vertices.clear();
|
||||
m_updateCache = true;
|
||||
m_hardwareCacheMode = HardwareBuffer::DynamicDraw;
|
||||
m_hardwareVertexBuffer = nullptr;
|
||||
m_hardwareTextureVertexBuffer = nullptr;
|
||||
m_hardwareCached = false;
|
||||
m_hardwareCaching = false;
|
||||
}
|
||||
|
||||
void CoordsBuffer::addRect(const Rect& dest)
|
||||
CoordsBuffer::~CoordsBuffer()
|
||||
{
|
||||
m_destRects << dest;
|
||||
m_updateCache = true;
|
||||
}
|
||||
|
||||
void CoordsBuffer::addRect(const Rect& dest, const Rect& src)
|
||||
{
|
||||
m_destRects << dest;
|
||||
m_srcRects << src;
|
||||
m_updateCache = true;
|
||||
if(m_hardwareVertexBuffer)
|
||||
delete m_hardwareVertexBuffer;
|
||||
if(m_hardwareTextureVertexBuffer)
|
||||
delete m_hardwareTextureVertexBuffer;
|
||||
}
|
||||
|
||||
void CoordsBuffer::addBoudingRect(const Rect& dest, int innerLineWidth)
|
||||
|
@ -58,7 +53,6 @@ void CoordsBuffer::addBoudingRect(const Rect& dest, int innerLineWidth)
|
|||
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)
|
||||
|
@ -83,28 +77,38 @@ void CoordsBuffer::addRepeatedRects(const Rect& dest, const Rect& src)
|
|||
}
|
||||
|
||||
partialDest.translate(dest.topLeft());
|
||||
m_destRects << partialDest;
|
||||
m_srcRects << partialSrc;
|
||||
m_vertexBuffer.addRect(partialDest);
|
||||
m_textureVertexBuffer.addRect(partialSrc);
|
||||
}
|
||||
}
|
||||
m_updateCache = true;
|
||||
m_hardwareCached = false;
|
||||
}
|
||||
|
||||
void CoordsBuffer::cacheVertexArrays()
|
||||
void CoordsBuffer::enableHardwareCaching(HardwareBuffer::UsagePattern usagePattern)
|
||||
{
|
||||
if(!m_updateCache)
|
||||
m_hardwareCacheMode = usagePattern;
|
||||
m_hardwareCaching = true;
|
||||
m_hardwareCached = false;
|
||||
}
|
||||
|
||||
void CoordsBuffer::updateCaches()
|
||||
{
|
||||
if(!m_hardwareCaching || m_hardwareCached)
|
||||
return;
|
||||
|
||||
int numDestRects = m_destRects.size();
|
||||
int numSrcRects = m_srcRects.size();
|
||||
m_vertices.clear();
|
||||
m_textureCoords.clear();
|
||||
|
||||
for(register int i=0;i<numDestRects;++i) {
|
||||
m_vertices.addRect(m_destRects[i]);
|
||||
if(numSrcRects == numDestRects)
|
||||
m_textureCoords.addRect(m_srcRects[i]);
|
||||
if(m_vertexBuffer.vertexCount() > 0) {
|
||||
if(!m_hardwareVertexBuffer && m_vertexBuffer.vertexCount() > 0)
|
||||
m_hardwareVertexBuffer = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
||||
m_hardwareVertexBuffer->bind();
|
||||
m_hardwareVertexBuffer->write((void*)m_vertexBuffer.vertices(), m_vertexBuffer.size() * sizeof(float), m_hardwareCacheMode);
|
||||
}
|
||||
|
||||
m_updateCache = false;
|
||||
if(m_textureVertexBuffer.vertexCount() > 0) {
|
||||
if(!m_hardwareTextureVertexBuffer && m_textureVertexBuffer.vertexCount() > 0)
|
||||
m_hardwareTextureVertexBuffer = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
||||
m_hardwareTextureVertexBuffer->bind();
|
||||
m_hardwareTextureVertexBuffer->write((void*)m_textureVertexBuffer.vertices(), m_textureVertexBuffer.size() * sizeof(float), m_hardwareCacheMode);
|
||||
}
|
||||
|
||||
m_hardwareCached = true;
|
||||
}
|
||||
|
|
|
@ -24,33 +24,53 @@
|
|||
#define COORDSBUFFER_H
|
||||
|
||||
#include "vertexarray.h"
|
||||
#include "hardwarebuffer.h"
|
||||
|
||||
class CoordsBuffer
|
||||
{
|
||||
public:
|
||||
void clear();
|
||||
CoordsBuffer();
|
||||
~CoordsBuffer();
|
||||
|
||||
void clear() {
|
||||
m_textureVertexBuffer.clear();
|
||||
m_vertexBuffer.clear();
|
||||
m_hardwareCached = false;
|
||||
}
|
||||
|
||||
void addRect(const Rect& dest) {
|
||||
m_vertexBuffer.addRect(dest);
|
||||
m_hardwareCached = false;
|
||||
}
|
||||
void addRect(const Rect& dest, const Rect& src) {
|
||||
m_vertexBuffer.addRect(dest);
|
||||
m_textureVertexBuffer.addRect(src);
|
||||
m_hardwareCached = false;
|
||||
}
|
||||
|
||||
// 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();
|
||||
void enableHardwareCaching(HardwareBuffer::UsagePattern usagePattern = HardwareBuffer::DynamicDraw);
|
||||
void updateCaches();
|
||||
bool isHardwareCached() { return m_hardwareCached; }
|
||||
|
||||
float *getVertices() const { return m_vertices.vertices(); }
|
||||
float *getTextureCoords() const { return m_textureCoords.vertices(); }
|
||||
int getVertexCount() const { return m_vertices.vertexCount(); }
|
||||
int getTextureCoordsCount() const { return m_textureCoords.vertexCount(); }
|
||||
float *getVertexBuffer() const { return m_vertexBuffer.vertices(); }
|
||||
float *getTextureVertexBuffer() const { return m_textureVertexBuffer.vertices(); }
|
||||
int getVertexCount() const { return m_vertexBuffer.vertexCount(); }
|
||||
int getTextureVertexCount() const { return m_textureVertexBuffer.vertexCount(); }
|
||||
|
||||
HardwareBuffer *getHardwareVertexBuffer() { return m_hardwareVertexBuffer; }
|
||||
HardwareBuffer *getHardwareTextureVertexBuffer() { return m_hardwareTextureVertexBuffer; }
|
||||
|
||||
private:
|
||||
DataBuffer<Rect> m_destRects;
|
||||
DataBuffer<Rect> m_srcRects;
|
||||
VertexArray m_vertices;
|
||||
VertexArray m_textureCoords;
|
||||
Boolean<true> m_updateCache;
|
||||
HardwareBuffer *m_hardwareVertexBuffer;
|
||||
HardwareBuffer *m_hardwareTextureVertexBuffer;
|
||||
HardwareBuffer::UsagePattern m_hardwareCacheMode;
|
||||
VertexArray m_vertexBuffer;
|
||||
VertexArray m_textureVertexBuffer;
|
||||
bool m_hardwareCached;
|
||||
bool m_hardwareCaching;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,20 +61,23 @@ void Font::load(const OTMLNodePtr& fontNode)
|
|||
}
|
||||
}
|
||||
|
||||
void Font::renderText(const std::string& text,
|
||||
const Point& startPos,
|
||||
const Color& color)
|
||||
void Font::drawText(const std::string& text, const Point& startPos)
|
||||
{
|
||||
Size boxSize = g_graphics.getViewportSize() - startPos.toSize();
|
||||
Rect screenCoords(startPos, boxSize);
|
||||
renderText(text, screenCoords, Fw::AlignTopLeft, color);
|
||||
drawText(text, screenCoords, Fw::AlignTopLeft);
|
||||
}
|
||||
|
||||
void Font::drawText(const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align)
|
||||
{
|
||||
static CoordsBuffer coordsBuffer;
|
||||
coordsBuffer.clear();
|
||||
|
||||
void Font::renderText(const std::string& text,
|
||||
const Rect& screenCoords,
|
||||
Fw::AlignmentFlag align,
|
||||
const Color& color)
|
||||
calculateDrawTextCoords(coordsBuffer, text, screenCoords, align);
|
||||
g_painter.drawTextureCoords(coordsBuffer, m_texture);
|
||||
}
|
||||
|
||||
void Font::calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align)
|
||||
{
|
||||
// prevent glitches from invalid rects
|
||||
if(!screenCoords.isValid() || !m_texture)
|
||||
|
@ -86,8 +89,6 @@ void Font::renderText(const std::string& text,
|
|||
Size textBoxSize;
|
||||
const std::vector<Point>& glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize);
|
||||
|
||||
g_painter.setColor(color);
|
||||
|
||||
for(int i = 0; i < textLenght; ++i) {
|
||||
int glyph = (uchar)text[i];
|
||||
|
||||
|
@ -148,7 +149,7 @@ void Font::renderText(const std::string& text,
|
|||
}
|
||||
|
||||
// render glyph
|
||||
g_painter.drawTexturedRect(glyphScreenCoords, m_texture, glyphTextureCoords);
|
||||
coordsBuffer.addRect(glyphScreenCoords, glyphTextureCoords);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "declarations.h"
|
||||
|
||||
#include <framework/otml/declarations.h>
|
||||
#include <framework/graphics/coordsbuffer.h>
|
||||
|
||||
class Font
|
||||
{
|
||||
|
@ -36,15 +37,12 @@ public:
|
|||
void load(const OTMLNodePtr& fontNode);
|
||||
|
||||
/// Simple text render starting at startPos
|
||||
void renderText(const std::string& text,
|
||||
const Point& startPos,
|
||||
const Color& color = Color::white);
|
||||
void drawText(const std::string& text, const Point& startPos);
|
||||
|
||||
/// Advanced text render delimited by a screen region and alignment
|
||||
void renderText(const std::string& text,
|
||||
const Rect& screenCoords,
|
||||
Fw::AlignmentFlag align = Fw::AlignTopLeft,
|
||||
const Color& color = Color::white);
|
||||
void drawText(const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align = Fw::AlignTopLeft);
|
||||
|
||||
void calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align = Fw::AlignTopLeft);
|
||||
|
||||
/// Calculate glyphs positions to use on render, also calculates textBoxSize if wanted
|
||||
const std::vector<Point>& calculateGlyphsPositions(const std::string& text,
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2012 OTClient <https://github.com/edubart/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 "hardwarebuffer.h"
|
||||
|
|
@ -24,8 +24,46 @@
|
|||
#ifndef HARDWAREBUFFER_H
|
||||
#define HARDWAREBUFFER_H
|
||||
|
||||
#include "declarations.h"
|
||||
|
||||
class HardwareBuffer
|
||||
{
|
||||
public:
|
||||
enum Type {
|
||||
VertexBuffer = GL_ARRAY_BUFFER,
|
||||
IndexBuffer = GL_ELEMENT_ARRAY_BUFFER
|
||||
};
|
||||
|
||||
enum UsagePattern {
|
||||
StreamDraw = GL_STREAM_DRAW,
|
||||
StreamRead = GL_STREAM_READ,
|
||||
StreamCopy = GL_STREAM_COPY,
|
||||
StaticDraw = GL_STATIC_DRAW,
|
||||
StaticRead = GL_STATIC_READ,
|
||||
StaticCopy = GL_STATIC_COPY,
|
||||
DynamicDraw = GL_DYNAMIC_DRAW,
|
||||
DynamicRead = GL_DYNAMIC_READ,
|
||||
DynamicCopy = GL_DYNAMIC_COPY
|
||||
};
|
||||
|
||||
HardwareBuffer(Type type ) {
|
||||
m_type = type;
|
||||
m_id = 0;
|
||||
glGenBuffers(1, &m_id);
|
||||
assert(m_id != 0);
|
||||
}
|
||||
~HardwareBuffer() {
|
||||
glDeleteBuffers(1, &m_id);
|
||||
}
|
||||
|
||||
void bind() { glBindBuffer(m_type, m_id); }
|
||||
static void unbind(Type type) { glBindBuffer(type, 0); }
|
||||
void write(void *data, int count, UsagePattern usage) { glBufferData(m_type, count, data, usage); }
|
||||
//void read(void *data, int count);
|
||||
|
||||
private:
|
||||
Type m_type;
|
||||
GLuint m_id;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -55,7 +55,6 @@ void Painter::terminate()
|
|||
|
||||
void Painter::drawProgram(const PainterShaderProgramPtr& program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode)
|
||||
{
|
||||
coordsBuffer.cacheVertexArrays();
|
||||
if(coordsBuffer.getVertexCount() == 0)
|
||||
return;
|
||||
|
||||
|
|
|
@ -79,41 +79,38 @@ void PainterShaderProgram::setTexture(const TexturePtr& texture)
|
|||
if(!texture)
|
||||
return;
|
||||
|
||||
float w = texture->getWidth();
|
||||
float h = texture->getHeight();
|
||||
|
||||
Matrix2 textureTransformMatrix = { 1.0f/w, 0.0f,
|
||||
0.0f, 1.0f/h };
|
||||
textureTransformMatrix.transpose();
|
||||
|
||||
bind();
|
||||
setUniformTexture(TEXTURE_UNIFORM, texture, 0);
|
||||
setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, textureTransformMatrix);
|
||||
setUniformValue(TEXTURE_TRANSFORM_MATRIX_UNIFORM, texture->getTransformMatrix());
|
||||
}
|
||||
|
||||
void PainterShaderProgram::draw(const CoordsBuffer& coordsBuffer, DrawMode drawMode)
|
||||
void PainterShaderProgram::draw(CoordsBuffer& coordsBuffer, DrawMode drawMode)
|
||||
{
|
||||
bind();
|
||||
|
||||
setUniformValue(TIME_UNIFORM, g_clock.timeElapsed(m_startTime));
|
||||
|
||||
int numVertices = coordsBuffer.getVertexCount();
|
||||
if(numVertices == 0)
|
||||
int vertexCount = coordsBuffer.getVertexCount();
|
||||
if(vertexCount == 0)
|
||||
return;
|
||||
|
||||
bool mustDisableVertexArray = false;
|
||||
if(coordsBuffer.getVertexCount() > 0) {
|
||||
enableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR);
|
||||
setAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR, coordsBuffer.getVertices(), 2);
|
||||
mustDisableVertexArray = true;
|
||||
coordsBuffer.updateCaches();
|
||||
bool hardwareCached = coordsBuffer.isHardwareCached();
|
||||
|
||||
enableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR);
|
||||
if(hardwareCached)
|
||||
coordsBuffer.getHardwareVertexBuffer()->bind();
|
||||
setAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR, hardwareCached ? 0 : coordsBuffer.getVertexBuffer(), 2);
|
||||
|
||||
if(coordsBuffer.getTextureVertexCount() != 0) {
|
||||
enableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR);
|
||||
if(hardwareCached)
|
||||
coordsBuffer.getHardwareTextureVertexBuffer()->bind();
|
||||
setAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR, hardwareCached ? 0 : coordsBuffer.getTextureVertexBuffer(), 2);
|
||||
}
|
||||
|
||||
bool mustDisableTexCoordsArray = false;
|
||||
if(coordsBuffer.getTextureCoordsCount() > 0) {
|
||||
enableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR);
|
||||
setAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR, coordsBuffer.getTextureCoords(), 2);
|
||||
mustDisableTexCoordsArray = true;
|
||||
}
|
||||
if(hardwareCached)
|
||||
HardwareBuffer::unbind(HardwareBuffer::VertexBuffer);
|
||||
|
||||
for(int i=0;i<(int)m_textures.size();++i) {
|
||||
int location = std::get<0>(m_textures[i]);
|
||||
|
@ -127,14 +124,11 @@ void PainterShaderProgram::draw(const CoordsBuffer& coordsBuffer, DrawMode drawM
|
|||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glDrawArrays(drawMode, 0, numVertices);
|
||||
glDrawArrays(drawMode, 0, vertexCount);
|
||||
|
||||
if(mustDisableVertexArray)
|
||||
disableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR);
|
||||
disableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR);
|
||||
|
||||
if(mustDisableTexCoordsArray)
|
||||
if(coordsBuffer.getTextureVertexCount() != 0)
|
||||
disableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR);
|
||||
|
||||
//release();
|
||||
}
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
void setOpacity(float opacity);
|
||||
void setTexture(const TexturePtr& texture);
|
||||
void setUniformTexture(int location, const TexturePtr& texture, int index);
|
||||
void draw(const CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
|
||||
void draw(CoordsBuffer& coordsBuffer, DrawMode drawMode = Triangles);
|
||||
|
||||
private:
|
||||
DrawMode m_drawMode;
|
||||
|
|
|
@ -45,6 +45,8 @@ Texture::~Texture()
|
|||
uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height)
|
||||
{
|
||||
m_size.resize(width, height);
|
||||
m_transformMatrix = { 1.0f/width, 0.0f,
|
||||
0.0f, 1.0f/height };
|
||||
|
||||
// gets max texture size supported by the driver
|
||||
static GLint maxTexSize = -1;
|
||||
|
@ -63,6 +65,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
|||
// generate gl texture
|
||||
GLuint id;
|
||||
glGenTextures(1, &id);
|
||||
assert(id != 0);
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
|
||||
// detect pixels GL format
|
||||
|
|
|
@ -47,6 +47,7 @@ public:
|
|||
int getWidth() { return m_size.width(); }
|
||||
int getHeight() { return m_size.height(); }
|
||||
const Size& getSize() { return m_size; }
|
||||
const Matrix2& getTransformMatrix() { return m_transformMatrix; }
|
||||
|
||||
bool isEmpty() { return m_textureId == 0; }
|
||||
bool hasMipmaps() { return m_hasMipmaps; }
|
||||
|
@ -57,6 +58,7 @@ protected:
|
|||
|
||||
GLuint m_textureId;
|
||||
Size m_size;
|
||||
Matrix2 m_transformMatrix;
|
||||
Boolean<false> m_hasMipmaps;
|
||||
Boolean<false> m_smooth;
|
||||
};
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
void clear() { m_buffer.reset(); }
|
||||
float *vertices() const { return m_buffer.data(); }
|
||||
int vertexCount() const { return m_buffer.size() / 2; }
|
||||
int size() const { return m_buffer.size(); }
|
||||
|
||||
private:
|
||||
DataBuffer<float> m_buffer;
|
||||
|
|
|
@ -47,7 +47,8 @@ void UIFrameCounter::draw()
|
|||
}
|
||||
m_frameCount++;
|
||||
|
||||
m_font->renderText(m_fpsText, m_rect, m_align, Color::white);
|
||||
g_painter.setColor(Color::white);
|
||||
m_font->drawText(m_fpsText, m_rect, m_align);
|
||||
}
|
||||
|
||||
void UIFrameCounter::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||
|
|
|
@ -362,7 +362,7 @@ public:
|
|||
|
||||
// image
|
||||
private:
|
||||
void initImage() { }
|
||||
void initImage();
|
||||
void parseImageStyle(const OTMLNodePtr& styleNode);
|
||||
|
||||
void updateImageCache() { m_imageMustRecache = true; }
|
||||
|
@ -427,8 +427,8 @@ private:
|
|||
void parseTextStyle(const OTMLNodePtr& styleNode);
|
||||
|
||||
Boolean<true> m_textMustRecache;
|
||||
FrameBufferPtr m_textFramebuffer;
|
||||
Size m_textCachedBoxSize;
|
||||
CoordsBuffer m_textCoordsBuffer;
|
||||
Rect m_textCachedScreenCoords;
|
||||
|
||||
protected:
|
||||
void drawText(const Rect& screenCoords);
|
||||
|
|
|
@ -25,6 +25,11 @@
|
|||
#include <framework/graphics/texture.h>
|
||||
#include <framework/graphics/texturemanager.h>
|
||||
|
||||
void UIWidget::initImage()
|
||||
{
|
||||
m_imageCoordsBuffer.enableHardwareCaching();
|
||||
}
|
||||
|
||||
void UIWidget::parseImageStyle(const OTMLNodePtr& styleNode)
|
||||
{
|
||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||
|
|
|
@ -30,6 +30,7 @@ void UIWidget::initText()
|
|||
{
|
||||
m_font = g_fonts.getDefaultFont();
|
||||
m_textAlign = Fw::AlignCenter;
|
||||
m_textCoordsBuffer.enableHardwareCaching();
|
||||
}
|
||||
|
||||
void UIWidget::parseTextStyle(const OTMLNodePtr& styleNode)
|
||||
|
@ -51,36 +52,16 @@ void UIWidget::drawText(const Rect& screenCoords)
|
|||
if(m_text.length() == 0 || m_color.aF() == 0.0f)
|
||||
return;
|
||||
|
||||
#if 0
|
||||
//TODO: creating framebuffers on the fly was slowing down the render
|
||||
// we should use vertex arrys instead of this method
|
||||
Size boxSize = screenCoords.size();
|
||||
if(boxSize != m_textCachedBoxSize || m_textMustRecache) {
|
||||
if(!m_textFramebuffer)
|
||||
m_textFramebuffer = FrameBufferPtr(new FrameBuffer(boxSize));
|
||||
else
|
||||
m_textFramebuffer->resize(boxSize);
|
||||
|
||||
m_textFramebuffer->bind();
|
||||
Rect virtualTextRect(0, 0, boxSize);
|
||||
virtualTextRect.translate(m_textOffset);
|
||||
g_painter.saveAndResetState();
|
||||
g_painter.setCompositionMode(Painter::CompositionMode_DestBlending);
|
||||
m_font->renderText(m_text, virtualTextRect, m_textAlign, Color::white);
|
||||
g_painter.restoreSavedState();
|
||||
m_textFramebuffer->release();
|
||||
|
||||
if(screenCoords != m_textCachedScreenCoords || m_textMustRecache) {
|
||||
m_textMustRecache = false;
|
||||
m_textCachedBoxSize = boxSize;
|
||||
m_textCachedScreenCoords = screenCoords;
|
||||
|
||||
m_textCoordsBuffer.clear();
|
||||
m_font->calculateDrawTextCoords(m_textCoordsBuffer, m_text, screenCoords, m_textAlign);
|
||||
}
|
||||
|
||||
g_painter.setColor(m_color);
|
||||
m_textFramebuffer->draw(screenCoords);
|
||||
#else
|
||||
Rect textRect = screenCoords;
|
||||
textRect.translate(m_textOffset);
|
||||
m_font->renderText(m_text, textRect, m_textAlign, m_color);
|
||||
#endif
|
||||
g_painter.drawTextureCoords(m_textCoordsBuffer, m_font->getTexture());
|
||||
}
|
||||
|
||||
void UIWidget::onTextChange(const std::string& text, const std::string& oldText)
|
||||
|
|
|
@ -40,7 +40,8 @@ void AnimatedText::draw(const Point& dest, const Rect& visibleRect)
|
|||
|
||||
if(visibleRect.contains(rect)) {
|
||||
//TODO: cache into a framebuffer
|
||||
m_font->renderText(m_text, rect, Fw::AlignLeft, m_color);
|
||||
g_painter.setColor(m_color);
|
||||
m_font->drawText(m_text, rect, Fw::AlignLeft);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -232,7 +232,7 @@ void Creature::drawInformation(const Point& point, bool useGray, const Rect& par
|
|||
g_painter.drawFilledRect(healthRect);
|
||||
|
||||
if(m_informationFont)
|
||||
m_informationFont->renderText(m_name, textRect, Fw::AlignTopCenter, fillColor);
|
||||
m_informationFont->drawText(m_name, textRect, Fw::AlignTopCenter);
|
||||
|
||||
if(m_skull != Otc::SkullNone && m_skullTexture) {
|
||||
g_painter.setColor(Color::white);
|
||||
|
|
|
@ -40,7 +40,8 @@ void StaticText::draw(const Point& dest, const Rect& parentRect)
|
|||
// draw only if the real center is not too far from the parent center, or its a yell
|
||||
if((boundRect.center() - rect.center()).length() < parentRect.width() / 15 || isYell()) {
|
||||
//TODO: cache into a framebuffer
|
||||
m_font->renderText(m_text, boundRect, Fw::AlignCenter, m_color);
|
||||
g_painter.setColor(m_color);
|
||||
m_font->drawText(m_text, boundRect, Fw::AlignCenter);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ void UIItem::draw()
|
|||
|
||||
if(m_font && m_item->isStackable() && m_item->getCount() > 1) {
|
||||
std::string count = Fw::tostring(m_item->getCount());
|
||||
m_font->renderText(count, Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight, Color(231, 231, 231));
|
||||
g_painter.setColor(Color(231, 231, 231));
|
||||
m_font->drawText(count, Rect(m_rect.topLeft(), m_rect.bottomRight() - Point(3, 0)), Fw::AlignBottomRight);
|
||||
}
|
||||
|
||||
//m_font->renderText(Fw::unsafeCast<std::string>(m_item->getId()), m_rect);
|
||||
|
|
Loading…
Reference in New Issue