animated texture
This commit is contained in:
parent
c6753747fb
commit
42eae9afd8
|
@ -22,7 +22,7 @@ MESSAGE(STATUS "BUILD TYPE: " ${CMAKE_BUILD_TYPE})
|
||||||
|
|
||||||
# setup compiler options
|
# setup compiler options
|
||||||
IF(CMAKE_COMPILER_IS_GNUCXX)
|
IF(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
SET(CMAKE_CXX_FLAGS "-Wall -Wextra -Werror -Wno-unused-parameter -std=gnu++0x")
|
SET(CMAKE_CXX_FLAGS "-Wall -Wextra -Werror -Wno-unused-parameter -Wno-unused-but-set-variable -std=gnu++0x")
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "-O1 -g -ggdb -fno-inline")
|
SET(CMAKE_CXX_FLAGS_DEBUG "-O1 -g -ggdb -fno-inline")
|
||||||
SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -Wl,-s")
|
SET(CMAKE_CXX_FLAGS_RELEASE "-O2 -Wl,-s")
|
||||||
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
|
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
|
||||||
|
@ -76,6 +76,7 @@ SET(SOURCES
|
||||||
src/framework/util/util.cpp
|
src/framework/util/util.cpp
|
||||||
src/framework/util/logger.cpp
|
src/framework/util/logger.cpp
|
||||||
src/framework/util/rsa.cpp
|
src/framework/util/rsa.cpp
|
||||||
|
src/framework/util/apngloader.cpp
|
||||||
|
|
||||||
# framework graphics
|
# framework graphics
|
||||||
src/framework/graphics/image.cpp
|
src/framework/graphics/image.cpp
|
||||||
|
@ -85,6 +86,7 @@ SET(SOURCES
|
||||||
src/framework/graphics/fonts.cpp
|
src/framework/graphics/fonts.cpp
|
||||||
src/framework/graphics/textureloader.cpp
|
src/framework/graphics/textureloader.cpp
|
||||||
src/framework/graphics/texture.cpp
|
src/framework/graphics/texture.cpp
|
||||||
|
src/framework/graphics/animatedtexture.cpp
|
||||||
src/framework/graphics/textures.cpp
|
src/framework/graphics/textures.cpp
|
||||||
src/framework/graphics/graphics.cpp
|
src/framework/graphics/graphics.cpp
|
||||||
src/framework/graphics/textarea.cpp
|
src/framework/graphics/textarea.cpp
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,8 @@
|
||||||
|
glyph height: 14
|
||||||
|
glyph spacing: [0, 1]
|
||||||
|
top margin: 0
|
||||||
|
image: sans-11px-bold.png
|
||||||
|
image glyph size: [16, 16]
|
||||||
|
|
||||||
|
glyph widths:
|
||||||
|
32: 4
|
Binary file not shown.
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 10 KiB |
|
@ -3,7 +3,6 @@ glyph spacing: [0, 1]
|
||||||
top margin: 0
|
top margin: 0
|
||||||
image: sans-11px.png
|
image: sans-11px.png
|
||||||
image glyph size: [16, 16]
|
image glyph size: [16, 16]
|
||||||
first glyph: 0
|
|
||||||
|
|
||||||
glyph widths:
|
glyph widths:
|
||||||
32: 4
|
32: 4
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,8 @@
|
||||||
|
glyph height: 14
|
||||||
|
glyph spacing: [0, 1]
|
||||||
|
top margin: 0
|
||||||
|
image: sans-12px-bold.png
|
||||||
|
image glyph size: [20, 16]
|
||||||
|
|
||||||
|
glyph widths:
|
||||||
|
32: 4
|
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -0,0 +1,8 @@
|
||||||
|
glyph height: 16
|
||||||
|
glyph spacing: [0, 1]
|
||||||
|
top margin: 0
|
||||||
|
image: sans-12px.png
|
||||||
|
image glyph size: [20, 16]
|
||||||
|
|
||||||
|
glyph widths:
|
||||||
|
32: 4
|
|
@ -39,6 +39,7 @@ window#infoWindow:
|
||||||
|
|
||||||
button#websiteButton:
|
button#websiteButton:
|
||||||
text: Github Page
|
text: Github Page
|
||||||
|
size: [80,22]
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
margin.bottom: 9
|
margin.bottom: 9
|
||||||
|
|
|
@ -5,6 +5,13 @@ panel#background:
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
panel#icos4d:
|
||||||
|
skin: icos4d
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.top: parent.top
|
||||||
|
margin.left: 60
|
||||||
|
margin.top: 70
|
||||||
|
|
||||||
panel#mainMenu:
|
panel#mainMenu:
|
||||||
skin: roundedGridPanel
|
skin: roundedGridPanel
|
||||||
size: [117, 171]
|
size: [117, 171]
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
default font: sans-11px
|
default font: sans-11px-bold
|
||||||
default font color: [0, 115, 234, 255]
|
default font color: [51, 51, 51, 255]
|
||||||
|
|
||||||
buttons:
|
buttons:
|
||||||
default:
|
default:
|
||||||
|
@ -53,6 +53,9 @@ panels:
|
||||||
image: lightness/background.png
|
image: lightness/background.png
|
||||||
antialised: true
|
antialised: true
|
||||||
|
|
||||||
|
icos4d:
|
||||||
|
image: lightness/icos4d.png
|
||||||
|
|
||||||
roundedGridPanel:
|
roundedGridPanel:
|
||||||
bordered image:
|
bordered image:
|
||||||
source: lightness/menupanel.png
|
source: lightness/menupanel.png
|
||||||
|
@ -81,10 +84,11 @@ panels:
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
default:
|
default:
|
||||||
font color: [0, 115, 234, 255]
|
font: sans-12px
|
||||||
|
|
||||||
windows:
|
windows:
|
||||||
default:
|
default:
|
||||||
|
font: sans-12px-bold
|
||||||
font color: [80, 80, 80, 255]
|
font color: [80, 80, 80, 255]
|
||||||
head:
|
head:
|
||||||
text align: left
|
text align: left
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 968 KiB |
|
@ -32,6 +32,7 @@
|
||||||
#include <net/connection.h>
|
#include <net/connection.h>
|
||||||
#include <script/luascript.h>
|
#include <script/luascript.h>
|
||||||
#include <ui/uiskins.h>
|
#include <ui/uiskins.h>
|
||||||
|
#include <graphics/textures.h>
|
||||||
|
|
||||||
Engine g_engine;
|
Engine g_engine;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/* 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/animatedtexture.h>
|
||||||
|
|
||||||
|
#include <GL/gl.h>
|
||||||
|
#include <core/engine.h>
|
||||||
|
#include <core/dispatcher.h>
|
||||||
|
|
||||||
|
AnimatedTexture::AnimatedTexture(int width, int height, int components, int numFrames, uchar *framesPixels, int *framesDelay) :
|
||||||
|
Texture(),
|
||||||
|
m_numFrames(numFrames)
|
||||||
|
{
|
||||||
|
m_size.setSize(width, height);
|
||||||
|
|
||||||
|
m_framesTextureId = new uint[numFrames];
|
||||||
|
m_framesDelay = new int[numFrames];
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenTextures(numFrames, m_framesTextureId);
|
||||||
|
|
||||||
|
for(int i=0;i<numFrames;++i) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_framesTextureId[i]);
|
||||||
|
|
||||||
|
// load the pixels into opengl memory
|
||||||
|
uchar *framePixels = framesPixels + (i*height*width*components);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, components, width, height, 0, format, GL_UNSIGNED_BYTE, framePixels);
|
||||||
|
|
||||||
|
// disable texture border
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
// nearest filtering
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
|
||||||
|
m_framesDelay[i] = framesDelay[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
m_currentFrame = -1;
|
||||||
|
g_dispatcher.scheduleTask(boost::bind(&AnimatedTexture::processAnimation, this), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimatedTexture::~AnimatedTexture()
|
||||||
|
{
|
||||||
|
glDeleteTextures(m_numFrames, m_framesTextureId);
|
||||||
|
delete[] m_framesTextureId;
|
||||||
|
delete[] m_framesDelay;
|
||||||
|
m_textureId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTexture::enableBilinearFilter()
|
||||||
|
{
|
||||||
|
for(int i=0;i<m_numFrames;++i) {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_framesTextureId[i]);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTexture::processAnimation()
|
||||||
|
{
|
||||||
|
m_currentFrame++;
|
||||||
|
if(m_currentFrame >= m_numFrames)
|
||||||
|
m_currentFrame = 0;
|
||||||
|
m_textureId = m_framesTextureId[m_currentFrame];
|
||||||
|
AnimatedTexturePtr me = boost::static_pointer_cast<AnimatedTexture>(shared_from_this());
|
||||||
|
if(me.use_count() > 1)
|
||||||
|
g_dispatcher.scheduleTask(boost::bind(&AnimatedTexture::processAnimation, me), m_framesDelay[m_currentFrame]);
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/* 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 ANIMATEDTEXTURE_H
|
||||||
|
#define ANIMATEDTEXTURE_H
|
||||||
|
|
||||||
|
#include <prerequisites.h>
|
||||||
|
#include <graphics/texture.h>
|
||||||
|
|
||||||
|
class AnimatedTexture : public Texture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AnimatedTexture(int width, int height, int components, int numFrames, uchar *framesPixels, int *framesDelay);
|
||||||
|
virtual ~AnimatedTexture();
|
||||||
|
|
||||||
|
void enableBilinearFilter();
|
||||||
|
void processAnimation();
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint *m_framesTextureId;
|
||||||
|
int *m_framesDelay;
|
||||||
|
int m_numFrames;
|
||||||
|
int m_currentFrame;
|
||||||
|
int m_lastAnimCheckTicks;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<AnimatedTexture> AnimatedTexturePtr;
|
||||||
|
typedef boost::weak_ptr<AnimatedTexture> AnimatedTextureWeakPtr;
|
||||||
|
|
||||||
|
#endif // ANIMATEDTEXTURE_H
|
|
@ -40,22 +40,24 @@ void Font::calculateGlyphsWidthsAutomatically(const Size& glyphSize)
|
||||||
glyphSize.width(),
|
glyphSize.width(),
|
||||||
m_glyphHeight);
|
m_glyphHeight);
|
||||||
int width = glyphSize.width();
|
int width = glyphSize.width();
|
||||||
for(int x = glyphCoords.left() + 2; x <= glyphCoords.right(); ++x) {
|
int lastColumnFilledPixels = 0;
|
||||||
bool allAlpha = true;
|
for(int x = glyphCoords.left() + 1; x <= glyphCoords.right(); ++x) {
|
||||||
|
int columnFilledPixels = 0;
|
||||||
|
|
||||||
// check if all vertical pixels are alpha
|
// check if all vertical pixels are alpha
|
||||||
for(int y = glyphCoords.top(); y <= glyphCoords.bottom(); ++y) {
|
for(int y = glyphCoords.top(); y <= glyphCoords.bottom(); ++y) {
|
||||||
if(texturePixels[(y * m_texture->getSize().width() * 4) + (x*4) + 3] != 0) {
|
if(texturePixels[(y * m_texture->getSize().width() * 4) + (x*4) + 3] != 0)
|
||||||
allAlpha = false;
|
columnFilledPixels++;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if all pixels were alpha we found the width
|
// if all pixels were alpha we found the width
|
||||||
if(allAlpha) {
|
if(columnFilledPixels == 0) {
|
||||||
width = x - glyphCoords.left();
|
width = x - glyphCoords.left();
|
||||||
|
if(m_glyphHeight >= 16 && lastColumnFilledPixels >= m_glyphHeight/3)
|
||||||
|
width += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
lastColumnFilledPixels = columnFilledPixels;
|
||||||
}
|
}
|
||||||
// store glyph size
|
// store glyph size
|
||||||
m_glyphsSize[glyph].setSize(width, m_glyphHeight);
|
m_glyphsSize[glyph].setSize(width, m_glyphHeight);
|
||||||
|
@ -175,6 +177,20 @@ void Font::renderText(const std::string& text,
|
||||||
// nothing to do
|
// nothing to do
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only render glyphs that are after 0, 0
|
||||||
|
if(glyphScreenCoords.bottom() < 0 || glyphScreenCoords.right() < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// bound glyph topLeft to 0,0 if needed
|
||||||
|
if(glyphScreenCoords.top() < 0) {
|
||||||
|
glyphTextureCoords.setTop(glyphTextureCoords.top() - glyphScreenCoords.top());
|
||||||
|
glyphScreenCoords.setTop(0);
|
||||||
|
}
|
||||||
|
if(glyphScreenCoords.left() < 0) {
|
||||||
|
glyphTextureCoords.setLeft(glyphTextureCoords.left() - glyphScreenCoords.left());
|
||||||
|
glyphScreenCoords.setLeft(0);
|
||||||
|
}
|
||||||
|
|
||||||
// translate rect to screen coords
|
// translate rect to screen coords
|
||||||
glyphScreenCoords.translate(screenCoords.topLeft());
|
glyphScreenCoords.translate(screenCoords.topLeft());
|
||||||
|
|
||||||
|
@ -212,7 +228,7 @@ const std::vector<Point>& Font::calculateGlyphsPositions(const std::string& text
|
||||||
// return if there is no text
|
// return if there is no text
|
||||||
if(textLength == 0) {
|
if(textLength == 0) {
|
||||||
if(textBoxSize)
|
if(textBoxSize)
|
||||||
textBoxSize->setSize(0,0);
|
textBoxSize->setSize(0,m_glyphHeight);
|
||||||
return glyphsPositions;
|
return glyphsPositions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,8 +128,10 @@ void Graphics::endRender()
|
||||||
|
|
||||||
void Graphics::disableDrawing()
|
void Graphics::disableDrawing()
|
||||||
{
|
{
|
||||||
|
if(m_drawMode != DRAW_NONE) {
|
||||||
glEnd();
|
glEnd();
|
||||||
m_drawMode = DRAW_NONE;
|
m_drawMode = DRAW_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::drawTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color)
|
void Graphics::drawTexturedRect(const Rect& screenCoords, const TexturePtr& texture, const Rect& textureCoords, const Color& color)
|
||||||
|
|
|
@ -146,10 +146,22 @@ void TextArea::recalculate()
|
||||||
m_startInternalPos = Point(0,0);
|
m_startInternalPos = Point(0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_drawArea.setLeft(m_screenCoords.left());
|
m_drawArea = m_screenCoords;
|
||||||
m_drawArea.setTop(m_screenCoords.top()+m_font->getTopMargin());
|
|
||||||
m_drawArea.setRight(m_screenCoords.right());
|
if(m_align & AlignBottom) {
|
||||||
m_drawArea.setBottom(m_screenCoords.bottom());
|
m_drawArea.translate(0, m_screenCoords.height() - textBoxSize.height());
|
||||||
|
} else if(m_align & AlignVerticalCenter) {
|
||||||
|
m_drawArea.translate(0, (m_screenCoords.height() - textBoxSize.height()) / 2);
|
||||||
|
} else { // AlignTop
|
||||||
|
}
|
||||||
|
|
||||||
|
if(m_align & AlignRight) {
|
||||||
|
m_drawArea.translate(m_screenCoords.width() - textBoxSize.width(), 0);
|
||||||
|
} else if(m_align & AlignHorizontalCenter) {
|
||||||
|
m_drawArea.translate((m_screenCoords.width() - textBoxSize.width()) / 2, 0);
|
||||||
|
} else { // AlignLeft
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
for(int i = 0; i < textLength; ++i) {
|
for(int i = 0; i < textLength; ++i) {
|
||||||
glyph = (uchar)m_text[i];
|
glyph = (uchar)m_text[i];
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include <graphics/texture.h>
|
#include <graphics/texture.h>
|
||||||
|
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <GL/glext.h>
|
|
||||||
|
|
||||||
Texture::Texture(int width, int height, int components, uchar *pixels)
|
Texture::Texture(int width, int height, int components, uchar *pixels)
|
||||||
{
|
{
|
||||||
|
@ -85,3 +84,4 @@ uchar *Texture::getPixels()
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
return pixels;
|
return pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include <prerequisites.h>
|
#include <prerequisites.h>
|
||||||
|
|
||||||
class Texture
|
class Texture : public boost::enable_shared_from_this<Texture>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Create a texture, width and height must be a multiple of 2
|
/// Create a texture, width and height must be a multiple of 2
|
||||||
|
@ -35,17 +35,18 @@ public:
|
||||||
virtual ~Texture();
|
virtual ~Texture();
|
||||||
|
|
||||||
/// Enable texture bilinear filter (smooth scaled textures)
|
/// Enable texture bilinear filter (smooth scaled textures)
|
||||||
void enableBilinearFilter();
|
virtual void enableBilinearFilter();
|
||||||
|
|
||||||
/// Get OpenGL texture id
|
/// Get OpenGL texture id
|
||||||
uint getTextureId() const { return m_textureId; }
|
virtual uint getTextureId() const { return m_textureId; }
|
||||||
|
|
||||||
/// Copy pixels from OpenGL texture
|
/// Copy pixels from OpenGL texture
|
||||||
uchar *getPixels();
|
uchar *getPixels();
|
||||||
|
|
||||||
const Size& getSize() const { return m_size; }
|
const Size& getSize() const { return m_size; }
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
|
Texture() { }
|
||||||
uint m_textureId;
|
uint m_textureId;
|
||||||
Size m_size;
|
Size m_size;
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,116 +25,22 @@
|
||||||
#include <prerequisites.h>
|
#include <prerequisites.h>
|
||||||
#include <graphics/textureloader.h>
|
#include <graphics/textureloader.h>
|
||||||
#include <graphics/texture.h>
|
#include <graphics/texture.h>
|
||||||
|
#include <util/apngloader.h>
|
||||||
|
#include "animatedtexture.h"
|
||||||
|
|
||||||
#include <png.h>
|
TexturePtr TextureLoader::loadPNG(uchar *fileData, uint fileSize)
|
||||||
|
|
||||||
struct File
|
|
||||||
{
|
{
|
||||||
File() {
|
TexturePtr texture;
|
||||||
offset = 0;
|
|
||||||
|
apng_data apng;
|
||||||
|
if(load_apng(fileData, fileSize, &apng) == 0) {
|
||||||
|
if(apng.num_frames > 1) { // animated texture
|
||||||
|
uchar *framesdata = apng.pdata + (apng.first_frame * apng.width * apng.height * apng.bpp);
|
||||||
|
texture = TexturePtr(new AnimatedTexture(apng.width, apng.height, apng.bpp, apng.num_frames, framesdata, (int*)apng.frames_delay));
|
||||||
|
} else
|
||||||
|
texture = TexturePtr(new Texture(apng.width, apng.height, apng.bpp, apng.pdata));
|
||||||
|
free_apng(&apng);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,13 @@
|
||||||
#define TEXTURELOADER_H
|
#define TEXTURELOADER_H
|
||||||
|
|
||||||
#include <prerequisites.h>
|
#include <prerequisites.h>
|
||||||
|
#include <graphics/texture.h>
|
||||||
class Texture;
|
|
||||||
|
|
||||||
class TextureLoader
|
class TextureLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Load a png textures using libpng
|
/// Load a png textures using libpng
|
||||||
static Texture *loadPNG(uchar *fileData);
|
static TexturePtr loadPNG(uchar *fileData, uint fileSize);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TEXTURELOADER_H
|
#endif // TEXTURELOADER_H
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <core/resources.h>
|
#include <core/resources.h>
|
||||||
#include <graphics/textures.h>
|
#include <graphics/textures.h>
|
||||||
#include <graphics/textureloader.h>
|
#include <graphics/textureloader.h>
|
||||||
|
#include <core/dispatcher.h>
|
||||||
|
|
||||||
Textures g_textures;
|
Textures g_textures;
|
||||||
|
|
||||||
|
@ -34,10 +35,10 @@ TexturePtr Textures::get(const std::string& textureFile)
|
||||||
TexturePtr texture;
|
TexturePtr texture;
|
||||||
|
|
||||||
// check if the texture is already loaded
|
// check if the texture is already loaded
|
||||||
auto it = m_texturesMap.find(textureFile);
|
auto it = m_textures.find(textureFile);
|
||||||
if(it != m_texturesMap.end()) {
|
if(it != m_textures.end()) {
|
||||||
if(it->second.expired())
|
if(it->second.expired())
|
||||||
m_texturesMap.erase(it);
|
m_textures.erase(it);
|
||||||
else
|
else
|
||||||
texture = it->second.lock();
|
texture = it->second.lock();
|
||||||
}
|
}
|
||||||
|
@ -60,11 +61,10 @@ TexturePtr Textures::get(const std::string& textureFile)
|
||||||
|
|
||||||
|
|
||||||
// load the texture
|
// load the texture
|
||||||
texture = TexturePtr(TextureLoader::loadPNG(textureFileData));
|
texture = TexturePtr(TextureLoader::loadPNG(textureFileData, fileSize));
|
||||||
if(!texture)
|
if(!texture)
|
||||||
flogError("ERROR: Unable to load texture %s", textureFile.c_str());
|
flogError("ERROR: Unable to load texture %s", textureFile.c_str());
|
||||||
delete[] textureFileData;
|
delete[] textureFileData;
|
||||||
}
|
}
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include <prerequisites.h>
|
#include <prerequisites.h>
|
||||||
#include <graphics/texture.h>
|
#include <graphics/texture.h>
|
||||||
|
#include <graphics/animatedtexture.h>
|
||||||
|
|
||||||
class Textures
|
class Textures
|
||||||
{
|
{
|
||||||
|
@ -37,8 +38,7 @@ public:
|
||||||
TexturePtr get(const std::string& textureFile);
|
TexturePtr get(const std::string& textureFile);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<std::string, TextureWeakPtr> TexturesMap;
|
std::map<std::string, TextureWeakPtr> m_textures;
|
||||||
TexturesMap m_texturesMap;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Textures g_textures;
|
extern Textures g_textures;
|
||||||
|
|
|
@ -37,7 +37,7 @@ void UIButton::onInputEvent(const InputEvent& event)
|
||||||
g_dispatcher.addTask(boost::bind(&Scriptable::callLuaTableField, shared_from_this(), "onClick"));
|
g_dispatcher.addTask(boost::bind(&Scriptable::callLuaTableField, shared_from_this(), "onClick"));
|
||||||
}
|
}
|
||||||
} else if(event.type == EV_MOUSE_MOVE && m_state != ButtonDown) {
|
} else if(event.type == EV_MOUSE_MOVE && m_state != ButtonDown) {
|
||||||
if(getRect().contains(event.mousePos) && UIContainer::getRoot()->recursiveGetChildByPos(event.mousePos) == asUIElement())
|
if(isMouseOver())
|
||||||
m_state = ButtonMouseOver;
|
m_state = ButtonMouseOver;
|
||||||
else
|
else
|
||||||
m_state = ButtonUp;
|
m_state = ButtonUp;
|
||||||
|
|
|
@ -213,6 +213,13 @@ void UIContainer::onInputEvent(const InputEvent& event)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
shouldFire = true;
|
shouldFire = true;
|
||||||
|
|
||||||
|
if(event.type == EV_MOUSE_MOVE) {
|
||||||
|
if(child->getRect().contains(event.mousePos) && UIContainer::getRoot()->recursiveGetChildByPos(event.mousePos) == child)
|
||||||
|
child->setMouseOver(true);
|
||||||
|
else
|
||||||
|
child->setMouseOver(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ UIElement::UIElement(UI::ElementType type) :
|
||||||
m_type(type),
|
m_type(type),
|
||||||
m_visible(true),
|
m_visible(true),
|
||||||
m_enabled(true),
|
m_enabled(true),
|
||||||
|
m_mouseOver(false),
|
||||||
m_marginLeft(0),
|
m_marginLeft(0),
|
||||||
m_marginRight(0),
|
m_marginRight(0),
|
||||||
m_marginTop(0),
|
m_marginTop(0),
|
||||||
|
|
|
@ -83,6 +83,9 @@ public:
|
||||||
void setFocused(bool focused);
|
void setFocused(bool focused);
|
||||||
bool isFocused() const;
|
bool isFocused() const;
|
||||||
|
|
||||||
|
void setMouseOver(bool mouseOver) { m_mouseOver = mouseOver; }
|
||||||
|
bool isMouseOver() const { return m_mouseOver; }
|
||||||
|
|
||||||
void setVisible(bool visible) { m_visible = visible; }
|
void setVisible(bool visible) { m_visible = visible; }
|
||||||
bool isVisible() const { return m_visible; }
|
bool isVisible() const { return m_visible; }
|
||||||
|
|
||||||
|
@ -123,6 +126,7 @@ private:
|
||||||
std::string m_id;
|
std::string m_id;
|
||||||
bool m_visible;
|
bool m_visible;
|
||||||
bool m_enabled;
|
bool m_enabled;
|
||||||
|
bool m_mouseOver;
|
||||||
|
|
||||||
Rect m_rect;
|
Rect m_rect;
|
||||||
int m_marginLeft;
|
int m_marginLeft;
|
||||||
|
|
|
@ -92,6 +92,8 @@ ImagePtr UIElementSkin::loadImage(const YAML::Node& node)
|
||||||
texture = g_textures.get("skins/" + yamlRead<std::string>(node, "image"));
|
texture = g_textures.get("skins/" + yamlRead<std::string>(node, "image"));
|
||||||
if(texture)
|
if(texture)
|
||||||
image = ImagePtr(new Image(texture));
|
image = ImagePtr(new Image(texture));
|
||||||
|
if(!m_defaultSize.isValid())
|
||||||
|
m_defaultSize = texture->getSize();
|
||||||
|
|
||||||
if(!image)
|
if(!image)
|
||||||
logError(yamlErrorDesc(node["image"], "failed to load image"));
|
logError(yamlErrorDesc(node["image"], "failed to load image"));
|
||||||
|
|
|
@ -34,8 +34,7 @@ class UILabel : public UIElement
|
||||||
public:
|
public:
|
||||||
UILabel() :
|
UILabel() :
|
||||||
UIElement(UI::Label),
|
UIElement(UI::Label),
|
||||||
m_align(AlignTopLeft),
|
m_align(AlignLeftCenter) { }
|
||||||
m_color(Color::white) { }
|
|
||||||
|
|
||||||
void setText(const std::string& text);
|
void setText(const std::string& text);
|
||||||
std::string getText() const { return m_text; }
|
std::string getText() const { return m_text; }
|
||||||
|
@ -48,7 +47,6 @@ public:
|
||||||
private:
|
private:
|
||||||
std::string m_text;
|
std::string m_text;
|
||||||
AlignmentFlag m_align;
|
AlignmentFlag m_align;
|
||||||
Color m_color;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef boost::shared_ptr<UILabel> UILabelPtr;
|
typedef boost::shared_ptr<UILabel> UILabelPtr;
|
||||||
|
|
|
@ -232,7 +232,7 @@ void UILoader::loadElement(const UIElementPtr& element, const YAML::Node& node)
|
||||||
else if(element->getElementType() == UI::Label) {
|
else if(element->getElementType() == UI::Label) {
|
||||||
UILabelPtr label = boost::static_pointer_cast<UILabel>(element);
|
UILabelPtr label = boost::static_pointer_cast<UILabel>(element);
|
||||||
label->setText(yamlRead(node, "text", std::string()));
|
label->setText(yamlRead(node, "text", std::string()));
|
||||||
label->setAlign(parseAlignment(yamlRead(node, "align", std::string())));
|
label->setAlign(parseAlignment(yamlRead(node, "align", std::string("left"))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue