mirror of
https://github.com/edubart/otclient.git
synced 2025-10-19 05:53:26 +02:00
refactoring paths and includes
This commit is contained in:
153
src/framework/graphics/borderedimage.cpp
Normal file
153
src/framework/graphics/borderedimage.cpp
Normal 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();
|
||||
}
|
87
src/framework/graphics/borderedimage.h
Normal file
87
src/framework/graphics/borderedimage.h
Normal 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
|
317
src/framework/graphics/font.cpp
Normal file
317
src/framework/graphics/font.cpp
Normal 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;
|
||||
}
|
86
src/framework/graphics/font.h
Normal file
86
src/framework/graphics/font.h
Normal 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
|
63
src/framework/graphics/fonts.cpp
Normal file
63
src/framework/graphics/fonts.cpp
Normal 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;
|
||||
}
|
||||
|
52
src/framework/graphics/fonts.h
Normal file
52
src/framework/graphics/fonts.h
Normal 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
|
150
src/framework/graphics/framebuffer.cpp
Normal file
150
src/framework/graphics/framebuffer.cpp
Normal 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();
|
||||
}
|
53
src/framework/graphics/framebuffer.h
Normal file
53
src/framework/graphics/framebuffer.h
Normal 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
|
307
src/framework/graphics/graphics.cpp
Normal file
307
src/framework/graphics/graphics.cpp
Normal 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);
|
||||
}
|
79
src/framework/graphics/graphics.h
Normal file
79
src/framework/graphics/graphics.h
Normal 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
|
50
src/framework/graphics/image.cpp
Normal file
50
src/framework/graphics/image.cpp
Normal 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);
|
||||
}
|
||||
|
||||
|
49
src/framework/graphics/image.h
Normal file
49
src/framework/graphics/image.h
Normal 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
|
82
src/framework/graphics/texture.cpp
Normal file
82
src/framework/graphics/texture.cpp
Normal 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;
|
||||
}
|
57
src/framework/graphics/texture.h
Normal file
57
src/framework/graphics/texture.h
Normal 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
|
139
src/framework/graphics/textureloader.cpp
Normal file
139
src/framework/graphics/textureloader.cpp
Normal 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;
|
||||
}
|
38
src/framework/graphics/textureloader.h
Normal file
38
src/framework/graphics/textureloader.h
Normal 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
|
65
src/framework/graphics/textures.cpp
Normal file
65
src/framework/graphics/textures.cpp
Normal 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;
|
||||
}
|
48
src/framework/graphics/textures.h
Normal file
48
src/framework/graphics/textures.h
Normal 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
|
Reference in New Issue
Block a user