refactoring paths and includes

This commit is contained in:
Eduardo Bart
2011-04-10 12:37:15 -03:00
parent 792d661dad
commit 1f78f93096
74 changed files with 130 additions and 162 deletions

View File

@@ -0,0 +1,153 @@
/* The MIT License
*
* Copyright (c) 2010 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 "borderedimage.h"
#include "graphics.h"
#include "textures.h"
BorderedImage::BorderedImage(TexturePtr texture,
const Rect& left,
const Rect& right,
const Rect& top,
const Rect& bottom,
const Rect& topLeft,
const Rect& topRight,
const Rect& bottomLeft,
const Rect& bottomRight,
const Rect& center) : Image(texture)
{
setTexCoords(left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight, center);
}
BorderedImage::BorderedImage(const std::string& texture,
const Rect& left,
const Rect& right,
const Rect& top,
const Rect& bottom,
const Rect& topLeft,
const Rect& topRight,
const Rect& bottomLeft,
const Rect& bottomRight,
const Rect& center) : Image(texture)
{
setTexCoords(left, right, top, bottom, topLeft, topRight, bottomLeft, bottomRight, center);
}
void BorderedImage::setTexCoords(const Rect& left,
const Rect& right,
const Rect& top,
const Rect& bottom,
const Rect& topLeft,
const Rect& topRight,
const Rect& bottomLeft,
const Rect& bottomRight,
const Rect& center)
{
m_leftBorderTexCoords = left;
m_rightBorderTexCoords = right;
m_topBorderTexCoords = top;
m_bottomBorderTexCoords = bottom;
m_topLeftCornerTexCoords = topLeft;
m_topRightCornerTexCoords = topRight;
m_bottomLeftCornerTexCoords = bottomLeft;
m_bottomRightCornerTexCoords = bottomRight;
m_centerTexCoords = center;
m_cornersSize = Size(left.width() + right.width(),
top.height() + bottom.height());
}
void BorderedImage::draw(const Rect& screenCoords)
{
// check minumim size
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);
// top left corner
rectCoords = Rect(screenCoords.topLeft(),
m_topLeftCornerTexCoords.size());
g_graphics._drawTexturedRect(rectCoords, m_topLeftCornerTexCoords, textureSize);
// top
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width(),
screenCoords.topLeft().y,
centerSize.width(),
m_topBorderTexCoords.height());
g_graphics._drawRepeatedTexturedRect(rectCoords, m_topBorderTexCoords, textureSize);
// top right corner
rectCoords = Rect(screenCoords.left() + m_topLeftCornerTexCoords.width() + centerSize.width(),
screenCoords.top(),
m_topRightCornerTexCoords.size());
g_graphics._drawTexturedRect(rectCoords, m_topRightCornerTexCoords, textureSize);
// left
rectCoords = Rect(screenCoords.left(),
screenCoords.top() + m_topLeftCornerTexCoords.height(),
m_leftBorderTexCoords.width(),
centerSize.height());
g_graphics._drawRepeatedTexturedRect(rectCoords, m_leftBorderTexCoords, textureSize);
// 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);
// bottom left corner
rectCoords = Rect(screenCoords.left(),
screenCoords.top() + m_topBorderTexCoords.height() + centerSize.height(),
m_bottomLeftCornerTexCoords.size());
g_graphics._drawTexturedRect(rectCoords, m_bottomLeftCornerTexCoords, textureSize);
// 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);
// 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();
}

View File

@@ -0,0 +1,87 @@
/* The MIT License
*
* Copyright (c) 2010 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.
*/
#ifndef BORDEREDIMAGE_H
#define BORDEREDIMAGE_H
#include "prerequisites.h"
#include "image.h"
#include "texture.h"
class BorderedImage : public Image
{
public:
BorderedImage(TexturePtr texture,
const Rect& left,
const Rect& right,
const Rect& top,
const Rect& bottom,
const Rect& topLeft,
const Rect& topRight,
const Rect& bottomLeft,
const Rect& bottomRight,
const Rect& center);
BorderedImage(const std::string& texture,
const Rect& left,
const Rect& right,
const Rect& top,
const Rect& bottom,
const Rect& topLeft,
const Rect& topRight,
const Rect& bottomLeft,
const Rect& bottomRight,
const Rect& center);
void setTexCoords(const Rect& left,
const Rect& right,
const Rect& top,
const Rect& bottom,
const Rect& topLeft,
const Rect& topRight,
const Rect& bottomLeft,
const Rect& bottomRight,
const Rect& center);
void draw(const Rect& screenCoords);
private:
Rect m_leftBorderTexCoords;
Rect m_rightBorderTexCoords;
Rect m_topBorderTexCoords;
Rect m_bottomBorderTexCoords;
Rect m_topLeftCornerTexCoords;
Rect m_topRightCornerTexCoords;
Rect m_bottomLeftCornerTexCoords;
Rect m_bottomRightCornerTexCoords;
Rect m_centerTexCoords;
Size m_cornersSize;
};
typedef std::shared_ptr<BorderedImage> BorderedImagePtr;
#endif // BORDEREDIMAGE_H

