ui loader and some refactoring

This commit is contained in:
Eduardo Bart
2011-04-10 17:40:44 -03:00
parent 1f78f93096
commit 992e0a8a6b
36 changed files with 646 additions and 425 deletions

View File

@@ -84,70 +84,64 @@ void BorderedImage::draw(const Rect& screenCoords)
if(screenCoords.size() <= m_cornersSize)
return;
const Size& textureSize = m_texture->getSize();
Rect rectCoords;
Size centerSize = screenCoords.size() - m_cornersSize;
g_graphics._beginTextureRender(m_texture.get());
// first the center
rectCoords = Rect(screenCoords.left() + m_leftBorderTexCoords.width(),
screenCoords.top() + m_topBorderTexCoords.height(),
centerSize);
g_graphics._drawRepeatedTexturedRect(rectCoords, m_centerTexCoords, textureSize);
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_centerTexCoords);
// top left corner
rectCoords = Rect(screenCoords.topLeft(),
m_topLeftCornerTexCoords.size());
g_graphics._drawTexturedRect(rectCoords, m_topLeftCornerTexCoords, textureSize);
g_graphics.drawTexturedRect(rectCoords, m_texture, m_topLeftCornerTexCoords);
// top
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width(),
screenCoords.topLeft().y,
centerSize.width(),
m_topBorderTexCoords.height());
g_graphics._drawRepeatedTexturedRect(rectCoords, m_topBorderTexCoords, textureSize);
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_topBorderTexCoords);
// top right corner
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width() + centerSize.width(),
screenCoords.top(),
m_topRightCornerTexCoords.size());
g_graphics._drawTexturedRect(rectCoords, m_topRightCornerTexCoords, textureSize);
g_graphics.drawTexturedRect(rectCoords, m_texture, m_topRightCornerTexCoords);
// left
rectCoords = Rect(screenCoords.left(),
screenCoords.top() + m_topLeftCornerTexCoords.height(),
m_leftBorderTexCoords.width(),
centerSize.height());
g_graphics._drawRepeatedTexturedRect(rectCoords, m_leftBorderTexCoords, textureSize);
g_graphics.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_graphics._drawRepeatedTexturedRect(rectCoords, m_rightBorderTexCoords, textureSize);
g_graphics.drawRepeatedTexturedRect(rectCoords, m_texture, m_rightBorderTexCoords);
// bottom left corner
rectCoords = Rect(screenCoords.left(),
screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(),
m_bottomLeftCornerTexCoords.size());
g_graphics._drawTexturedRect(rectCoords, m_bottomLeftCornerTexCoords, textureSize);
g_graphics.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_graphics._drawRepeatedTexturedRect(rectCoords, m_bottomBorderTexCoords, textureSize);
g_graphics.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_graphics._drawTexturedRect(rectCoords, m_bottomRightCornerTexCoords, textureSize);
//g_graphics._drawBoundingRect(screenCoords, Color(0xFF00FF00), 1);
g_graphics._endTextureRender();
g_graphics.drawTexturedRect(rectCoords, m_texture, m_bottomRightCornerTexCoords);
}

View File

