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"
|
#include "coordsbuffer.h"
|
||||||
|
|
||||||
void CoordsBuffer::clear()
|
CoordsBuffer::CoordsBuffer()
|
||||||
{
|
{
|
||||||
m_destRects.reset();
|
m_hardwareCacheMode = HardwareBuffer::DynamicDraw;
|
||||||
m_srcRects.reset();
|
m_hardwareVertexBuffer = nullptr;
|
||||||
m_textureCoords.clear();
|
m_hardwareTextureVertexBuffer = nullptr;
|
||||||
m_vertices.clear();
|
m_hardwareCached = false;
|
||||||
m_updateCache = true;
|
m_hardwareCaching = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoordsBuffer::addRect(const Rect& dest)
|
CoordsBuffer::~CoordsBuffer()
|
||||||
{
|
{
|
||||||
m_destRects << dest;
|
if(m_hardwareVertexBuffer)
|
||||||
m_updateCache = true;
|
delete m_hardwareVertexBuffer;
|
||||||
}
|
if(m_hardwareTextureVertexBuffer)
|
||||||
|
delete m_hardwareTextureVertexBuffer;
|
||||||
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)
|
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(right - w + 1, top, w, height - w)); // right
|
||||||
addRect(Rect(left + w, bottom - w + 1, width - w, w)); // bottom
|
addRect(Rect(left + w, bottom - w + 1, width - w, w)); // bottom
|
||||||
addRect(Rect(left, top + w, w, height - w)); // left
|
addRect(Rect(left, top + w, w, height - w)); // left
|
||||||
m_updateCache = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoordsBuffer::addRepeatedRects(const Rect& dest, const Rect& src)
|
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());
|
partialDest.translate(dest.topLeft());
|
||||||
m_destRects << partialDest;
|
m_vertexBuffer.addRect(partialDest);
|
||||||
m_srcRects << partialSrc;
|
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;
|
return;
|
||||||
|
|
||||||
int numDestRects = m_destRects.size();
|
if(m_vertexBuffer.vertexCount() > 0) {
|
||||||
int numSrcRects = m_srcRects.size();
|
if(!m_hardwareVertexBuffer && m_vertexBuffer.vertexCount() > 0)
|
||||||
m_vertices.clear();
|
m_hardwareVertexBuffer = new HardwareBuffer(HardwareBuffer::VertexBuffer);
|
||||||
m_textureCoords.clear();
|
m_hardwareVertexBuffer->bind();
|
||||||
|
m_hardwareVertexBuffer->write((void*)m_vertexBuffer.vertices(), m_vertexBuffer.size() * sizeof(float), m_hardwareCacheMode);
|
||||||
for(register int i=0;i<numDestRects;++i) {
|
|
||||||
m_vertices.addRect(m_destRects[i]);
|
|
||||||
if(numSrcRects == numDestRects)
|
|
||||||
m_textureCoords.addRect(m_srcRects[i]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
#define COORDSBUFFER_H
|
||||||
|
|
||||||
#include "vertexarray.h"
|
#include "vertexarray.h"
|
||||||
|
#include "hardwarebuffer.h"
|
||||||
|
|
||||||
class CoordsBuffer
|
class CoordsBuffer
|
||||||
{
|
{
|
||||||
public:
|
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);
|
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 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 *getVertexBuffer() const { return m_vertexBuffer.vertices(); }
|
||||||
float *getTextureCoords() const { return m_textureCoords.vertices(); }
|
float *getTextureVertexBuffer() const { return m_textureVertexBuffer.vertices(); }
|
||||||
int getVertexCount() const { return m_vertices.vertexCount(); }
|
int getVertexCount() const { return m_vertexBuffer.vertexCount(); }
|
||||||
int getTextureCoordsCount() const { return m_textureCoords.vertexCount(); }
|
int getTextureVertexCount() const { return m_textureVertexBuffer.vertexCount(); }
|
||||||
|
|
||||||
|
HardwareBuffer *getHardwareVertexBuffer() { return m_hardwareVertexBuffer; }
|
||||||
|
HardwareBuffer *getHardwareTextureVertexBuffer() { return m_hardwareTextureVertexBuffer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DataBuffer<Rect> m_destRects;
|
HardwareBuffer *m_hardwareVertexBuffer;
|
||||||
DataBuffer<Rect> m_srcRects;
|
HardwareBuffer *m_hardwareTextureVertexBuffer;
|
||||||
VertexArray m_vertices;
|
HardwareBuffer::UsagePattern m_hardwareCacheMode;
|
||||||
VertexArray m_textureCoords;
|
VertexArray m_vertexBuffer;
|
||||||
Boolean<true> m_updateCache;
|
VertexArray m_textureVertexBuffer;
|
||||||
|
bool m_hardwareCached;
|
||||||
|
bool m_hardwareCaching;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -61,20 +61,23 @@ void Font::load(const OTMLNodePtr& fontNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Font::renderText(const std::string& text,
|
void Font::drawText(const std::string& text, const Point& startPos)
|
||||||
const Point& startPos,
|
|
||||||
const Color& color)
|
|
||||||
{
|
{
|
||||||
Size boxSize = g_graphics.getViewportSize() - startPos.toSize();
|
Size boxSize = g_graphics.getViewportSize() - startPos.toSize();
|
||||||
Rect screenCoords(startPos, boxSize);
|
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,
|
calculateDrawTextCoords(coordsBuffer, text, screenCoords, align);
|
||||||
const Rect& screenCoords,
|
g_painter.drawTextureCoords(coordsBuffer, m_texture);
|
||||||
Fw::AlignmentFlag align,
|
}
|
||||||
const Color& color)
|
|
||||||
|
void Font::calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align)
|
||||||
{
|
{
|
||||||
// prevent glitches from invalid rects
|
// prevent glitches from invalid rects
|
||||||
if(!screenCoords.isValid() || !m_texture)
|
if(!screenCoords.isValid() || !m_texture)
|
||||||
|
@ -86,8 +89,6 @@ void Font::renderText(const std::string& text,
|
||||||
Size textBoxSize;
|
Size textBoxSize;
|
||||||
const std::vector<Point>& glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize);
|
const std::vector<Point>& glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize);
|
||||||
|
|
||||||
g_painter.setColor(color);
|
|
||||||
|
|
||||||
for(int i = 0; i < textLenght; ++i) {
|
for(int i = 0; i < textLenght; ++i) {
|
||||||
int glyph = (uchar)text[i];
|
int glyph = (uchar)text[i];
|
||||||
|
|
||||||
|
@ -148,7 +149,7 @@ void Font::renderText(const std::string& text,
|
||||||
}
|
}
|
||||||
|
|
||||||
// render glyph
|
// render glyph
|
||||||
g_painter.drawTexturedRect(glyphScreenCoords, m_texture, glyphTextureCoords);
|
coordsBuffer.addRect(glyphScreenCoords, glyphTextureCoords);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "declarations.h"
|
#include "declarations.h"
|
||||||
|
|
||||||
#include <framework/otml/declarations.h>
|
#include <framework/otml/declarations.h>
|
||||||
|
#include <framework/graphics/coordsbuffer.h>
|
||||||
|
|
||||||
class Font
|
class Font
|
||||||
{
|
{
|
||||||
|
@ -36,15 +37,12 @@ public:
|
||||||
void load(const OTMLNodePtr& fontNode);
|
void load(const OTMLNodePtr& fontNode);
|
||||||
|
|
||||||
/// Simple text render starting at startPos
|
/// Simple text render starting at startPos
|
||||||
void renderText(const std::string& text,
|
void drawText(const std::string& text, const Point& startPos);
|
||||||
const Point& startPos,
|
|
||||||
const Color& color = Color::white);
|
|
||||||
|
|
||||||
/// Advanced text render delimited by a screen region and alignment
|
/// Advanced text render delimited by a screen region and alignment
|
||||||
void renderText(const std::string& text,
|
void drawText(const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align = Fw::AlignTopLeft);
|
||||||
const Rect& screenCoords,
|
|
||||||
Fw::AlignmentFlag align = Fw::AlignTopLeft,
|
void calculateDrawTextCoords(CoordsBuffer& coordsBuffer, const std::string& text, const Rect& screenCoords, Fw::AlignmentFlag align = Fw::AlignTopLeft);
|
||||||
const Color& color = Color::white);
|
|
||||||
|
|
||||||
/// Calculate glyphs positions to use on render, also calculates textBoxSize if wanted
|
/// Calculate glyphs positions to use on render, also calculates textBoxSize if wanted
|
||||||
const std::vector<Point>& calculateGlyphsPositions(const std::string& text,
|
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
|
#ifndef HARDWAREBUFFER_H
|
||||||
#define HARDWAREBUFFER_H
|
#define HARDWAREBUFFER_H
|
||||||
|
|
||||||
|
#include "declarations.h"
|
||||||
|
|
||||||
class HardwareBuffer
|
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
|
#endif
|
||||||
|
|
|
@ -55,7 +55,6 @@ void Painter::terminate()
|
||||||
|
|
||||||
void Painter::drawProgram(const PainterShaderProgramPtr& program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode)
|
void Painter::drawProgram(const PainterShaderProgramPtr& program, CoordsBuffer& coordsBuffer, PainterShaderProgram::DrawMode drawMode)
|
||||||
{
|
{
|
||||||
coordsBuffer.cacheVertexArrays();
|
|
||||||
if(coordsBuffer.getVertexCount() == 0)
|
if(coordsBuffer.getVertexCount() == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -79,41 +79,38 @@ void PainterShaderProgram::setTexture(const TexturePtr& texture)
|
||||||
if(!texture)
|
if(!texture)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
float w = texture->getWidth();
|
|
||||||
float h = texture->getHeight();
|
|
||||||
|
|
||||||
Matrix2 textureTransformMatrix = { 1.0f/w, 0.0f,
|
|
||||||
0.0f, 1.0f/h };
|
|
||||||
textureTransformMatrix.transpose();
|
|
||||||
|
|
||||||
bind();
|
bind();
|
||||||
setUniformTexture(TEXTURE_UNIFORM, texture, 0);
|
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();
|
bind();
|
||||||
|
|
||||||
setUniformValue(TIME_UNIFORM, g_clock.timeElapsed(m_startTime));
|
setUniformValue(TIME_UNIFORM, g_clock.timeElapsed(m_startTime));
|
||||||
|
|
||||||
int numVertices = coordsBuffer.getVertexCount();
|
int vertexCount = coordsBuffer.getVertexCount();
|
||||||
if(numVertices == 0)
|
if(vertexCount == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool mustDisableVertexArray = false;
|
coordsBuffer.updateCaches();
|
||||||
if(coordsBuffer.getVertexCount() > 0) {
|
bool hardwareCached = coordsBuffer.isHardwareCached();
|
||||||
enableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR);
|
|
||||||
setAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR, coordsBuffer.getVertices(), 2);
|
enableAttributeArray(PainterShaderProgram::VERTEX_COORDS_ATTR);
|
||||||
mustDisableVertexArray = true;
|
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(hardwareCached)
|
||||||
if(coordsBuffer.getTextureCoordsCount() > 0) {
|
HardwareBuffer::unbind(HardwareBuffer::VertexBuffer);
|
||||||
enableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR);
|
|
||||||
setAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR, coordsBuffer.getTextureCoords(), 2);
|
|
||||||
mustDisableTexCoordsArray = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i=0;i<(int)m_textures.size();++i) {
|
for(int i=0;i<(int)m_textures.size();++i) {
|
||||||
int location = std::get<0>(m_textures[i]);
|
int location = std::get<0>(m_textures[i]);
|
||||||
|
@ -127,14 +124,11 @@ void PainterShaderProgram::draw(const CoordsBuffer& coordsBuffer, DrawMode drawM
|
||||||
}
|
}
|
||||||
glActiveTexture(GL_TEXTURE0);
|
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);
|
disableAttributeArray(PainterShaderProgram::TEXTURE_COORDS_ATTR);
|
||||||
|
|
||||||
//release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
void setOpacity(float opacity);
|
void setOpacity(float opacity);
|
||||||
void setTexture(const TexturePtr& texture);
|
void setTexture(const TexturePtr& texture);
|
||||||
void setUniformTexture(int location, const TexturePtr& texture, int index);
|
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:
|
private:
|
||||||
DrawMode m_drawMode;
|
DrawMode m_drawMode;
|
||||||
|
|
|
@ -45,6 +45,8 @@ Texture::~Texture()
|
||||||
uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height)
|
uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int height)
|
||||||
{
|
{
|
||||||
m_size.resize(width, 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
|
// gets max texture size supported by the driver
|
||||||
static GLint maxTexSize = -1;
|
static GLint maxTexSize = -1;
|
||||||
|
@ -63,6 +65,7 @@ uint Texture::internalLoadGLTexture(uchar *pixels, int channels, int width, int
|
||||||
// generate gl texture
|
// generate gl texture
|
||||||
GLuint id;
|
GLuint id;
|
||||||
glGenTextures(1, &id);
|
glGenTextures(1, &id);
|
||||||
|
assert(id != 0);
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
|
|
||||||
// detect pixels GL format
|
// detect pixels GL format
|
||||||
|
|
|
@ -47,6 +47,7 @@ public:
|
||||||
int getWidth() { return m_size.width(); }
|
int getWidth() { return m_size.width(); }
|
||||||
int getHeight() { return m_size.height(); }
|
int getHeight() { return m_size.height(); }
|
||||||
const Size& getSize() { return m_size; }
|
const Size& getSize() { return m_size; }
|
||||||
|
const Matrix2& getTransformMatrix() { return m_transformMatrix; }
|
||||||
|
|
||||||
bool isEmpty() { return m_textureId == 0; }
|
bool isEmpty() { return m_textureId == 0; }
|
||||||
bool hasMipmaps() { return m_hasMipmaps; }
|
bool hasMipmaps() { return m_hasMipmaps; }
|
||||||
|
@ -57,6 +58,7 @@ protected:
|
||||||
|
|
||||||
GLuint m_textureId;
|
GLuint m_textureId;
|
||||||
Size m_size;
|
Size m_size;
|
||||||
|
Matrix2 m_transformMatrix;
|
||||||
Boolean<false> m_hasMipmaps;
|
Boolean<false> m_hasMipmaps;
|
||||||
Boolean<false> m_smooth;
|
Boolean<false> m_smooth;
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,6 +59,7 @@ public:
|
||||||
void clear() { m_buffer.reset(); }
|
void clear() { m_buffer.reset(); }
|
||||||
float *vertices() const { return m_buffer.data(); }
|
float *vertices() const { return m_buffer.data(); }
|
||||||
int vertexCount() const { return m_buffer.size() / 2; }
|
int vertexCount() const { return m_buffer.size() / 2; }
|
||||||
|
int size() const { return m_buffer.size(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DataBuffer<float> m_buffer;
|
DataBuffer<float> m_buffer;
|
||||||
|
|
|
@ -47,7 +47,8 @@ void UIFrameCounter::draw()
|
||||||
}
|
}
|
||||||
m_frameCount++;
|
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)
|
void UIFrameCounter::onStyleApply(const std::string& styleName, const OTMLNodePtr& styleNode)
|
||||||
|
|
|
@ -362,7 +362,7 @@ public:
|
||||||
|
|
||||||
// image
|
// image
|
||||||
private:
|
private:
|
||||||
void initImage() { }
|
void initImage();
|
||||||
void parseImageStyle(const OTMLNodePtr& styleNode);
|
void parseImageStyle(const OTMLNodePtr& styleNode);
|
||||||
|
|
||||||
void updateImageCache() { m_imageMustRecache = true; }
|
void updateImageCache() { m_imageMustRecache = true; }
|
||||||
|
@ -427,8 +427,8 @@ private:
|
||||||
void parseTextStyle(const OTMLNodePtr& styleNode);
|
void parseTextStyle(const OTMLNodePtr& styleNode);
|
||||||
|
|
||||||
Boolean<true> m_textMustRecache;
|
Boolean<true> m_textMustRecache;
|
||||||
FrameBufferPtr m_textFramebuffer;
|
CoordsBuffer m_textCoordsBuffer;
|
||||||
Size m_textCachedBoxSize;
|
Rect m_textCachedScreenCoords;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void drawText(const Rect& screenCoords);
|
void drawText(const Rect& screenCoords);
|
||||||
|
|
|
@ -25,6 +25,11 @@
|
||||||
#include <framework/graphics/texture.h>
|
#include <framework/graphics/texture.h>
|
||||||
#include <framework/graphics/texturemanager.h>
|
#include <framework/graphics/texturemanager.h>
|
||||||
|
|
||||||
|
void UIWidget::initImage()
|
||||||
|
{
|
||||||
|
m_imageCoordsBuffer.enableHardwareCaching();
|
||||||
|
}
|
||||||
|
|
||||||
void UIWidget::parseImageStyle(const OTMLNodePtr& styleNode)
|
void UIWidget::parseImageStyle(const OTMLNodePtr& styleNode)
|
||||||
{
|
{
|
||||||
for(const OTMLNodePtr& node : styleNode->children()) {
|
for(const OTMLNodePtr& node : styleNode->children()) {
|
||||||
|
|
|
@ -30,6 +30,7 @@ void UIWidget::initText()
|
||||||
{
|
{
|
||||||
m_font = g_fonts.getDefaultFont();
|
m_font = g_fonts.getDefaultFont();
|
||||||
m_textAlign = Fw::AlignCenter;
|
m_textAlign = Fw::AlignCenter;
|
||||||
|
m_textCoordsBuffer.enableHardwareCaching();
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIWidget::parseTextStyle(const OTMLNodePtr& styleNode)
|
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)
|
if(m_text.length() == 0 || m_color.aF() == 0.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#if 0
|
if(screenCoords != m_textCachedScreenCoords || m_textMustRecache) {
|
||||||
//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();
|
|
||||||
|
|
||||||
m_textMustRecache = false;
|
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);
|
g_painter.setColor(m_color);
|
||||||
m_textFramebuffer->draw(screenCoords);
|
g_painter.drawTextureCoords(m_textCoordsBuffer, m_font->getTexture());
|
||||||
#else
|
|
||||||
Rect textRect = screenCoords;
|
|
||||||
textRect.translate(m_textOffset);
|
|
||||||
m_font->renderText(m_text, textRect, m_textAlign, m_color);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UIWidget::onTextChange(const std::string& text, const std::string& oldText)
|
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)) {
|
if(visibleRect.contains(rect)) {
|
||||||
//TODO: cache into a framebuffer
|
//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);
|
g_painter.drawFilledRect(healthRect);
|
||||||
|
|
||||||
if(m_informationFont)
|
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) {
|
if(m_skull != Otc::SkullNone && m_skullTexture) {
|
||||||
g_painter.setColor(Color::white);
|
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
|
// 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()) {
|
if((boundRect.center() - rect.center()).length() < parentRect.width() / 15 || isYell()) {
|
||||||
//TODO: cache into a framebuffer
|
//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) {
|
if(m_font && m_item->isStackable() && m_item->getCount() > 1) {
|
||||||
std::string count = Fw::tostring(m_item->getCount());
|
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);
|
//m_font->renderText(Fw::unsafeCast<std::string>(m_item->getId()), m_rect);
|
||||||
|
|
Loading…
Reference in New Issue