View File

@@ -0,0 +1,317 @@
/* The MIT License
*
* Copyright (c) 2010 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 "font.h"
#include "core/resources.h"
#include "textures.h"
#include "graphics.h"
Font::Font() :
m_glyphHeight(10),
m_topMargin(0)
{
}
void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
{
int numHorizontalGlyphs = m_texture->getSize().width() / glyphSize.width();
uchar *texturePixels = m_texture->getPixels();
// small AI to auto calculate pixels widths
for(int glyph = 32; glyph< 256; ++glyph) {
Rect glyphCoords(((glyph - 32) % numHorizontalGlyphs) * glyphSize.width(),
((glyph - 32) / numHorizontalGlyphs) * glyphSize.height(),
glyphSize.width(),
m_glyphHeight);
int width = glyphSize.width();
for(int x = glyphCoords.left() + 2; x <= glyphCoords.right(); ++x) {
bool allAlpha = true;
// check if all vertical pixels are alpha
for(int y = glyphCoords.top(); y <= glyphCoords.bottom(); ++y) {
if(texturePixels[(y * m_texture->getSize().width() * 4) + (x*4) + 3] != 0) {
allAlpha = false;
break;
}
}
// if all pixels were alpha we found the width
if(allAlpha) {
width = x - glyphCoords.left();
break;
}
}
// store glyph size
m_glyphsSize[glyph].setSize(width, m_glyphHeight);
}
delete[] texturePixels;
}
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());
return false;
}
std::istringstream fin(fileContents);
std::string textureName;
Size glyphSize;
try {
YAML::Parser parser(fin);
YAML::Node doc;
parser.GetNextDocument(doc);
doc["glyph height"] >> m_glyphHeight;
doc["glyph spacing"] >> m_glyphSpacing;
doc["top margin"] >> m_topMargin;
doc["image glyph size"] >> glyphSize;
doc["image"] >> textureName;
m_texture = g_textures.get("fonts/" + textureName);
if(!m_texture) {
logError("Failed to load image for font \"%s\"", file.c_str());
return false;
}
// set glyphs height
for(int glyph = 32; glyph < 256; ++glyph) {
}
calculateGlyphsWidthsAutomatically(glyphSize);
// read custom widths
if(doc.FindValue("glyph widths")) {
const YAML::Node& widthsNode = doc["glyph widths"];
for(auto it = widthsNode.begin(); it != widthsNode.end(); ++it) {
int glyph, glyphWidth;
it.first() >> glyph;
it.second() >> glyphWidth;
m_glyphsSize[glyph].setWidth(glyphWidth);
}
}
// calculate glyphs texture coords
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);
}
} catch (YAML::ParserException& e) {
logError("Malformed font file \"%s\"", file.c_str());
return false;
}
return true;
}
void Font::renderText(const std::string& text,
const Point& startPos)
{
Size boxSize = g_graphics.getScreenSize() - startPos.toSize();
Rect screenCoords(startPos, boxSize);
Font::renderText(text, screenCoords);
}
void Font::renderText(const std::string& text,
const Rect& screenCoords,
int align,
const Color& color,
const Point& startInternalPos,
bool debug)
{
// 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
Size textBoxSize;
Point *glyphsPositions = calculateGlyphsPositions(text, align, &textBoxSize);
for(int i = 0; i < textLenght; ++i) {
int glyph = (int)text[i];
// skip invalid glyphs
if(glyph < 32)
continue;
// calculate initial glyph rect and texture coords
Rect glyphScreenCoords(glyphsPositions[i], m_glyphsSize[glyph]);
Rect glyphTextureCoords = m_glyphsTextureCoords[glyph];
// first translate to align position
if(align & ALIGN_BOTTOM) {
glyphScreenCoords.translate(0, screenCoords.height() - textBoxSize.height());
} else if(align & ALIGN_VERTICAL_CENTER) {
glyphScreenCoords.translate(0, (screenCoords.height() - textBoxSize.height()) / 2);
} else { // ALIGN_TOP
// nothing to do
}
if(align & ALIGN_RIGHT) {
glyphScreenCoords.translate(screenCoords.width() - textBoxSize.width(), 0);
} else if(align & ALIGN_HORIZONTAL_CENTER) {
glyphScreenCoords.translate((screenCoords.width() - textBoxSize.width()) / 2, 0);
} else { // ALIGN_TOP
// nothing to do
}
// only render glyphs that are after startRenderPosition
if(glyphScreenCoords.bottom() < startInternalPos.y || glyphScreenCoords.right() < startInternalPos.x)
continue;
// bound glyph topLeft to startRenderPosition
if(glyphScreenCoords.top() < startInternalPos.y) {
glyphTextureCoords.setTop(glyphTextureCoords.top() + (startInternalPos.y - glyphScreenCoords.top()));
glyphScreenCoords.setTop(startInternalPos.y);
}
if(glyphScreenCoords.left() < startInternalPos.x) {
glyphTextureCoords.setLeft(glyphTextureCoords.left() + (startInternalPos.x - glyphScreenCoords.left()));
glyphScreenCoords.setLeft(startInternalPos.x);
}
// subtract startInternalPos
glyphScreenCoords.translate(-startInternalPos);
// translate rect to screen coords
glyphScreenCoords.translate(screenCoords.topLeft());
// only render if glyph rect is visible on screenCoords
if(!screenCoords.intersects(glyphScreenCoords))
continue;
// bound glyph bottomRight to screenCoords bottomRight
if(glyphScreenCoords.bottom() > screenCoords.bottom()) {
glyphTextureCoords.setBottom(glyphTextureCoords.bottom() + (screenCoords.bottom() - glyphScreenCoords.bottom()));
glyphScreenCoords.setBottom(screenCoords.bottom());
}
if(glyphScreenCoords.right() > screenCoords.right()) {
glyphTextureCoords.setRight(glyphTextureCoords.right() + (screenCoords.right() - glyphScreenCoords.right()));
glyphScreenCoords.setRight(screenCoords.right());
}
// render glyph
g_graphics._drawTexturedRect(glyphScreenCoords, glyphTextureCoords, textureSize);
//g_graphics._drawBoundingRect(glyphScreenCoords, Color(0xFF0000FF));
}
// 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)
{
static Point glyphsPositions[8192];
static int lineWidths[512];
int maxLineWidth = 0;
int lines = 0;
int glyph;
int i;
// protect buffer overflow on glyphsPostions
int numGlyphs = text.length();
if(numGlyphs > 8192)
logFatal("could not calculate glyphs positions, text length is > 8192!");
// calculate lines width
if((align & ALIGN_RIGHT || align & ALIGN_HORIZONTAL_CENTER) || textBoxSize) {
lineWidths[0] = 0;
for(i = 0; i< numGlyphs; ++i) {
glyph = (int)text[i];
if(glyph == (uchar)'\n') {
lineWidths[++lines] = 0;
} else if(glyph >= 32) {
lineWidths[lines] += m_glyphsSize[glyph].width() + m_glyphSpacing.width();
maxLineWidth = std::max(maxLineWidth, lineWidths[lines]);
}
}
}
Point virtualPos(0, m_topMargin);
lines = 0;
for(i = 0; i < numGlyphs; ++i) {
glyph = (int)text[i];
// store current glyph topLeft
glyphsPositions[i] = virtualPos;
// new line or first glyph
if(glyph == (uchar)'\n' || i == 0) {
if(glyph == (uchar)'\n') {
virtualPos.y += m_glyphHeight + m_glyphSpacing.height();
lines++;
}
// calculate start x pos
if(align & ALIGN_RIGHT) {
virtualPos.x = (maxLineWidth - lineWidths[lines]);
} else if(align & ALIGN_HORIZONTAL_CENTER) {
virtualPos.x = (maxLineWidth - lineWidths[lines]) / 2;
} else { // ALIGN_LEFT
virtualPos.x = 0;
}
}
// render only if the glyph is valid
if(glyph >= 32 && glyph != (uchar)'\n') {
virtualPos.x += m_glyphsSize[glyph].width() + m_glyphSpacing.width();
}
}
if(textBoxSize) {
textBoxSize->setWidth(maxLineWidth);
textBoxSize->setHeight(virtualPos.y + m_glyphHeight);
}
return (Point *)glyphsPositions;
}
Size Font::calculateTextRectSize(const std::string& text)
{
Size size;
calculateGlyphsPositions(text, ALIGN_TOP_LEFT, &size);
return size;
}

View File

@@ -0,0 +1,86 @@
/* The MIT License
*
* Copyright (c) 2010 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.
*/
#ifndef FONT_H
#define FONT_H
#include "prerequisites.h"
#include "texture.h"
enum EAlign {
ALIGN_TOP = 1 << 0,
ALIGN_BOTTOM = 1 << 1,
ALIGN_LEFT = 1 << 2,
ALIGN_RIGHT = 1 << 3,
ALIGN_HORIZONTAL_CENTER = 1 << 4,
ALIGN_VERTICAL_CENTER = 1 << 5,
ALIGN_CENTER = ALIGN_HORIZONTAL_CENTER | ALIGN_VERTICAL_CENTER,
ALIGN_TOP_RIGHT = ALIGN_TOP | ALIGN_RIGHT,
ALIGN_TOP_LEFT = ALIGN_TOP | ALIGN_LEFT,
ALIGN_BOTTOM_RIGHT = ALIGN_BOTTOM | ALIGN_RIGHT,
ALIGN_BOTTOM_LEFT = ALIGN_BOTTOM | ALIGN_LEFT
};
class Font
{
public:
Font();
virtual ~Font() { }
/// Load font from file
bool load(const std::string &file);
/// Simple text render starting at pos
void renderText(const std::string& text,
const Point& startPos);
/** Advanced text render
* screenCoords is the rect that will be filled on the screen
* startRenderPosition is the postion to start rendering relative to the text rect
*/
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);
/// 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);
/// Simulate render and calculate text size
Size calculateTextRectSize(const std::string& text);
private:
void calculateGlyphsWidthsAutomatically(const Size& glyphSize);
int m_glyphHeight;
int m_topMargin;
Size m_glyphSpacing;
TexturePtr m_texture;
Rect m_glyphsTextureCoords[256];
Size m_glyphsSize[256];
};
#endif // FONT_H

View File

@@ -0,0 +1,63 @@
/* The MIT License
*
* Copyright (c) 2010 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 "fonts.h"
#include "font.h"
#include "core/resources.h"
Fonts g_fonts;
Font *g_defaultFont = NULL;
void Fonts::init()
{
// load all fonts
std::list<std::string> files = g_resources.getDirectoryFiles("fonts");
foreach(const std::string& file, files) {
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;
}
}
// set default font
g_defaultFont = get("tibia-12px-rounded");
if(!g_defaultFont)
logFatal("Default font not found!");
}
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();
}
logError("Font \"%s\" not found", fontName.c_str());
return NULL;
}

View File

@@ -0,0 +1,52 @@
/* The MIT License
*
* Copyright (c) 2010 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.
*/
#ifndef FONTS_H
#define FONTS_H
#include "prerequisites.h"
#include "font.h"
class Fonts
{
public:
Fonts() { }
/// Initialize all fonts
void init();
/// Get a font by name
Font *get(const std::string& fontName);
/// Terminate all fonts
void terminate() { }
private:
std::map<std::string, std::shared_ptr<Font> > m_fonts;
};
extern Fonts g_fonts;
extern Font *g_defaultFont;
#endif // FONTS_H

View File

@@ -0,0 +1,150 @@
/* The MIT License
*
* Copyright (c) 2010 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 "framebuffer.h"
#include "core/platform.h"
#include "graphics.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>
PFNGLGENFRAMEBUFFERSPROC oglGenFramebuffers = 0;
PFNGLBINDFRAMEBUFFERPROC oglBindFramebuffer = 0;
PFNGLFRAMEBUFFERTEXTURE2DPROC oglFramebufferTexture2D = 0;
PFNGLDELETEFRAMEBUFFERSPROC oglDeleteFramebuffers = 0;
PFNGLCHECKFRAMEBUFFERSTATUSPROC oglCheckFramebufferStatus = 0;
FrameBuffer::FrameBuffer(int width, int height)
{
m_fbo = 0;
m_width = width;
m_height = height;
// create FBO texture
glGenTextures(1, &m_fboTexture);
glBindTexture(GL_TEXTURE_2D, m_fboTexture);
glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// we want bilinear filtering (for a smooth framebuffer)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// use FBO ext only if supported
if(g_graphics.isExtensionSupported("ARB_framebuffer_object")) {
m_fallbackOldImp = false;
if(!oglGenFramebuffers) {
oglGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)Platform::getExtensionProcAddress("glGenFramebuffers");
oglBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)Platform::getExtensionProcAddress("glBindFramebuffer");
oglFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)Platform::getExtensionProcAddress("glFramebufferTexture2D");
oglDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)Platform::getExtensionProcAddress("glDeleteFramebuffers");
oglCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)Platform::getExtensionProcAddress("glCheckFramebufferStatus");
}
// generate FBO
oglGenFramebuffers(1, &m_fbo);
oglBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
// attach 2D texture to this FBO
oglFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_fboTexture, 0);
GLenum status = oglCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
switch(status) {
case GL_FRAMEBUFFER_COMPLETE_EXT:
//ok
break;
default: // fallback to old implementation
m_fallbackOldImp = true;
break;
}
} else {
// otherwise fallback to copy texture from screen implementation
m_fallbackOldImp = true;
}
}
FrameBuffer::~FrameBuffer()
{
glDeleteTextures(1, &m_fboTexture);
if(m_fbo)
oglDeleteFramebuffers(1, &m_fbo);
}
void FrameBuffer::bind()
{
if(!m_fallbackOldImp) {
// bind framebuffer
oglBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
}
// setup framebuffer viewport
glViewport(0, 0, m_width, m_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0f, m_width, 0, m_height);
// back to model view
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// clear framebuffer
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
}
void FrameBuffer::unbind()
{
if(!m_fallbackOldImp) {
// bind back buffer again
oglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
glDrawBuffer(GL_BACK);
glReadBuffer(GL_BACK);
// restore graphics viewport
g_graphics.restoreViewport();
} else {
// copy screen to texture
glBindTexture(GL_TEXTURE_2D, m_fboTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
// restore graphics viewport
g_graphics.restoreViewport();
// clear screen
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
}
}
void FrameBuffer::draw(int x, int y, int width, int height)
{
glBindTexture(GL_TEXTURE_2D, m_fboTexture);
glBegin(GL_QUADS);
glTexCoord2i(0, 0); glVertex2i(x, y);
glTexCoord2i(0, 1); glVertex2i(x, y+height);
glTexCoord2i(1, 1); glVertex2i(x+width, y+height);
glTexCoord2i(1, 0); glVertex2i(x+width, y);
glEnd();
}

View File

@@ -0,0 +1,53 @@
/* The MIT License
*
* Copyright (c) 2010 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.
*/
#ifndef FRAMEBUFFER_H
#define FRAMEBUFFER_H
#include "prerequisites.h"
class FrameBuffer
{
public:
FrameBuffer(int width, int height);
virtual ~FrameBuffer();
/// Bind the framebuffer, everything rendered will be draw on it
void bind();
/// Unbind the framebuffer, render on back buffer again
void unbind();
/// Draw framebuffer
void draw(int x, int y, int width, int height);
private:
uint m_fboTexture;
uint m_fbo;
bool m_fallbackOldImp;
int m_width;
int m_height;
};
#endif // FRAMEBUFFER_H

View File

@@ -0,0 +1,307 @@
/* The MIT License
*
* Copyright (c) 2010 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 "graphics.h"
#include "texture.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>
Graphics g_graphics;
void Graphics::init()
{
// setup opengl
glEnable(GL_ALPHA_TEST); // enable alpha by default
glAlphaFunc(GL_GREATER, 0.0f); // default alpha mode
glDisable(GL_DEPTH_TEST); // we are rendering 2D only, we don't need it
glEnable(GL_TEXTURE_2D); // enable textures by default
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glShadeModel(GL_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
logInfo("GPU %s", (const char*)glGetString(GL_RENDERER));
logInfo("OpenGL %s", (const char*)glGetString(GL_VERSION));
}
void Graphics::terminate()
{
}
bool Graphics::isExtensionSupported(const char *extension)
{
const GLubyte *extensions = NULL;
const GLubyte *start;
GLubyte *where, *terminator;
where = (GLubyte *)strchr(extension, ' ');
if(where || *extension == '\0')
return 0;
extensions = glGetString(GL_EXTENSIONS);
start = extensions;
while(true) {
where = (GLubyte *) strstr((const char *)start, extension);
if(!where)
break;
terminator = where + strlen(extension);
if(where == start || *(where - 1) == ' ')
if(*terminator == ' ' || *terminator == '\0')
return 1;
start = terminator;
}
return 0;
}
void Graphics::resize(const Size& size)
{
m_screenSize = size;
restoreViewport();
}
void Graphics::restoreViewport()
{
const int& width = m_screenSize.width();
const int& height = m_screenSize.height();
// resize gl viewport
glViewport(0, 0, width, height);
/*
0,0---------0,w
| |
| |
| |
h,0---------h,w
*/
// setup view region like above
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0f, width, height, 0.0f);
// back to model view
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void Graphics::beginRender()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
}
void Graphics::endRender()
{
}
void Graphics::setColor(const Color& color)
{
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();
float textureRight = 0.0f;
float textureBottom = 1.0f;
float textureTop = 0.0f;
float textureLeft = 1.0f;
if(!textureCoords.isEmpty()) {
textureRight = (float)(textureCoords.right() + 1) / textureSize.width();
textureBottom = (float)(textureCoords.bottom() + 1) / textureSize.height();
textureTop = (float)textureCoords.top() / textureSize.height();
textureLeft = (float)textureCoords.left() / textureSize.width();
}
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)
{
if(screenCoords.size().isEmpty())
return;
// render many repeated texture rects
Rect virtualScreenCoords(0,0,screenCoords.size());
for(int y = 0; y <= virtualScreenCoords.height(); y += textureCoords.height()) {
for(int x = 0; x <= virtualScreenCoords.width(); x += textureCoords.width()) {
Rect partialCoords(x, y, textureCoords.size());
Rect partialTextureCoords = textureCoords;
// partialCoords to screenCoords bottomRight
if(partialCoords.bottom() > virtualScreenCoords.bottom()) {
partialTextureCoords.setBottom(partialTextureCoords.bottom() + (virtualScreenCoords.bottom() - partialCoords.bottom()));
partialCoords.setBottom(virtualScreenCoords.bottom());
}
if(partialCoords.right() > virtualScreenCoords.right()) {
partialTextureCoords.setRight(partialTextureCoords.right() + (virtualScreenCoords.right() - partialCoords.right()));
partialCoords.setRight(virtualScreenCoords.right());
}
partialCoords.translate(screenCoords.topLeft());
_drawTexturedRect(partialCoords, partialTextureCoords, textureSize);
}
}
}
void Graphics::drawColoredRect(const Rect& screenCoords, const Color& color)
{
if(screenCoords.size().isEmpty())
return;
glDisable(GL_TEXTURE_2D);
setColor(color);
// rect correction for opengl
int right = screenCoords.right() + 1;
int bottom = screenCoords.bottom() + 1;
int top = screenCoords.top();
int left = screenCoords.left();
glBegin(GL_QUADS);
glVertex2i(left, top);
glVertex2i(left, bottom);
glVertex2i(right, bottom);
glVertex2i(right, top);
glEnd();
glEnable(GL_TEXTURE_2D);
resetColor();
}
void Graphics::drawBoundingRect(const Rect& screenCoords, const Color& color, int innerLineWidth)
{
if(2 * innerLineWidth > screenCoords.height())
return;
glDisable(GL_TEXTURE_2D);
setColor(color);
// rect correction for opengl
int right = screenCoords.right()+1;
int bottom = screenCoords.bottom()+1;
int top = screenCoords.top();
int left = screenCoords.left();
glBegin(GL_QUADS);
// top line
glVertex2i(left, top);
glVertex2i(left, top + innerLineWidth);
glVertex2i(right, top + innerLineWidth);
glVertex2i(right, top);
// left
glVertex2i(left, screenCoords.top() + innerLineWidth);
glVertex2i(left, bottom - innerLineWidth);
glVertex2i(left + innerLineWidth, bottom - innerLineWidth);
glVertex2i(left + innerLineWidth, screenCoords.top() + innerLineWidth);
// bottom line
glVertex2i(left, bottom);
glVertex2i(left, bottom - innerLineWidth);
glVertex2i(right, bottom - innerLineWidth);
glVertex2i(right, bottom);
// right line
glVertex2i(right , top + innerLineWidth);
glVertex2i(right , bottom - innerLineWidth);
glVertex2i(right - innerLineWidth, bottom - innerLineWidth);
glVertex2i(right - innerLineWidth, top + innerLineWidth);
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

@@ -0,0 +1,79 @@
/* The MIT License
*
* Copyright (c) 2010 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.
*/
#ifndef GRAPHICS_H
#define GRAPHICS_H
#include "prerequisites.h"
class Texture;
class Graphics
{
public:
Graphics() { }
void init();
void terminate();
/// Check if a GL extension is supported
bool isExtensionSupported(const char *extension);
/// Called after every window resize
void resize(const Size& size);
/// Restore original viewport
void restoreViewport();
/// Called before every render
void beginRender();
/// Called after every render
void endRender();
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();
private:
Size m_screenSize;
};
extern Graphics g_graphics;
#endif // GRAPHICS_H

View File

@@ -0,0 +1,50 @@
/* The MIT License
*
* Copyright (c) 2010 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 "image.h"
#include "graphics.h"
#include "textures.h"
Image::Image(const std::string& texture)
{
m_texture = g_textures.get(texture);
}
Image::Image(const std::string& texture, Rect textureCoords) :
m_textureCoords(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);
}

View File

@@ -0,0 +1,49 @@
/* The MIT License
*
* Copyright (c) 2010 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.
*/
#ifndef IMAGE_H
#define IMAGE_H
#include "prerequisites.h"
#include "texture.h"
class Image
{
public:
Image(TexturePtr texture) : m_texture(texture) { }
Image(TexturePtr texture, Rect textureCoords) : m_texture(texture), m_textureCoords(textureCoords) { }
Image(const std::string& texture);
Image(const std::string& texture, Rect textureCoords);
void enableBilinearFilter();
virtual void draw(const Rect& screenCoords);
protected:
TexturePtr m_texture;
Rect m_textureCoords;
};
typedef std::shared_ptr<Image> ImagePtr;
#endif // IMAGE_H

View File

@@ -0,0 +1,82 @@
/* The MIT License
*
* Copyright (c) 2010 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 "texture.h"
#include <GL/gl.h>
#include <GL/glext.h>
Texture::Texture(int width, int height, int components, uchar *pixels)
{
m_size.setWidth(width);
m_size.setHeight(height);
glGenTextures(1, &m_textureId);
glBindTexture(GL_TEXTURE_2D, m_textureId);
GLenum format = 0;
switch(components) {
case 4:
format = GL_RGBA;
break;
case 3:
format = GL_RGB;
break;
case 2:
format = GL_LUMINANCE_ALPHA;
break;
case 1:
format = GL_LUMINANCE;
break;
}
glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, format, GL_UNSIGNED_BYTE, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
Texture::~Texture()
{
if(m_textureId)
glDeleteTextures(1, &m_textureId);
}
void Texture::enableBilinearFilter()
{
glBindTexture(GL_TEXTURE_2D, m_textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
uchar *Texture::getPixels()
{
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);
return pixels;
}

View File

@@ -0,0 +1,57 @@
/* The MIT License
*
* Copyright (c) 2010 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.
*/
#ifndef TEXTURE_H
#define TEXTURE_H
#include "prerequisites.h"
class Textures;
class Texture
{
public:
/// Create a texture, width and height must be a multiple of 2
Texture(int width, int height, int components, uchar *pixels = NULL);
virtual ~Texture();
/// Enable texture bilinear filter (smooth scaled textures)
void enableBilinearFilter();
/// Get OpenGL texture id
uint getTextureId() const { return m_textureId; }
/// Copy pixels from OpenGL texture
uchar *getPixels();
const Size& getSize() const { return m_size; }
private:
uint m_textureId;
Size m_size;
};
typedef std::shared_ptr<Texture> TexturePtr;
#endif // TEXTURE_H

View File

@@ -0,0 +1,139 @@
/* The MIT License
*
* Copyright (c) 2010 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 "textureloader.h"
#include "texture.h"
#include <png.h>
struct File
{
File() {
offset = 0;
}
uchar *data;
uint offset;
};
void png_read_from_mem(png_structp png_ptr, png_bytep data, png_size_t size)
{
File *file = (File*)png_get_io_ptr(png_ptr);
/* Copy data from image buffer */
memcpy(data, file->data + file->offset, size);
/* Advance in the file */
file->offset += size;
}
Texture *TextureLoader::loadPNG(uchar *fileData)
{
File file;
file.data = fileData;
if(png_sig_cmp(file.data, 0, 8))
return NULL;
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr)
return NULL;
png_infop info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr) {
png_destroy_read_struct(&png_ptr, NULL, NULL);
return NULL;
}
if(setjmp(png_jmpbuf(png_ptr))) {
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return NULL;
}
// Set "png_read" callback function and give source of data
png_set_read_fn(png_ptr, (png_voidp *)&file, png_read_from_mem);
png_read_info(png_ptr, info_ptr);
int bitDepth = png_get_bit_depth(png_ptr, info_ptr);
int colourType = png_get_color_type(png_ptr, info_ptr);
if(colourType == PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr);
if(bitDepth < 8 && (colourType == PNG_COLOR_TYPE_GRAY || colourType == PNG_COLOR_TYPE_GRAY_ALPHA))
png_set_expand_gray_1_2_4_to_8(png_ptr);
if(png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png_ptr);
if(bitDepth < 8)
png_set_packing(png_ptr);
else if(bitDepth == 16)
png_set_strip_16(png_ptr);
png_read_update_info(png_ptr, info_ptr);
png_uint_32 width, height;
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bitDepth, &colourType, NULL, NULL, NULL);
int components;
switch(colourType)
{
case PNG_COLOR_TYPE_GRAY:
components = 1;
break;
case PNG_COLOR_TYPE_GRAY_ALPHA:
components = 2;
break;
case PNG_COLOR_TYPE_RGB:
components = 3;
break;
case PNG_COLOR_TYPE_RGB_ALPHA:
components = 4;
break;
default:
if(png_ptr)
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
return NULL;
};
uchar *pixels = new uchar[width * height * components];
png_bytep *row_pointers = new png_bytep[height];
for(uint i = 0; i < height; ++i)
row_pointers[i] = (png_bytep)(pixels + (i * width * components));
png_read_image(png_ptr, row_pointers);
png_read_end(png_ptr, NULL);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
delete[] row_pointers;
Texture *texture = new Texture(width, height, components, pixels);
delete[] pixels;
return texture;
}

View File

@@ -0,0 +1,38 @@
/* The MIT License
*
* Copyright (c) 2010 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.
*/
#ifndef TEXTURELOADER_H
#define TEXTURELOADER_H
#include "prerequisites.h"
class Texture;
namespace TextureLoader
{
/// Load a png textures using libpng
Texture *loadPNG(uchar *fileData);
}
#endif // TEXTURELOADER_H

View File

@@ -0,0 +1,65 @@
/* The MIT License
*
* Copyright (c) 2010 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 "textures.h"
#include "core/resources.h"
#include "textureloader.h"
Textures g_textures;
TexturePtr Textures::get(const std::string& textureFile)
{
TexturePtr texture;
// check if the texture is already loaded
auto it = m_texturesMap.find(textureFile);
if(it != m_texturesMap.end()) {
if(it->second.expired())
m_texturesMap.erase(it);
else
texture = it->second.lock();
}
if(!texture) { // load texture
// currently only png textures are supported
if(!boost::ends_with(textureFile, ".png")) {
logFatal("Unable to load texture %s, file format no supported.", textureFile.c_str());
return texture;
}
uint fileSize;
uchar *textureFileData = g_resources.loadFile(textureFile, &fileSize);
if(!textureFileData) {
logFatal("Unable to load texture %s, file could not be read.", textureFile.c_str());
return texture;
}
texture = TexturePtr(TextureLoader::loadPNG(textureFileData));
if(!texture)
logFatal("Unable to load texture %s, loading error.", textureFile.c_str());
delete[] textureFileData;
}
return texture;
}

View File

@@ -0,0 +1,48 @@
/* The MIT License
*
* Copyright (c) 2010 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.
*/
#ifndef TEXTURES_H
#define TEXTURES_H
#include "prerequisites.h"
#include "texture.h"
typedef std::weak_ptr<Texture> TextureWeakPtr;
class Textures
{
public:
Textures() { }
/// Load a texture from file, if it was already loaded it will be retrieved from cache
TexturePtr get(const std::string& textureFile);
private:
typedef std::map<std::string, TextureWeakPtr> TexturesMap;
TexturesMap m_texturesMap;
};
extern Textures g_textures;
#endif // TEXTURES_H