@@ -27,11 +27,7 @@
#include "textures.h"
#include "graphics.h"
Font::Font() :
m_glyphHeight(10),
m_topMargin(0)
{
}
void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
{
@@ -73,12 +69,11 @@ bool Font::load(const std::string& file)
{
std::string fileContents = g_resources.loadTextFile(file);
if(!fileContents.size()) {
logError("Empty font file \"%s", file.c_str());
logError("Coult not load font file \"%s", file.c_str());
return false;
}
std::istringstream fin(fileContents);
std::string textureName;
Size glyphSize;
@@ -88,22 +83,25 @@ bool Font::load(const std::string& file)
YAML::Node doc;
parser.GetNextDocument(doc);
// required values
doc["glyph height"] >> m_glyphHeight;
doc["glyph spacing"] >> m_glyphSpacing;
doc["top margin"] >> m_topMargin;
doc["image glyph size"] >> glyphSize;
doc["image"] >> textureName;
// optional values
if(doc.FindValue("glyph spacing"))
doc["glyph spacing"] >> m_glyphSpacing;
if(doc.FindValue("top margin"))
doc["top margin"] >> m_topMargin;
// load texture
m_texture = g_textures.get("fonts/" + textureName);
if(!m_texture) {
logError("Failed to load image for font \"%s\"", file.c_str());
logError("Failed to load image for font file \"%s\"", file.c_str());
return false;
}
// set glyphs height
for(int glyph = 32; glyph < 256; ++glyph) {
}
// auto calculate widths
calculateGlyphsWidthsAutomatically(glyphSize);
// read custom widths
@@ -121,13 +119,12 @@ bool Font::load(const std::string& file)
int numHorizontalGlyphs = m_texture->getSize().width() / glyphSize.width();
for(int glyph = 32; glyph< 256; ++glyph) {
m_glyphsTextureCoords[glyph].setRect(((glyph - 32) % numHorizontalGlyphs) * glyphSize.width(),
((glyph - 32) / numHorizontalGlyphs) * glyphSize.height(),
m_glyphsSize[glyph].width(),
m_glyphHeight);
((glyph - 32) / numHorizontalGlyphs) * glyphSize.height(),
m_glyphsSize[glyph].width(),
m_glyphHeight);
}
} catch (YAML::ParserException& e) {
logError("Malformed font file \"%s\"", file.c_str());
} catch (YAML::Exception& e) {
logError("Malformed font file \"%s\":\n %s", file.c_str(), e.what());
return false;
}
@@ -146,18 +143,12 @@ void Font::renderText(const std::string& text,
const Rect& screenCoords,
int align,
const Color& color,
const Point& startInternalPos,
bool debug)
const Point& startInternalPos)
{
// prevent glitches from invalid rects
if(!screenCoords.isValid())
return;
// begin texture rendering
g_graphics.setColor(color);
g_graphics._beginTextureRender(m_texture.get());
const Size& textureSize = m_texture->getSize();
int textLenght = text.length();
// map glyphs positions
@@ -227,17 +218,8 @@ void Font::renderText(const std::string& text,
}
// render glyph
g_graphics._drawTexturedRect(glyphScreenCoords, glyphTextureCoords, textureSize);
//g_graphics._drawBoundingRect(glyphScreenCoords, Color(0xFF0000FF));
g_graphics.drawTexturedRect(glyphScreenCoords, m_texture, glyphTextureCoords, color);
}
// end texture redering
g_graphics._endTextureRender();
g_graphics.resetColor();
if(debug)
g_graphics.drawBoundingRect(screenCoords.expanded(1), Color(0xFF00FF00));
}
Point* Font::calculateGlyphsPositions(const std::string& text, int align, Size *textBoxSize)

View File

@@ -45,8 +45,10 @@ enum EAlign {
class Font
{
public:
Font();
virtual ~Font() { }
Font(const std::string& name) :
m_name(name),
m_glyphHeight(10),
m_topMargin(0) { }
/// Load font from file
bool load(const std::string &file);
@@ -62,9 +64,8 @@ public:
void renderText(const std::string& text,
const Rect& screenCoords,
int align = ALIGN_TOP_LEFT,
const Color& color = Color(0xFFFFFFFF),
const Point& startInternalPos = Point(),
bool debug = false);
const Color& color = Color::white,
const Point& startInternalPos = Point());
/// Calculate glyphs positions to use on render, also calculates textBoxSize if wanted
Point *calculateGlyphsPositions(const std::string& text, int align = ALIGN_TOP_LEFT, Size *textBoxSize = NULL);
@@ -72,9 +73,12 @@ public:
/// Simulate render and calculate text size
Size calculateTextRectSize(const std::string& text);
const std::string& getName() const { return m_name; }
private:
void calculateGlyphsWidthsAutomatically(const Size& glyphSize);
std::string m_name;
int m_glyphHeight;
int m_topMargin;
Size m_glyphSpacing;
@@ -83,4 +87,6 @@ private:
Size m_glyphsSize[256];
};
typedef std::shared_ptr<Font> FontPtr;
#endif // FONT_H

View File

@@ -23,13 +23,11 @@
#include "fonts.h"
#include "font.h"
#include "core/resources.h"
Fonts g_fonts;
Font *g_defaultFont = NULL;
void Fonts::init()
void Fonts::init(const std::string& defaultFontName)
{
// load all fonts
std::list<std::string> files = g_resources.getDirectoryFiles("fonts");
@@ -37,27 +35,28 @@ void Fonts::init()
if(boost::ends_with(file, ".yml")) {
std::string name = file;
boost::erase_first(name, ".yml");
std::shared_ptr<Font> font(new Font);
font->load("fonts/" + file);
m_fonts[name] = font;
FontPtr font(new Font(name));
if(font->load("fonts/" + file)) {
m_fonts.push_back(font);
if(name == defaultFontName)
m_defaultFont = font;
}
}
}
// set default font
g_defaultFont = get("tibia-12px-rounded");
if(!g_defaultFont)
logFatal("Default font not found!");
if(!m_defaultFont)
logFatal("Could not load the default font \"%s\"\n", defaultFontName.c_str());
}
Font* Fonts::get(const std::string& fontName)
{
// find font by name
auto it = m_fonts.find(fontName);
if(it != m_fonts.end()) {
return it->second.get();
for(auto it = m_fonts.begin(); it != m_fonts.end(); ++it) {
if((*it)->getName() == fontName)
return (*it).get();
}
logError("Font \"%s\" not found", fontName.c_str());
return NULL;
logError("Font \"%s\" not found, returing the default one", fontName.c_str());
return m_defaultFont.get();
}

View File

@@ -34,19 +34,22 @@ public:
Fonts() { }
/// Initialize all fonts
void init();
/// Get a font by name
Font *get(const std::string& fontName);
void init(const std::string& defaultFontName);
/// Terminate all fonts
void terminate() { }
/// Get a font by name
Font *get(const std::string& fontName);
/// Get the default font
Font *getDefaultFont() { return m_defaultFont.get(); };
private:
std::map<std::string, std::shared_ptr<Font> > m_fonts;
std::vector<FontPtr> m_fonts;
FontPtr m_defaultFont;
};
extern Fonts g_fonts;
extern Font *g_defaultFont;
#endif // FONTS_H

View File

@@ -123,49 +123,19 @@ void Graphics::endRender()
}
void Graphics::setColor(const Color& color)
void Graphics::drawTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color)
{
if(screenCoords.size().isEmpty())
return;
glColor4ubv(color.rgbaPtr());
}
void Graphics::resetColor()
{
glColor4ub(0xFF, 0xFF, 0xFF, 0xFF);
}
void Graphics::_beginTextureRender(const Texture *texture)
{
glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
glBegin(GL_QUADS);
}
void Graphics::_endTextureRender()
{
glEnd();
}
void Graphics::drawTexturedRect(const Rect& screenCoords, const Texture *texture, const Rect& textureCoords)
{
if(screenCoords.size().isEmpty())
return;
glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
glBegin(GL_QUADS);
_drawTexturedRect(screenCoords, textureCoords, texture->getSize());
glEnd();
}
void Graphics::_drawTexturedRect(const Rect& screenCoords, const Rect& textureCoords, const Size& textureSize)
{
if(screenCoords.size().isEmpty())
return;
// rect correction for opengl
int right = screenCoords.right() + 1;
int bottom = screenCoords.bottom() + 1;
int top = screenCoords.top();
int left = screenCoords.left();
const Size& textureSize = texture->getSize();
float textureRight = 0.0f;
float textureBottom = 1.0f;
@@ -179,24 +149,18 @@ void Graphics::_drawTexturedRect(const Rect& screenCoords, const Rect& textureCo
textureLeft = (float)textureCoords.left() / textureSize.width();
}
glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
glBegin(GL_QUADS);
glTexCoord2f(textureLeft, textureTop); glVertex2i(left, top);
glTexCoord2f(textureLeft, textureBottom); glVertex2i(left, bottom);
glTexCoord2f(textureRight, textureBottom); glVertex2i(right, bottom);
glTexCoord2f(textureRight, textureTop); glVertex2i(right, top);
}
void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords, const Texture* texture, const Rect& texCoords)
{
if(screenCoords.size().isEmpty())
return;
glBindTexture(GL_TEXTURE_2D, texture->getTextureId());
glBegin(GL_QUADS);
_drawRepeatedTexturedRect(screenCoords, texCoords, texture->getSize());
glEnd();
}
void Graphics::_drawRepeatedTexturedRect(const Rect& screenCoords, const Rect& textureCoords, const Size& textureSize)
void Graphics::drawRepeatedTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color)
{
if(screenCoords.size().isEmpty())
return;
@@ -219,20 +183,19 @@ void Graphics::_drawRepeatedTexturedRect(const Rect& screenCoords, const Rect& t
}
partialCoords.translate(screenCoords.topLeft());
_drawTexturedRect(partialCoords, partialTextureCoords, textureSize);
drawTexturedRect(partialCoords, texture, partialTextureCoords, color);
}
}
}
void Graphics::drawColoredRect(const Rect& screenCoords, const Color& color)
void Graphics::drawFilledRect(const Rect& screenCoords, const Color& color)
{
if(screenCoords.size().isEmpty())
return;
glDisable(GL_TEXTURE_2D);
setColor(color);
glColor4ubv(color.rgbaPtr());
// rect correction for opengl
int right = screenCoords.right() + 1;
@@ -248,8 +211,6 @@ void Graphics::drawColoredRect(const Rect& screenCoords, const Color& color)
glEnd();
glEnable(GL_TEXTURE_2D);
resetColor();
}
@@ -260,7 +221,7 @@ void Graphics::drawBoundingRect(const Rect& screenCoords, const Color& color, in
glDisable(GL_TEXTURE_2D);
setColor(color);
glColor4ubv(color.rgbaPtr());
// rect correction for opengl
int right = screenCoords.right()+1;
@@ -295,13 +256,4 @@ void Graphics::drawBoundingRect(const Rect& screenCoords, const Color& color, in
glEnd();
glEnable(GL_TEXTURE_2D);
resetColor();
}
void Graphics::_drawBoundingRect(const Rect& screenCoords, const Color& color, int innerLineWidth)
{
glEnd();
drawBoundingRect(screenCoords, color, innerLineWidth);
glBegin(GL_QUADS);
}

View File

@@ -26,15 +26,17 @@
#define GRAPHICS_H
#include "prerequisites.h"
class Texture;
#include "texture.h"
class Graphics
{
public:
Graphics() { }
/// Initialize graphics
void init();
/// Termiante graphics
void terminate();
/// Check if a GL extension is supported
@@ -54,21 +56,10 @@ public:
const Size& getScreenSize() const { return m_screenSize; }
void setColor(const Color& color);
void resetColor();
// high level rendering
void drawTexturedRect(const Rect& screenCoords, const Texture *texture, const Rect& texCoords = Rect());
void drawRepeatedTexturedRect(const Rect& screenCoords, const Texture *texture, const Rect& texCoords);
void drawColoredRect(const Rect& screenCoords, const Color& color);
void drawBoundingRect(const Rect& screenCoords, const Color& color, int innerLineWidth = 1);
// lower level rendering
void _beginTextureRender(const Texture *texture);
void _drawTexturedRect(const Rect& screenCoords, const Rect& textureCoords, const Size& textureSize);
void _drawRepeatedTexturedRect(const Rect& screenCoords, const Rect& textureCoords, const Size& textureSize);
void _drawBoundingRect(const Rect& screenCoords, const Color& color, int innerLineWidth = 1);
void _endTextureRender();
void drawTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords = Rect(), const Color& color = Color::white);
void drawRepeatedTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color = Color::white);
void drawFilledRect(const Rect& screenCoords, const Color& color);
void drawBoundingRect(const Rect& screenCoords, const Color& color = Color::green, int innerLineWidth = 1);
private:
Size m_screenSize;

View File

@@ -37,14 +37,9 @@ Image::Image(const std::string& texture, Rect textureCoords) :
m_texture = g_textures.get(texture);
}
void Image::enableBilinearFilter()
{
m_texture->enableBilinearFilter();
}
void Image::draw(const Rect& screenCoords)
{
g_graphics.drawTexturedRect(screenCoords, m_texture.get(), m_textureCoords);
g_graphics.drawTexturedRect(screenCoords, m_texture, m_textureCoords);
}

View File

@@ -36,7 +36,7 @@ public:
Image(const std::string& texture);
Image(const std::string& texture, Rect textureCoords);
void enableBilinearFilter();
/// Draw image on screen
virtual void draw(const Rect& screenCoords);
protected:

View File

@@ -29,9 +29,9 @@
Texture::Texture(int width, int height, int components, uchar *pixels)
{
m_size.setWidth(width);
m_size.setHeight(height);
m_size.setSize(width, height);
// generate opengl texture
glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId);
@@ -51,11 +51,14 @@ Texture::Texture(int width, int height, int components, uchar *pixels)
break;
}
// load the pixels into opengl memory
glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, format, GL_UNSIGNED_BYTE, pixels);
// disable texture border
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// nearest filtering
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
@@ -75,6 +78,7 @@ void Texture::enableBilinearFilter()
uchar *Texture::getPixels()
{
// copy pixels from opengl memory
uchar *pixels = new uchar[m_size.area()*4];
glBindTexture(GL_TEXTURE_2D, m_textureId);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

View File

@@ -41,23 +41,22 @@ TexturePtr Textures::get(const std::string& textureFile)
texture = it->second.lock();
}
if(!texture) { // load texture
// texture not found, load it
if(!texture) {
// currently only png textures are supported
if(!boost::ends_with(textureFile, ".png")) {
if(!boost::ends_with(textureFile, ".png"))
logFatal("Unable to load texture %s, file format no supported.", textureFile.c_str());
return texture;
}
// load texture file data
uint fileSize;
uchar *textureFileData = g_resources.loadFile(textureFile, &fileSize);
if(!textureFileData) {
if(!textureFileData)
logFatal("Unable to load texture %s, file could not be read.", textureFile.c_str());
return texture;
}
// load the texture
texture = TexturePtr(TextureLoader::loadPNG(textureFileData));
if(!texture)
logFatal("Unable to load texture %s, loading error.", textureFile.c_str());
logFatal("Unable to load texture %s", textureFile.c_str());
delete[] textureFileData;
}