parent
5e637ca028
commit
61bfb22f27
|
@ -8,6 +8,7 @@ project(colobot C CXX)
|
|||
find_package(OpenGL 1.4 REQUIRED)
|
||||
find_package(SDL 1.2.10 REQUIRED)
|
||||
find_package(SDL_image 1.2 REQUIRED)
|
||||
find_package(SDL_ttf 2.0 REQUIRED)
|
||||
find_package(PNG 1.2 REQUIRED)
|
||||
|
||||
# GLEW requirement depends on platform
|
||||
|
|
|
@ -176,6 +176,7 @@ graphics/opengl/gldevice.cpp
|
|||
set(LIBS
|
||||
${SDL_LIBRARY}
|
||||
${SDLIMAGE_LIBRARY}
|
||||
${SDLTTF_LIBRARY}
|
||||
${OPENGL_LIBRARY}
|
||||
${PNG_LIBRARIES}
|
||||
${OPTIONAL_LIBS}
|
||||
|
|
|
@ -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() )
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ¶ms) = 0;
|
||||
//! Creates a texture from raw image data; image data can be freed after that
|
||||
virtual Gfx::Texture CreateTexture(ImageData *data, const Gfx::TextureCreateParams ¶ms) = 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
|
||||
|
|
|
@ -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,17 +178,12 @@ 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;
|
||||
}
|
||||
|
||||
bool Gfx::CEngine::GetWasInit()
|
||||
{
|
||||
return m_wasInit;
|
||||
m_sound = nullptr;
|
||||
m_terrain = nullptr;
|
||||
}
|
||||
|
||||
std::string Gfx::CEngine::GetError()
|
||||
|
@ -196,53 +191,6 @@ std::string Gfx::CEngine::GetError()
|
|||
return m_error;
|
||||
}
|
||||
|
||||
bool Gfx::CEngine::Create()
|
||||
{
|
||||
m_wasInit = true;
|
||||
|
||||
/*m_lightMan = new Gfx::CLight(m_iMan, this);
|
||||
m_text = new Gfx::CText(m_iMan, this);
|
||||
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_matWorldInterface.LoadIdentity();
|
||||
m_matViewInterface.LoadIdentity();
|
||||
Math::LoadOrthoProjectionMatrix(m_matProjInterface, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Gfx::CEngine::Destroy()
|
||||
{
|
||||
// TODO
|
||||
|
||||
/*delete m_lightMan;
|
||||
m_lightMan = NULL;
|
||||
|
||||
delete m_text;
|
||||
m_text = NULL;
|
||||
|
||||
delete m_particle;
|
||||
m_particle = NULL;
|
||||
|
||||
delete m_water;
|
||||
m_water = NULL;
|
||||
|
||||
delete m_cloud;
|
||||
m_cloud = NULL;
|
||||
|
||||
delete m_lightning;
|
||||
m_lightning = NULL;
|
||||
|
||||
delete m_planet;
|
||||
m_planet = NULL;*/
|
||||
|
||||
m_wasInit = false;
|
||||
}
|
||||
|
||||
void Gfx::CEngine::SetDevice(Gfx::CDevice *device)
|
||||
{
|
||||
m_device = device;
|
||||
|
@ -253,8 +201,31 @@ Gfx::CDevice* Gfx::CEngine::GetDevice()
|
|||
return m_device;
|
||||
}
|
||||
|
||||
bool Gfx::CEngine::AfterDeviceSetInit()
|
||||
bool Gfx::CEngine::Create()
|
||||
{
|
||||
m_size = m_lastSize = m_app->GetVideoConfig().size;
|
||||
|
||||
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);
|
||||
|
@ -269,12 +240,38 @@ bool Gfx::CEngine::AfterDeviceSetInit()
|
|||
return true;
|
||||
}
|
||||
|
||||
void Gfx::CEngine::Destroy()
|
||||
{
|
||||
m_text->Destroy();
|
||||
|
||||
delete m_lightMan;
|
||||
m_lightMan = nullptr;
|
||||
|
||||
delete m_text;
|
||||
m_text = nullptr;
|
||||
|
||||
/* TODO:
|
||||
delete m_particle;
|
||||
m_particle = nullptr;
|
||||
|
||||
delete m_water;
|
||||
m_water = nullptr;
|
||||
|
||||
delete m_cloud;
|
||||
m_cloud = nullptr;
|
||||
|
||||
delete m_lightning;
|
||||
m_lightning = nullptr;
|
||||
|
||||
delete m_planet;
|
||||
m_planet = nullptr;*/
|
||||
}
|
||||
|
||||
void Gfx::CEngine::ResetAfterDeviceChanged()
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
||||
Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName, const Gfx::TextureCreateParams ¶ms)
|
||||
{
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
const float NORMSTRETCH = 0.8f;
|
||||
//! 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
|
||||
};
|
||||
|
||||
/* 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
|
||||
|
||||
class CText {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\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
|
||||
|
|
|
@ -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 ¶ms)
|
||||
{
|
||||
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 ¶ms)
|
||||
{
|
||||
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)
|
||||
|
|
|
@ -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 ¶ms);
|
||||
virtual Gfx::Texture CreateTexture(ImageData *data, const Gfx::TextureCreateParams ¶ms);
|
||||
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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue