summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPiotr Dziwinski <piotrdz@gmail.com>2012-08-03 23:23:13 +0200
committerPiotr Dziwinski <piotrdz@gmail.com>2012-08-03 23:23:13 +0200
commit61bfb22f27f5216f989c023a5e39fad7e356d2d6 (patch)
tree9d7a8a760ace272739f651a2f4208326731a6fe7 /src
parent5e637ca0288ddd631ec33e1d620cd4a73bcdc2be (diff)
downloadcolobot-61bfb22f27f5216f989c023a5e39fad7e356d2d6.tar.gz
colobot-61bfb22f27f5216f989c023a5e39fad7e356d2d6.tar.bz2
colobot-61bfb22f27f5216f989c023a5e39fad7e356d2d6.zip
Basic font rendering
- added basic font rendering - minor refactoring & fixes
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/app/app.cpp54
-rw-r--r--src/app/app.h6
-rw-r--r--src/graphics/core/device.h9
-rw-r--r--src/graphics/engine/engine.cpp148
-rw-r--r--src/graphics/engine/engine.h31
-rw-r--r--src/graphics/engine/text.cpp477
-rw-r--r--src/graphics/engine/text.h267
-rw-r--r--src/graphics/opengl/gldevice.cpp39
-rw-r--r--src/graphics/opengl/gldevice.h5
-rw-r--r--src/math/const.h11
-rw-r--r--src/math/func.h8
-rw-r--r--src/math/geometry.h4
-rw-r--r--src/math/intsize.h15
-rw-r--r--src/math/size.h9
15 files changed, 895 insertions, 189 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9bcd288..25a576e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -176,6 +176,7 @@ graphics/opengl/gldevice.cpp
set(LIBS
${SDL_LIBRARY}
${SDLIMAGE_LIBRARY}
+${SDLTTF_LIBRARY}
${OPENGL_LIBRARY}
${PNG_LIBRARIES}
${OPTIONAL_LIBS}
diff --git a/src/app/app.cpp b/src/app/app.cpp
index d20232d..3681172 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -122,6 +122,7 @@ bool CApplication::ParseArguments(int argc, char *argv[])
{
waitDataDir = false;
m_dataPath = arg;
+ continue;
}
if (arg == "-debug")
@@ -153,10 +154,6 @@ bool CApplication::Create()
// Temporarily -- only in windowed mode
m_deviceConfig.fullScreen = false;
- // Create the 3D engine
- m_engine = new Gfx::CEngine(m_iMan, this);
-
-
/* // Create the sound instance.
m_sound = new CSound(m_iMan);
@@ -224,20 +221,15 @@ bool CApplication::Create()
return false;
}
+ // Create the 3D engine
+ m_engine = new Gfx::CEngine(m_iMan, this);
+
m_engine->SetDevice(m_device);
- if (! m_engine->Create() )
- {
- SystemDialog( SDT_ERROR, "COLOBT - Fatal Error",
- std::string("Error in CEngine::Create() :\n") +
- std::string(m_engine->GetError()) );
- m_exitCode = 1;
- return false;
- }
- if (! m_engine->AfterDeviceSetInit() )
+ if (! m_engine->Create() )
{
SystemDialog( SDT_ERROR, "COLOBT - Fatal Error",
- std::string("Error in CEngine::AfterDeviceSetInit() :\n") +
+ std::string("Error in CEngine::Init() :\n") +
std::string(m_engine->GetError()) );
m_exitCode = 1;
return false;
@@ -315,8 +307,7 @@ void CApplication::Destroy()
if (m_engine != NULL)
{
- if (m_engine->GetWasInit())
- m_engine->Destroy();
+ m_engine->Destroy();
delete m_engine;
m_engine = NULL;
@@ -324,8 +315,7 @@ void CApplication::Destroy()
if (m_device != NULL)
{
- if (m_device->GetWasInit())
- m_device->Destroy();
+ m_device->Destroy();
delete m_device;
m_device = NULL;
@@ -616,21 +606,6 @@ PressState TranslatePressState(unsigned char state)
return STATE_RELEASED;
}
-/** Conversion of the position of the mouse from window coords to interface coords:
- - x: 0=left, 1=right
- - y: 0=down, 1=up */
-Math::Point CApplication::WindowToInterfaceCoords(Math::IntPoint pos)
-{
- return Math::Point( static_cast<float>(pos.x) / static_cast<float>(m_deviceConfig.size.w),
- 1.0f - static_cast<float>(pos.y) / static_cast<float>(m_deviceConfig.size.h) );
-}
-
-Math::IntPoint CApplication::InterfaceToWindowCoords(Math::Point pos)
-{
- return Math::IntPoint(static_cast<int>(pos.x * m_deviceConfig.size.w),
- static_cast<int>((1.0f - pos.y) * m_deviceConfig.size.h));
-}
-
/** The SDL event parsed is stored internally.
If event is not available or is not understood, returned event is of type EVENT_NULL. */
Event CApplication::ParseEvent()
@@ -666,14 +641,16 @@ Event CApplication::ParseEvent()
event.mouseButton.button = m_private->currentEvent.button.button;
event.mouseButton.state = TranslatePressState(m_private->currentEvent.button.state);
- event.mouseButton.pos = WindowToInterfaceCoords(Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
+ event.mouseButton.pos = m_engine->WindowToInterfaceCoords(
+ Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
}
else if (m_private->currentEvent.type == SDL_MOUSEMOTION)
{
event.type = EVENT_MOUSE_MOVE;
event.mouseMove.state = TranslatePressState(m_private->currentEvent.button.state);
- event.mouseMove.pos = WindowToInterfaceCoords(Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
+ event.mouseMove.pos = m_engine->WindowToInterfaceCoords(
+ Math::IntPoint(m_private->currentEvent.button.x, m_private->currentEvent.button.y));
}
else if (m_private->currentEvent.type == SDL_JOYAXISMOTION)
{
@@ -792,6 +769,11 @@ void CApplication::StepSimulation(float rTime)
// TODO
}
+Gfx::GLDeviceConfig CApplication::GetVideoConfig()
+{
+ return m_deviceConfig;
+}
+
VideoQueryResult CApplication::GetVideoResolutionList(std::vector<Math::IntSize> &resolutions,
bool fullScreen, bool resizeable)
{
@@ -891,7 +873,7 @@ bool CApplication::GetSystemMouseVisibile()
void CApplication::SetSystemMousePos(Math::Point pos)
{
- Math::IntPoint windowPos = InterfaceToWindowCoords(pos);
+ Math::IntPoint windowPos = m_engine->InterfaceToWindowCoords(pos);
SDL_WarpMouse(windowPos.x, windowPos.y);
m_systemMousePos = pos;
}
diff --git a/src/app/app.h b/src/app/app.h
index 483aa55..bba55b2 100644
--- a/src/app/app.h
+++ b/src/app/app.h
@@ -25,7 +25,6 @@
#include "graphics/core/device.h"
#include "graphics/engine/engine.h"
#include "graphics/opengl/gldevice.h"
-#include "math/intsize.h"
#include <string>
#include <vector>
@@ -206,11 +205,6 @@ protected:
//! Closes the joystick device
void CloseJoystick();
- //! Converts window coords to interface coords
- Math::Point WindowToInterfaceCoords(Math::IntPoint pos);
- //! Converts the interface coords to window coords
- Math::IntPoint InterfaceToWindowCoords(Math::Point pos);
-
protected:
//! Instance manager
CInstanceManager* m_iMan;
diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h
index c10b853..3ab86dd 100644
--- a/src/graphics/core/device.h
+++ b/src/graphics/core/device.h
@@ -32,6 +32,7 @@
class CImage;
+struct ImageData;
namespace Gfx {
@@ -279,8 +280,6 @@ public:
//! Destroys the device, releasing every acquired resource
virtual void Destroy() = 0;
- //! Returns whether the device has been initialized
- virtual bool GetWasInit() = 0;
//! Returns the last encountered error
virtual std::string GetError() = 0;
@@ -317,6 +316,8 @@ public:
//! Creates a texture from image; the image can be safely removed after that
virtual Gfx::Texture CreateTexture(CImage *image, const Gfx::TextureCreateParams &params) = 0;
+ //! Creates a texture from raw image data; image data can be freed after that
+ virtual Gfx::Texture CreateTexture(ImageData *data, const Gfx::TextureCreateParams &params) = 0;
//! Deletes a given texture, freeing it from video memory
virtual void DestroyTexture(const Gfx::Texture &texture) = 0;
//! Deletes all textures created so far
@@ -324,8 +325,10 @@ public:
//! Returns the maximum number of multitexture stages
virtual int GetMaxTextureCount() = 0;
- //! Sets the (multi)texture at given index
+ //! Sets the texture at given texture stage
virtual void SetTexture(int index, const Gfx::Texture &texture) = 0;
+ //! Sets the texture image by ID at given texture stage
+ virtual void SetTexture(int index, unsigned int textureId) = 0;
//! Returns the (multi)texture at given index
virtual Gfx::Texture GetTexture(int index) = 0;
//! Enables/disables the given texture stage
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index e544ee3..345a15c 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -25,6 +25,8 @@
#include "common/key.h"
#include "common/logger.h"
#include "graphics/core/device.h"
+#include "graphics/engine/lightman.h"
+#include "graphics/engine/text.h"
#include "math/geometry.h"
// Initial size of various vectors
@@ -44,23 +46,21 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app)
{
m_iMan = iMan;
m_app = app;
- m_device = NULL;
-
- m_wasInit = false;
+ m_device = nullptr;
m_iMan = iMan;
m_iMan->AddInstance(CLASS_ENGINE, this);
m_app = app;
- m_lightMan = NULL;
- m_text = NULL;
- m_particle = NULL;
- m_water = NULL;
- m_cloud = NULL;
- m_lightning = NULL;
- m_planet = NULL;
- m_sound = NULL;
- m_terrain = NULL;
+ m_lightMan = nullptr;
+ m_text = nullptr;
+ m_particle = nullptr;
+ m_water = nullptr;
+ m_cloud = nullptr;
+ m_lightning = nullptr;
+ m_planet = nullptr;
+ m_sound = nullptr;
+ m_terrain = nullptr;
m_focus = 0.75f;
m_baseTime = 0;
@@ -178,95 +178,93 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app)
Gfx::CEngine::~CEngine()
{
- m_iMan = NULL;
- m_app = NULL;
- m_device = NULL;
+ m_iMan = nullptr;
+ m_app = nullptr;
+ m_device = nullptr;
- m_sound = NULL;
- m_terrain = NULL;
+ m_sound = nullptr;
+ m_terrain = nullptr;
}
-bool Gfx::CEngine::GetWasInit()
+std::string Gfx::CEngine::GetError()
{
- return m_wasInit;
+ return m_error;
}
-std::string Gfx::CEngine::GetError()
+void Gfx::CEngine::SetDevice(Gfx::CDevice *device)
{
- return m_error;
+ m_device = device;
+}
+
+Gfx::CDevice* Gfx::CEngine::GetDevice()
+{
+ return m_device;
}
bool Gfx::CEngine::Create()
{
- m_wasInit = true;
+ m_size = m_lastSize = m_app->GetVideoConfig().size;
- /*m_lightMan = new Gfx::CLight(m_iMan, this);
+ m_lightMan = new Gfx::CLightManager(m_iMan, this);
m_text = new Gfx::CText(m_iMan, this);
+ /* TODO:
m_particle = new Gfx::CParticle(m_iMan, this);
m_water = new Gfx::CWater(m_iMan, this);
m_cloud = new Gfx::CCloud(m_iMan, this);
m_lightning = new Gfx::CLightning(m_iMan, this);
m_planet = new Gfx::CPlanet(m_iMan, this);*/
+ m_text->SetDevice(m_device);
+ if (! m_text->Create())
+ {
+ m_error = std::string("Error creating CText: ") + m_text->GetError();
+ return false;
+ }
+
+
m_matWorldInterface.LoadIdentity();
m_matViewInterface.LoadIdentity();
Math::LoadOrthoProjectionMatrix(m_matProjInterface, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
+ m_device->SetClearColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f));
+
+ m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false);
+
+ Gfx::TextureCreateParams params;
+ params.format = Gfx::TEX_IMG_RGB;
+ params.minFilter = Gfx::TEX_MIN_FILTER_NEAREST;
+ params.magFilter = Gfx::TEX_MAG_FILTER_NEAREST;
+ params.mipmap = false;
+ m_miceTexture = CreateTexture("mouse.png", params);
+
return true;
}
void Gfx::CEngine::Destroy()
{
- // TODO
+ m_text->Destroy();
- /*delete m_lightMan;
- m_lightMan = NULL;
+ delete m_lightMan;
+ m_lightMan = nullptr;
delete m_text;
- m_text = NULL;
+ m_text = nullptr;
+ /* TODO:
delete m_particle;
- m_particle = NULL;
+ m_particle = nullptr;
delete m_water;
- m_water = NULL;
+ m_water = nullptr;
delete m_cloud;
- m_cloud = NULL;
+ m_cloud = nullptr;
delete m_lightning;
- m_lightning = NULL;
+ m_lightning = nullptr;
delete m_planet;
- m_planet = NULL;*/
-
- m_wasInit = false;
-}
-
-void Gfx::CEngine::SetDevice(Gfx::CDevice *device)
-{
- m_device = device;
-}
-
-Gfx::CDevice* Gfx::CEngine::GetDevice()
-{
- return m_device;
-}
-
-bool Gfx::CEngine::AfterDeviceSetInit()
-{
- m_device->SetClearColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f));
-
- m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false);
-
- Gfx::TextureCreateParams params;
- params.format = Gfx::TEX_IMG_RGB;
- params.minFilter = Gfx::TEX_MIN_FILTER_NEAREST;
- params.magFilter = Gfx::TEX_MAG_FILTER_NEAREST;
- params.mipmap = false;
- m_miceTexture = CreateTexture("mouse.png", params);
-
- return true;
+ m_planet = nullptr;*/
}
void Gfx::CEngine::ResetAfterDeviceChanged()
@@ -274,7 +272,6 @@ void Gfx::CEngine::ResetAfterDeviceChanged()
// TODO
}
-
Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName, const Gfx::TextureCreateParams &params)
{
CImage img;
@@ -610,9 +607,38 @@ bool Gfx::CEngine::DrawInterface()
DrawMouse();
+ m_text->DrawString("abcdefghijklmnopqrstuvwxyz ąęśćółńż", Gfx::FONT_COLOBOT, 15.0f, Math::Point(0.25f, 0.2f), 1.0f, 0);
+
return true;
}
+/** Conversion of the position of the mouse from window coords to interface coords:
+ - x: 0=left, 1=right
+ - y: 0=down, 1=up */
+Math::Point Gfx::CEngine::WindowToInterfaceCoords(Math::IntPoint pos)
+{
+ return Math::Point( static_cast<float>(pos.x) / static_cast<float>(m_size.w),
+ 1.0f - static_cast<float>(pos.y) / static_cast<float>(m_size.h) );
+}
+
+Math::IntPoint Gfx::CEngine::InterfaceToWindowCoords(Math::Point pos)
+{
+ return Math::IntPoint(static_cast<int>(pos.x * m_size.w),
+ static_cast<int>((1.0f - pos.y) * m_size.h));
+}
+
+Math::Size Gfx::CEngine::WindowToInterfaceSize(Math::IntSize size)
+{
+ return Math::Size( static_cast<float>(size.w) / static_cast<float>(m_size.w),
+ static_cast<float>(size.h) / static_cast<float>(m_size.h) );
+}
+
+Math::IntSize Gfx::CEngine::InterfaceToWindowSize(Math::Size size)
+{
+ return Math::IntSize(static_cast<int>(size.w * m_size.w),
+ static_cast<int>(size.h * m_size.h));
+}
+
void Gfx::CEngine::DrawMouse()
{
if (! m_mouseVisible)
diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h
index 25c5e5d..79844c6 100644
--- a/src/graphics/engine/engine.h
+++ b/src/graphics/engine/engine.h
@@ -29,6 +29,7 @@
#include "math/intsize.h"
#include "math/matrix.h"
#include "math/point.h"
+#include "math/size.h"
#include "math/vector.h"
@@ -514,23 +515,18 @@ public:
CEngine(CInstanceManager *iMan, CApplication *app);
~CEngine();
- //! Returns whether the device was initialized
- bool GetWasInit();
//! Returns the last error encountered
std::string GetError();
- //! Performs the first initialization, before a device was set
- bool Create();
- //! Frees all resources before exit
- void Destroy();
-
//! Sets the device to be used
void SetDevice(Gfx::CDevice *device);
//! Returns the current device
Gfx::CDevice* GetDevice();
- //! Performs initialization after a device was created and set
- bool AfterDeviceSetInit();
+ //! Performs the initialization; must be called after device was set
+ bool Create();
+ //! Frees all resources before exit
+ void Destroy();
//! Resets some states and flushes textures after device was changed (e.g. resoulution changed)
void ResetAfterDeviceChanged();
@@ -544,6 +540,17 @@ public:
bool Render();
+ //! Converts window coords to interface coords
+ Math::Point WindowToInterfaceCoords(Math::IntPoint pos);
+ //! Converts interface coords to window coords
+ Math::IntPoint InterfaceToWindowCoords(Math::Point pos);
+
+ //! Converts window size to interface size
+ Math::Size WindowToInterfaceSize(Math::IntSize size);
+ //! Converts interface size to window size
+ Math::IntSize InterfaceToWindowSize(Math::Size size);
+
+
bool WriteProfile();
void SetPause(bool pause);
@@ -769,7 +776,8 @@ public:
Math::Vector GetLookatPt();
float GetEyeDirH();
float GetEyeDirV();
- Math::Point GetDim();
+ Math::IntPoint GetViewportSize();
+ Math::IntPoint GetLastViewportSize();
void UpdateMatProj();
void ApplyChange();
@@ -903,8 +911,9 @@ protected:
bool m_render;
bool m_movieLock;
- //! Current size of window
+ //! Current size of viewport
Math::IntSize m_size;
+ //! Previous size of viewport
Math::IntSize m_lastSize;
std::vector<Gfx::EngineObjLevel1> m_objectTree;
diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp
index 2a9543c..eea9fdb 100644
--- a/src/graphics/engine/text.cpp
+++ b/src/graphics/engine/text.cpp
@@ -19,5 +19,480 @@
#include "graphics/engine/text.h"
+#include "app/app.h"
+#include "common/image.h"
+#include "common/iman.h"
+#include "common/logger.h"
+#include "common/stringutils.h"
+#include "math/func.h"
-// TODO implementation
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+
+
+namespace Gfx
+{
+
+/**
+ \struct CachedFont
+ \brief Base TTF font with UTF-8 char cache */
+struct CachedFont
+{
+ TTF_Font* font;
+ std::map<Gfx::UTF8Char, Gfx::CharTexture> cache;
+
+ CachedFont() : font(nullptr) {}
+};
+
+};
+
+
+
+Gfx::CText::CText(CInstanceManager *iMan, Gfx::CEngine* engine)
+{
+ m_iMan = iMan;
+ m_iMan->AddInstance(CLASS_TEXT, this);
+
+ m_device = nullptr;
+ m_engine = engine;
+
+ m_defaultSize = 12.0f;
+ m_fontPath = "fonts";
+
+ m_lastFontType = Gfx::FONT_COLOBOT;
+ m_lastFontSize = 0;
+ m_lastCachedFont = nullptr;
+}
+
+Gfx::CText::~CText()
+{
+ m_iMan->DeleteInstance(CLASS_TEXT, this);
+
+ m_iMan = nullptr;
+ m_device = nullptr;
+ m_engine = nullptr;
+}
+
+bool Gfx::CText::Create()
+{
+ if (TTF_Init() != 0)
+ {
+ m_error = std::string("TTF_Init error: ") + std::string(TTF_GetError());
+ return false;
+ }
+
+ m_fonts[Gfx::FONT_COLOBOT] = new MultisizeFont("dvu_sans.ttf");
+ m_fonts[Gfx::FONT_COLOBOT_BOLD] = new MultisizeFont("dvu_sans_bold.ttf");
+ m_fonts[Gfx::FONT_COLOBOT_ITALIC] = new MultisizeFont("dvu_sans_italic.ttf");
+
+ m_fonts[Gfx::FONT_COURIER] = new MultisizeFont("dvu_sans_mono.ttf");
+ m_fonts[Gfx::FONT_COURIER_BOLD] = new MultisizeFont("dvu_sans_mono_bold.ttf");
+
+ for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it)
+ {
+ Gfx::FontType type = (*it).first;
+ CachedFont* cf = GetOrOpenFont(type, m_defaultSize);
+ if (cf == nullptr || cf->font == nullptr)
+ return false;
+ }
+
+ return true;
+}
+
+void Gfx::CText::Destroy()
+{
+ for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it)
+ {
+ MultisizeFont* mf = (*it).second;
+
+ for (auto jt = mf->fonts.begin(); jt != mf->fonts.end(); ++jt)
+ {
+ CachedFont* cf = (*jt).second;
+
+ TTF_CloseFont(cf->font);
+
+ cf->font = nullptr;
+ delete cf;
+ }
+
+ mf->fonts.clear();
+ delete mf;
+ }
+
+ m_fonts.clear();
+
+ m_lastCachedFont = nullptr;
+
+ TTF_Quit();
+}
+
+void Gfx::CText::SetDevice(Gfx::CDevice* device)
+{
+ m_device = device;
+}
+
+std::string Gfx::CText::GetError()
+{
+ return m_error;
+}
+
+void Gfx::CText::FlushCache()
+{
+ for (auto it = m_fonts.begin(); it != m_fonts.end(); ++it)
+ {
+ MultisizeFont *mf = (*it).second;
+ for (auto jt = mf->fonts.begin(); jt != mf->fonts.end(); ++jt)
+ {
+ CachedFont *f = (*jt).second;
+ f->cache.clear();
+ }
+ }
+}
+
+void Gfx::CText::DrawText(const std::string &text, const std::vector<FontMetaChar> &format,
+ Math::Point pos, float width, Gfx::JustifyType justify, float size,
+ float stretch, int eol)
+{
+ // TODO
+}
+
+void Gfx::CText::DrawText(const std::string &text, Gfx::FontType font,
+ Math::Point pos, float width, Gfx::JustifyType justify, float size,
+ float stretch, int eol)
+{
+ // TODO
+}
+
+void Gfx::CText::SizeText(const std::string &text, const std::vector<FontMetaChar> &format,
+ Math::Point pos, Gfx::JustifyType justify, float size,
+ Math::Point &start, Math::Point &end)
+{
+ // TODO
+}
+
+void Gfx::CText::SizeText(const std::string &text, Gfx::FontType font,
+ Math::Point pos, Gfx::JustifyType justify, float size,
+ Math::Point &start, Math::Point &end)
+{
+ // TODO
+}
+
+float Gfx::CText::GetAscent(Gfx::FontType font, float size)
+{
+ // TODO
+ return 0.0f;
+}
+
+float Gfx::CText::GetDescent(Gfx::FontType font, float size)
+{
+ // TODO
+ return 0.0f;
+}
+
+float Gfx::CText::GetHeight(Gfx::FontType font, float size)
+{
+ // TODO
+ return 0.0f;
+}
+
+
+float Gfx::CText::GetStringWidth(const std::string &text,
+ const std::vector<FontMetaChar> &format, float size)
+{
+ // TODO
+ return 0.0f;
+}
+
+float Gfx::CText::GetStringWidth(const std::string &text, Gfx::FontType font, float size)
+{
+ // TODO
+ return 0.0f;
+}
+
+float Gfx::CText::GetCharWidth(int character, Gfx::FontType font, float size, float offset)
+{
+ // TODO
+ return 0.0f;
+}
+
+
+int Gfx::CText::Justify(const std::string &text, const std::vector<FontMetaChar> &format,
+ float size, float width)
+{
+ // TODO
+ return 0;
+}
+
+int Gfx::CText::Justify(const std::string &text, Gfx::FontType font, float size, float width)
+{
+ // TODO
+ return 0;
+}
+
+int Gfx::CText::Detect(const std::string &text, const std::vector<FontMetaChar> &format,
+ float size, float offset)
+{
+ // TODO
+ return 0;
+}
+
+int Gfx::CText::Detect(const std::string &text, Gfx::FontType font, float size, float offset)
+{
+ // TODO
+ return 0;
+}
+
+void Gfx::CText::DrawString(const std::string &text, const std::vector<FontMetaChar> &format,
+ float size, Math::Point pos, float width, int eol)
+{
+ // TODO
+}
+
+void Gfx::CText::DrawString(const std::string &text, Gfx::FontType font,
+ float size, Math::Point pos, float width, int eol)
+{
+ m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true);
+ m_device->SetTextureEnabled(0, true);
+
+ m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true);
+ m_device->SetBlendFunc(Gfx::BLEND_SRC_ALPHA, Gfx::BLEND_INV_SRC_ALPHA);
+
+ unsigned int index = 0;
+ Math::Point screenPos = pos;
+ while (index < text.length())
+ {
+ UTF8Char ch;
+
+ int len = StrUtils::Utf8CharSizeAt(text, index);
+ if (len >= 1)
+ ch.c1 = text[index];
+ if (len >= 2)
+ ch.c2 = text[index+1];
+ if (len >= 3)
+ ch.c3 = text[index+2];
+
+ index += len;
+
+ DrawChar(ch, font, size, screenPos);
+ }
+}
+
+void Gfx::CText::DrawColor(int color, float size, Math::Point pos, float width)
+{
+ // TODO !!!
+ /*
+ float h, u1, u2, v1, v2, dp;
+ int icon;
+
+ int icon = -1;
+ switch (color)
+ {
+ case Gfx::FONT_COLOR_LINK:
+ icon = 9;
+ break;
+ case Gfx::FONT_COLOR_TOKEN:
+ icon = 4;
+ break;
+ case Gfx::FONT_COLOR_TYPE:
+ icon = 5;
+ break;
+ }
+ icon = -1;
+ if ( color == COLOR_LINK ) icon = 9; // blue
+ if ( color == COLOR_TOKEN ) icon = 4; // orange
+ if ( color == COLOR_TYPE ) icon = 5; // green
+ if ( color == COLOR_CONST ) icon = 8; // red
+ if ( color == COLOR_REM ) icon = 6; // magenta
+ if ( color == COLOR_KEY ) icon = 10; // gray
+
+ if ( icon == -1 ) return;
+
+ if ( color == COLOR_LINK )
+ {
+ m_engine->SetState(D3DSTATENORMAL);
+ }
+
+ Math::IntSize vsize = m_engine->GetViewportSize();
+ if (vsize.h <= 768.0f) // 1024x768 or less?
+ h = 1.01f / dim.y; // 1 pixel
+ else // more than 1024x768?
+ h = 2.0f / dim.y; // 2 pixels
+
+ Math::Point p1, p2;
+ p1.x = pos.x;
+ p2.x = pos.x + width;
+
+ if (color == Gfx::FONT_COLOR_LINK)
+ {
+ p1.y = pos.y;
+ p2.y = pos.y + h; // just emphasized
+ }
+ else
+ {
+ p1.y = pos.y;
+ p2.y = pos.y + (16.0f/256.0f)*(size/20.0f);
+ }
+
+ u1 = (16.0f/256.0f)*(icon%16);
+ v1 = (240.0f/256.0f);
+ u2 = (16.0f/256.0f)+u1;
+ v2 = (16.0f/256.0f)+v1;
+
+ dp = 0.5f/256.0f;
+ u1 += dp;
+ v1 += dp;
+ u2 -= dp;
+ v2 -= dp;
+
+ Math::Vector n(0.0f, 0.0f, -1.0f); // normal
+
+ Gfx::Vertex quad[] =
+ {
+ Gfx::Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(u1, v2)),
+ Gfx::Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(u1, v1)),
+ Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(u2, v2)),
+ Gfx::Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(u2, v1)),
+ };
+
+ m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);
+ m_engine->AddStatisticTriangle(2);
+
+ if (color == Gfx::FONT_COLOR_LINK)
+ m_engine->SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE);*/
+}
+
+void Gfx::CText::DrawChar(UTF8Char character, Gfx::FontType font, float size, Math::Point &pos)
+{
+ CachedFont* cf = GetOrOpenFont(font, size);
+
+ if (cf == nullptr)
+ return;
+
+ auto it = cf->cache.find(character);
+ CharTexture tex;
+ if (it != cf->cache.end())
+ {
+ tex = (*it).second;
+ }
+ else
+ {
+ char str[] = { character.c1, character.c2, character.c3, '\0' };
+ tex = CreateCharTexture(str, cf);
+
+ if (tex.id == 0) // invalid
+ return;
+
+ cf->cache[character] = tex;
+ }
+
+ Math::Vector n(0.0f, 0.0f, -1.0f); // normal
+
+ Gfx::Vertex quad[4] =
+ {
+ Gfx::Vertex(Math::Vector(pos.x, pos.y + tex.charSize.h, 0.0f),
+ n, Math::Point(0.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector(pos.x, pos.y + tex.charSize.h - tex.texSize.h, 0.0f),
+ n, Math::Point(0.0f, 1.0f)),
+ Gfx::Vertex(Math::Vector(pos.x + tex.texSize.w, pos.y + tex.charSize.h, 0.0f),
+ n, Math::Point(1.0f, 0.0f)),
+ Gfx::Vertex(Math::Vector(pos.x + tex.texSize.w, pos.y + tex.charSize.h - tex.texSize.h, 0.0f),
+ n, Math::Point(1.0f, 1.0f))
+ };
+
+ m_device->SetTexture(0, tex.id);
+ m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4);
+
+ pos.x += tex.charSize.w;
+}
+
+Gfx::CachedFont* Gfx::CText::GetOrOpenFont(Gfx::FontType font, float size)
+{
+ // TODO: sizing
+ int pointSize = static_cast<int>(size);
+
+ if (m_lastCachedFont != nullptr)
+ {
+ if (m_lastFontType == font && m_lastFontSize == pointSize)
+ return m_lastCachedFont;
+ }
+
+ auto it = m_fonts.find(font);
+ if (it == m_fonts.end())
+ {
+ m_error = std::string("Invalid font type ") + StrUtils::ToString<int>(static_cast<int>(font));
+ return nullptr;
+ }
+
+ MultisizeFont* mf = (*it).second;
+
+ auto jt = mf->fonts.find(pointSize);
+ if (jt != mf->fonts.end())
+ {
+ m_lastCachedFont = (*jt).second;
+ m_lastFontType = font;
+ m_lastFontSize = pointSize;
+ return m_lastCachedFont;
+ }
+
+ std::string path = CApplication::GetInstance().GetDataFilePath(m_fontPath, mf->fileName);
+
+ m_lastCachedFont = new CachedFont();
+ m_lastCachedFont->font = TTF_OpenFont(path.c_str(), pointSize);
+ if (m_lastCachedFont->font == nullptr)
+ m_error = std::string("TTF_OpenFont error ") + std::string(TTF_GetError());
+
+ mf->fonts[pointSize] = m_lastCachedFont;
+
+ return m_lastCachedFont;
+}
+
+Gfx::CharTexture Gfx::CText::CreateCharTexture(const char* str, Gfx::CachedFont* font)
+{
+ CharTexture texture;
+
+ SDL_Surface* textSurface = nullptr;
+ SDL_Color white = {255, 255, 255, 0};
+ textSurface = TTF_RenderUTF8_Blended(font->font, str, white);
+
+ if (textSurface == nullptr)
+ {
+ m_error = "TTF_Render error";
+ return texture;
+ }
+
+ int w = Math::NextPowerOfTwo(textSurface->w);
+ int h = Math::NextPowerOfTwo(textSurface->h);
+
+ textSurface->flags = textSurface->flags & (~SDL_SRCALPHA);
+ SDL_Surface* textureSurface = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000, 0x0000ff00,
+ 0x000000ff, 0xff000000);
+ SDL_BlitSurface(textSurface, NULL, textureSurface, NULL);
+
+ ImageData data;
+ data.surface = textureSurface;
+
+ Gfx::TextureCreateParams createParams;
+ createParams.format = Gfx::TEX_IMG_RGBA;
+ createParams.minFilter = Gfx::TEX_MIN_FILTER_NEAREST;
+ createParams.magFilter = Gfx::TEX_MAG_FILTER_NEAREST;
+ createParams.mipmap = false;
+
+ Gfx::Texture tex = m_device->CreateTexture(&data, createParams);
+
+ data.surface = nullptr;
+
+ SDL_FreeSurface(textSurface);
+ SDL_FreeSurface(textureSurface);
+
+ if (! tex.valid)
+ {
+ m_error = "Texture create error";
+ return texture;
+ }
+
+ texture.id = tex.id;
+ texture.texSize = m_engine->WindowToInterfaceSize(Math::IntSize(textureSurface->w, textureSurface->h));
+ texture.charSize = m_engine->WindowToInterfaceSize(Math::IntSize(textSurface->w, textSurface->h));
+
+ return texture;
+}
diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h
index c2de220..19d9882 100644
--- a/src/graphics/engine/text.h
+++ b/src/graphics/engine/text.h
@@ -19,95 +19,268 @@
#pragma once
-#include "graphics/engine/engine.h"
-#include "graphics/core/device.h"
#include "math/point.h"
+#include "math/size.h"
+#include <vector>
+#include <map>
class CInstanceManager;
-
namespace Gfx {
-const float SMALLFONT = 10.0f;
-const float BIGFONT = 15.0f;
+class CEngine;
+class CDevice;
+
+//! Standard small font size
+const float FONT_SIZE_SMALL = 10.0f;
+//! Standard big font size
+const float FONT_SIZE_BIG = 15.0f;
+
+/**
+ \enum TextAlignType
+ \brief Type of text alignment */
+enum JustifyType
+{
+ TEXT_ALIGN_RIGHT,
+ TEXT_ALIGN_LEFT,
+ TEXT_ALIGN_CENTER
+};
-const float NORMSTRETCH = 0.8f;
+/* Font meta char constants */
+//! Type used for font character metainfo
+typedef short FontMetaChar;
+/**
+ \enum FontType
+ \brief Type of font
+ Bitmask in lower 4 bits (mask 0x00f) */
enum FontType
{
- FONT_COLOBOT = 0,
- FONT_COURIER = 1,
- FONT_BUTTON = 2,
+ //! Flag for bold font subtype
+ FONT_BOLD = 0x04,
+ //! Flag for italic font subtype
+ FONT_ITALIC = 0x08,
+
+ //! Default colobot font used for interface
+ FONT_COLOBOT = 0x00,
+ //! Alias for bold colobot font
+ FONT_COLOBOT_BOLD = FONT_COLOBOT | FONT_BOLD,
+ //! Alias for italic colobot font
+ FONT_COLOBOT_ITALIC = FONT_COLOBOT | FONT_ITALIC,
+
+ //! Courier (monospace) font used mainly in code editor (only regular & bold)
+ FONT_COURIER = 0x01,
+ //! Alias for bold courier font
+ FONT_COURIER_BOLD = FONT_COURIER | FONT_BOLD,
+
+ // 0x02 left for possible another font
+
+ //! Pseudo-font loaded from textures for buttons, icons, etc.
+ FONT_BUTTON = 0x03,
};
+/**
+ \enum FontTitle
+ \brief Size of font title
+
+ Bitmask in 2 bits left shifted 4 (mask 0x030) */
enum FontTitle
{
- TITLE_BIG = 0x04,
- TITLE_NORM = 0x08,
- TITLE_LITTLE = 0x0c,
+ FONT_TITLE_BIG = 0x01 << 4,
+ FONT_TITLE_NORM = 0x02 << 4,
+ FONT_TITLE_LITTLE = 0x03 << 4,
};
+/**
+ \enum FontColor
+ \brief Font color type (?)
+
+ Bitmask in 3 bits left shifted 6 (mask 0x1c0) */
enum FontColor
{
- COLOR_LINK = 0x10,
- COLOR_TOKEN = 0x20,
- COLOR_TYPE = 0x30,
- COLOR_CONST = 0x40,
- COLOR_REM = 0x50,
- COLOR_KEY = 0x60,
- COLOR_TABLE = 0x70,
+ FONT_COLOR_LINK = 0x01 << 6,
+ FONT_COLOR_TOKEN = 0x02 << 6,
+ FONT_COLOR_TYPE = 0x03 << 6,
+ FONT_COLOR_CONST = 0x04 << 6,
+ FONT_COLOR_REM = 0x05 << 6,
+ FONT_COLOR_KEY = 0x06 << 6,
+ FONT_COLOR_TABLE = 0x07 << 6,
};
-const short FONT_MASK = 0x03;
-const short TITLE_MASK = 0x0c;
-const short COLOR_MASK = 0x70;
-const short IMAGE_MASK = 0x80;
+/**
+ \enum FontMask
+ \brief Masks in FontMetaChar for different attributes */
+enum FontMask
+{
+ //! Mask for FontType
+ FONT_MASK_FONT = 0x00f,
+ //! Mask for FontTitle
+ FONT_MASK_TITLE = 0x030,
+ //! Mask for FontColor
+ FONT_MASK_COLOR = 0x1c0,
+ //! Mask for image bit
+ FONT_MASK_IMAGE = 0x200
+};
+
+
+/**
+ \struct UTF8Char
+ \brief UTF-8 character in font cache
+
+ Only 3-byte chars are supported */
+struct UTF8Char
+{
+ char c1, c2, c3;
+
+ explicit UTF8Char(char ch1 = '\0', char ch2 = '\0', char ch3 = '\0')
+ : c1(ch1), c2(ch2), c3(ch3) {}
+
+ inline bool operator<(const UTF8Char &other) const
+ {
+ if (c1 < other.c1)
+ return true;
+ else if (c1 > other.c1)
+ return false;
+ if (c2 < other.c2)
+ return true;
+ else if (c2 > other.c2)
+ return false;
+ return c3 < other.c3;
+ }
+
+ inline bool operator==(const UTF8Char &other) const
+ {
+ return c1 == other.c1 && c2 == other.c2 && c3 == other.c3;
+ }
+};
-class CText {
+/**
+ \struct CharTexture
+ \brief Texture of font character */
+struct CharTexture
+{
+ unsigned int id;
+ Math::Size texSize;
+ Math::Size charSize;
+
+ CharTexture() : id(0) {}
+};
+
+// Definition is private - in text.cpp
+struct CachedFont;
+
+/**
+ \struct MultisizeFont
+ \brief Font with multiple possible sizes */
+struct MultisizeFont
+{
+ std::string fileName;
+ std::map<int, CachedFont*> fonts;
+
+ MultisizeFont(const std::string &fn)
+ : fileName(fn) {}
+};
+
+/**
+ \class CText
+ \brief Text rendering engine
+
+ ... */
+class CText
+{
public:
CText(CInstanceManager *iMan, Gfx::CEngine* engine);
~CText();
+ //! Sets the device to be used
void SetDevice(Gfx::CDevice *device);
- void DrawText(char *string, char *format, int len, Math::Point pos, float width, int justif, float size, float stretch, int eol);
- void DrawText(char *string, char *format, Math::Point pos, float width, int justif, float size, float stretch, int eol);
- void DrawText(char *string, int len, Math::Point pos, float width, int justif, float size, float stretch, FontType font, int eol);
- void DrawText(char *string, Math::Point pos, float width, int justif, float size, float stretch, FontType font, int eol);
- void DimText(char *string, char *format, int len, Math::Point pos, int justif, float size, float stretch, Math::Point &start, Math::Point &end);
- void DimText(char *string, char *format, Math::Point pos, int justif, float size, float stretch, Math::Point &start, Math::Point &end);
- void DimText(char *string, int len, Math::Point pos, int justif, float size, float stretch, FontType font, Math::Point &start, Math::Point &end);
- void DimText(char *string, Math::Point pos, int justif, float size, float stretch, FontType font, Math::Point &start, Math::Point &end);
+ //! Returns the last encountered error
+ std::string GetError();
- float RetAscent(float size, FontType font);
- float RetDescent(float size, FontType font);
- float RetHeight(float size, FontType font);
+ //! Initializes the font engine; must be called after SetDevice()
+ bool Create();
+ //! Frees resources before exit
+ void Destroy();
- float RetStringWidth(char *string, char *format, int len, float size, float stretch);
- float RetStringWidth(char *string, int len, float size, float stretch, FontType font);
- float RetCharWidth(int character, float offset, float size, float stretch, FontType font);
+ //! Flushes cached textures
+ void FlushCache();
- int Justif(char *string, char *format, int len, float width, float size, float stretch);
- int Justif(char *string, int len, float width, float size, float stretch, FontType font);
- int Detect(char *string, char *format, int len, float offset, float size, float stretch);
- int Detect(char *string, int len, float offset, float size, float stretch, FontType font);
+ //! Draws text (multi-format)
+ void DrawText(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
+ Math::Point pos, float width, Gfx::JustifyType justify, float size,
+ float stretch, int eol);
+ //! Draws text (one font)
+ void DrawText(const std::string &text, Gfx::FontType font,
+ Math::Point pos, float width, Gfx::JustifyType justify, float size,
+ float stretch, int eol);
-protected:
- void DrawString(char *string, char *format, int len, Math::Point pos, float width, float size, float stretch, int eol);
- void DrawString(char *string, int len, Math::Point pos, float width, float size, float stretch, FontType font, int eol);
- void DrawColor(Math::Point pos, float size, float width, int color);
- void DrawChar(int character, Math::Point pos, float size, float stretch, FontType font);
+ //! Calculates dimensions for text (multi-format)
+ void SizeText(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
+ Math::Point pos, Gfx::JustifyType justify, float size,
+ Math::Point &start, Math::Point &end);
+ //! Calculates dimensions for text (one font)
+ void SizeText(const std::string &text, Gfx::FontType font,
+ Math::Point pos, Gfx::JustifyType justify, float size,
+ Math::Point &start, Math::Point &end);
+
+ //! Returns the ascent font metric
+ float GetAscent(Gfx::FontType font, float size);
+ //! Returns the descent font metric
+ float GetDescent(Gfx::FontType font, float size);
+ //! Returns the height font metric
+ float GetHeight(Gfx::FontType font, float size);
+
+ //! Returns width of string (multi-format)
+ float GetStringWidth(const std::string &text,
+ const std::vector<Gfx::FontMetaChar> &format, float size);
+ //! Returns width of string (single font)
+ float GetStringWidth(const std::string &text, Gfx::FontType font, float size);
+ //! Returns width of single character
+ float GetCharWidth(int character, Gfx::FontType font, float size, float offset);
+
+ //! Justifies a line of text (multi-format)
+ int Justify(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
+ float size, float width);
+ //! Justifies a line of text (one font)
+ int Justify(const std::string &text, Gfx::FontType font, float size, float width);
+
+ //! Returns the most suitable position to a given offset (multi-format)
+ int Detect(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
+ float size, float offset);
+ //! Returns the most suitable position to a given offset (one font)
+ int Detect(const std::string &text, Gfx::FontType font, float size, float offset);
+
+public: // for testing!
+ Gfx::CachedFont* GetOrOpenFont(Gfx::FontType type, float size);
+ Gfx::CharTexture CreateCharTexture(const char* utf8Char, Gfx::CachedFont* font);
+
+ void DrawString(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
+ float size, Math::Point pos, float width, int eol);
+ void DrawString(const std::string &text, Gfx::FontType font,
+ float size, Math::Point pos, float width, int eol);
+ void DrawColor(int color, float size, Math::Point pos, float width);
+ void DrawChar(UTF8Char character, Gfx::FontType font, float size, Math::Point &pos);
protected:
CInstanceManager* m_iMan;
Gfx::CEngine* m_engine;
Gfx::CDevice* m_device;
+ std::string m_error;
+ float m_defaultSize;
+ std::string m_fontPath;
+
+ std::map<Gfx::FontType, Gfx::MultisizeFont*> m_fonts;
+
+ Gfx::FontType m_lastFontType;
+ int m_lastFontSize;
+ Gfx::CachedFont* m_lastCachedFont;
};
}; // namespace Gfx
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index 3a255f4..cef372f 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -64,7 +64,6 @@ void Gfx::GLDeviceConfig::LoadDefault()
Gfx::CGLDevice::CGLDevice(const Gfx::GLDeviceConfig &config)
{
m_config = config;
- m_wasInit = false;
m_lighting = false;
m_texturing = false;
}
@@ -74,11 +73,6 @@ Gfx::CGLDevice::~CGLDevice()
{
}
-bool Gfx::CGLDevice::GetWasInit()
-{
- return m_wasInit;
-}
-
std::string Gfx::CGLDevice::GetError()
{
return m_error;
@@ -110,8 +104,6 @@ bool Gfx::CGLDevice::Create()
/* NOTE: when not using GLEW, extension testing is not performed, as it is assumed that
glext.h is up-to-date and the OpenGL shared library has the required functions present. */
- m_wasInit = true;
-
// This is mostly done in all modern hardware by default
// DirectX doesn't even allow the option to turn off perspective correction anymore
// So turn it on permanently
@@ -158,8 +150,6 @@ void Gfx::CGLDevice::Destroy()
m_currentTextures.clear();
m_texturesEnabled.clear();
m_textureStageParams.clear();
-
- m_wasInit = false;
}
void Gfx::CGLDevice::ConfigChanged(const Gfx::GLDeviceConfig& newConfig)
@@ -385,15 +375,20 @@ bool Gfx::CGLDevice::GetLightEnabled(int index)
This struct must not be deleted in other way than through DeleteTexture() */
Gfx::Texture Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCreateParams &params)
{
- Gfx::Texture result;
-
ImageData *data = image->GetData();
if (data == NULL)
{
m_error = "Invalid texture data";
- return result; // invalid texture
+ return Gfx::Texture(); // invalid texture
}
+ return CreateTexture(data, params);
+}
+
+Gfx::Texture Gfx::CGLDevice::CreateTexture(ImageData *data, const Gfx::TextureCreateParams &params)
+{
+ Gfx::Texture result;
+
result.valid = true;
result.size.w = data->surface->w;
result.size.h = data->surface->h;
@@ -531,6 +526,24 @@ void Gfx::CGLDevice::SetTexture(int index, const Gfx::Texture &texture)
glDisable(GL_TEXTURE_2D);
}
+void Gfx::CGLDevice::SetTexture(int index, unsigned int textureId)
+{
+ assert(index >= 0);
+ assert(index < static_cast<int>( m_currentTextures.size() ));
+
+ // Enable the given texture stage
+ glActiveTexture(GL_TEXTURE0 + index);
+ glEnable(GL_TEXTURE_2D);
+
+ m_currentTextures[index].id = textureId;
+
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ // Disable the stage if it is set so
+ if ( (! m_texturing) || (! m_texturesEnabled[index]) )
+ glDisable(GL_TEXTURE_2D);
+}
+
/**
Returns the previously assigned texture or invalid texture if the given stage is not enabled. */
Gfx::Texture Gfx::CGLDevice::GetTexture(int index)
diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h
index 1864000..a41c41c 100644
--- a/src/graphics/opengl/gldevice.h
+++ b/src/graphics/opengl/gldevice.h
@@ -73,7 +73,6 @@ public:
CGLDevice(const Gfx::GLDeviceConfig &config);
virtual ~CGLDevice();
- virtual bool GetWasInit();
virtual std::string GetError();
virtual bool Create();
@@ -100,11 +99,13 @@ public:
virtual bool GetLightEnabled(int index);
virtual Gfx::Texture CreateTexture(CImage *image, const Gfx::TextureCreateParams &params);
+ virtual Gfx::Texture CreateTexture(ImageData *data, const Gfx::TextureCreateParams &params);
virtual void DestroyTexture(const Gfx::Texture &texture);
virtual void DestroyAllTextures();
virtual int GetMaxTextureCount();
virtual void SetTexture(int index, const Gfx::Texture &texture);
+ virtual void SetTexture(int index, unsigned int textureId);
virtual Gfx::Texture GetTexture(int index);
virtual void SetTextureEnabled(int index, bool enabled);
virtual bool GetTextureEnabled(int index);
@@ -163,8 +164,6 @@ private:
private:
//! Current config
Gfx::GLDeviceConfig m_config;
- //! Was initialized?
- bool m_wasInit;
//! Last encountered error
std::string m_error;
diff --git a/src/math/const.h b/src/math/const.h
index dd7ab0f..b08a400 100644
--- a/src/math/const.h
+++ b/src/math/const.h
@@ -20,6 +20,8 @@
#pragma once
+#include <cmath>
+
// Math module namespace
namespace Math
@@ -30,12 +32,12 @@ namespace Math
const float TOLERANCE = 1e-6f;
//! Very small number (used in testing/returning some values)
-const float VERY_SMALL = 1e-6f;
+const float VERY_SMALL_NUM = 1e-6f;
//! Very big number (used in testing/returning some values)
-const float VERY_BIG = 1e6f;
+const float VERY_BIG_NUM = 1e6f;
//! Huge number
-const float HUGE = 1.0e+38f;
+const float HUGE_NUM = 1.0e+38f;
//! PI
const float PI = 3.14159265358979323846f;
@@ -45,6 +47,9 @@ const float DEG_TO_RAD = 0.01745329251994329547f;
//! Radians to degrees multiplier
const float RAD_TO_DEG = 57.29577951308232286465f;
+//! Natural logarithm of 2
+const float LOG_2 = log(2.0f);
+
/* @} */ // end of group
}; // namespace Math
diff --git a/src/math/func.h b/src/math/func.h
index 2127d1a..e97d990 100644
--- a/src/math/func.h
+++ b/src/math/func.h
@@ -127,6 +127,14 @@ inline float Rand()
return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
}
+//! Returns the next nearest power of two to \a x
+inline int NextPowerOfTwo(int x)
+{
+ double logbase2 = log(static_cast<float>(x)) / Math::LOG_2;
+ return static_cast<int>(pow(2, ceil(logbase2)) + 0.5);
+}
+
+
//! Returns a normalized angle, that is in other words between 0 and 2 * PI
inline float NormAngle(float angle)
{
diff --git a/src/math/geometry.h b/src/math/geometry.h
index 61d1868..3a31ad6 100644
--- a/src/math/geometry.h
+++ b/src/math/geometry.h
@@ -45,9 +45,9 @@ inline float MidPoint(const Math::Point &a, const Math::Point &b, float px)
if (IsEqual(a.x, b.x))
{
if (a.y < b.y)
- return HUGE;
+ return Math::HUGE_NUM;
else
- return -HUGE;
+ return -Math::HUGE_NUM;
}
return (b.y-a.y) * (px-a.x) / (b.x-a.x) + a.y;
}
diff --git a/src/math/intsize.h b/src/math/intsize.h
index f4b2431..d53de85 100644
--- a/src/math/intsize.h
+++ b/src/math/intsize.h
@@ -20,6 +20,9 @@
#pragma once
+#include "math/intpoint.h"
+
+
// Math module namespace
namespace Math
{
@@ -31,9 +34,9 @@ namespace Math
struct IntSize
{
//! Width
- int w;
+ long w;
//! Height
- int h;
+ long h;
//! Constructs a zero size: (0,0)
inline IntSize()
@@ -42,7 +45,7 @@ struct IntSize
}
//! Constructs a size from given dimensions: (w,h)
- inline explicit IntSize(int w, int h)
+ inline explicit IntSize(long w, long h)
{
this->w = w;
this->h = h;
@@ -53,6 +56,12 @@ struct IntSize
{
w = h = 0;
}
+
+ //! Converts Point to Size
+ inline static Math::IntSize FromIntPoint(Math::IntPoint p)
+ {
+ return Math::IntSize(p.x, p.y);
+ }
}; // struct Size
diff --git a/src/math/size.h b/src/math/size.h
index 781b9a4..03cffaa 100644
--- a/src/math/size.h
+++ b/src/math/size.h
@@ -20,6 +20,9 @@
#pragma once
+#include "math/point.h"
+
+
// Math module namespace
namespace Math
{
@@ -58,6 +61,12 @@ struct Size
{
w = h = 0.0f;
}
+
+ //! Converts Point to Size
+ inline static Math::Size FromPoint(Math::Point p)
+ {
+ return Math::Size(p.x, p.y);
+ }
}; // struct Size