parent
5e637ca028
commit
61bfb22f27
|
@ -8,6 +8,7 @@ project(colobot C CXX)
|
||||||
find_package(OpenGL 1.4 REQUIRED)
|
find_package(OpenGL 1.4 REQUIRED)
|
||||||
find_package(SDL 1.2.10 REQUIRED)
|
find_package(SDL 1.2.10 REQUIRED)
|
||||||
find_package(SDL_image 1.2 REQUIRED)
|
find_package(SDL_image 1.2 REQUIRED)
|
||||||
|
find_package(SDL_ttf 2.0 REQUIRED)
|
||||||
find_package(PNG 1.2 REQUIRED)
|
find_package(PNG 1.2 REQUIRED)
|
||||||
|
|
||||||
# GLEW requirement depends on platform
|
# GLEW requirement depends on platform
|
||||||
|
|
|
@ -176,6 +176,7 @@ graphics/opengl/gldevice.cpp
|
||||||
set(LIBS
|
set(LIBS
|
||||||
${SDL_LIBRARY}
|
${SDL_LIBRARY}
|
||||||
${SDLIMAGE_LIBRARY}
|
${SDLIMAGE_LIBRARY}
|
||||||
|
${SDLTTF_LIBRARY}
|
||||||
${OPENGL_LIBRARY}
|
${OPENGL_LIBRARY}
|
||||||
${PNG_LIBRARIES}
|
${PNG_LIBRARIES}
|
||||||
${OPTIONAL_LIBS}
|
${OPTIONAL_LIBS}
|
||||||
|
|
|
@ -122,6 +122,7 @@ bool CApplication::ParseArguments(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
waitDataDir = false;
|
waitDataDir = false;
|
||||||
m_dataPath = arg;
|
m_dataPath = arg;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arg == "-debug")
|
if (arg == "-debug")
|
||||||
|
@ -153,10 +154,6 @@ bool CApplication::Create()
|
||||||
// Temporarily -- only in windowed mode
|
// Temporarily -- only in windowed mode
|
||||||
m_deviceConfig.fullScreen = false;
|
m_deviceConfig.fullScreen = false;
|
||||||
|
|
||||||
// Create the 3D engine
|
|
||||||
m_engine = new Gfx::CEngine(m_iMan, this);
|
|
||||||
|
|
||||||
|
|
||||||
/* // Create the sound instance.
|
/* // Create the sound instance.
|
||||||
m_sound = new CSound(m_iMan);
|
m_sound = new CSound(m_iMan);
|
||||||
|
|
||||||
|
@ -224,20 +221,15 @@ bool CApplication::Create()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the 3D engine
|
||||||
|
m_engine = new Gfx::CEngine(m_iMan, this);
|
||||||
|
|
||||||
m_engine->SetDevice(m_device);
|
m_engine->SetDevice(m_device);
|
||||||
|
|
||||||
if (! m_engine->Create() )
|
if (! m_engine->Create() )
|
||||||
{
|
{
|
||||||
SystemDialog( SDT_ERROR, "COLOBT - Fatal Error",
|
SystemDialog( SDT_ERROR, "COLOBT - Fatal Error",
|
||||||
std::string("Error in CEngine::Create() :\n") +
|
std::string("Error in CEngine::Init() :\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(m_engine->GetError()) );
|
std::string(m_engine->GetError()) );
|
||||||
m_exitCode = 1;
|
m_exitCode = 1;
|
||||||
return false;
|
return false;
|
||||||
|
@ -315,8 +307,7 @@ void CApplication::Destroy()
|
||||||
|
|
||||||
if (m_engine != NULL)
|
if (m_engine != NULL)
|
||||||
{
|
{
|
||||||
if (m_engine->GetWasInit())
|
m_engine->Destroy();
|
||||||
m_engine->Destroy();
|
|
||||||
|
|
||||||
delete m_engine;
|
delete m_engine;
|
||||||
m_engine = NULL;
|
m_engine = NULL;
|
||||||
|
@ -324,8 +315,7 @@ void CApplication::Destroy()
|
||||||
|
|
||||||
if (m_device != NULL)
|
if (m_device != NULL)
|
||||||
{
|
{
|
||||||
if (m_device->GetWasInit())
|
m_device->Destroy();
|
||||||
m_device->Destroy();
|
|
||||||
|
|
||||||
delete m_device;
|
delete m_device;
|
||||||
m_device = NULL;
|
m_device = NULL;
|
||||||
|
@ -616,21 +606,6 @@ PressState TranslatePressState(unsigned char state)
|
||||||
return STATE_RELEASED;
|
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.
|
/** The SDL event parsed is stored internally.
|
||||||
If event is not available or is not understood, returned event is of type EVENT_NULL. */
|
If event is not available or is not understood, returned event is of type EVENT_NULL. */
|
||||||
Event CApplication::ParseEvent()
|
Event CApplication::ParseEvent()
|
||||||
|
@ -666,14 +641,16 @@ Event CApplication::ParseEvent()
|
||||||
|
|
||||||
event.mouseButton.button = m_private->currentEvent.button.button;
|
event.mouseButton.button = m_private->currentEvent.button.button;
|
||||||
event.mouseButton.state = TranslatePressState(m_private->currentEvent.button.state);
|
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)
|
else if (m_private->currentEvent.type == SDL_MOUSEMOTION)
|
||||||
{
|
{
|
||||||
event.type = EVENT_MOUSE_MOVE;
|
event.type = EVENT_MOUSE_MOVE;
|
||||||
|
|
||||||
event.mouseMove.state = TranslatePressState(m_private->currentEvent.button.state);
|
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)
|
else if (m_private->currentEvent.type == SDL_JOYAXISMOTION)
|
||||||
{
|
{
|
||||||
|
@ -792,6 +769,11 @@ void CApplication::StepSimulation(float rTime)
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Gfx::GLDeviceConfig CApplication::GetVideoConfig()
|
||||||
|
{
|
||||||
|
return m_deviceConfig;
|
||||||
|
}
|
||||||
|
|
||||||
VideoQueryResult CApplication::GetVideoResolutionList(std::vector<Math::IntSize> &resolutions,
|
VideoQueryResult CApplication::GetVideoResolutionList(std::vector<Math::IntSize> &resolutions,
|
||||||
bool fullScreen, bool resizeable)
|
bool fullScreen, bool resizeable)
|
||||||
{
|
{
|
||||||
|
@ -891,7 +873,7 @@ bool CApplication::GetSystemMouseVisibile()
|
||||||
|
|
||||||
void CApplication::SetSystemMousePos(Math::Point pos)
|
void CApplication::SetSystemMousePos(Math::Point pos)
|
||||||
{
|
{
|
||||||
Math::IntPoint windowPos = InterfaceToWindowCoords(pos);
|
Math::IntPoint windowPos = m_engine->InterfaceToWindowCoords(pos);
|
||||||
SDL_WarpMouse(windowPos.x, windowPos.y);
|
SDL_WarpMouse(windowPos.x, windowPos.y);
|
||||||
m_systemMousePos = pos;
|
m_systemMousePos = pos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
#include "graphics/core/device.h"
|
#include "graphics/core/device.h"
|
||||||
#include "graphics/engine/engine.h"
|
#include "graphics/engine/engine.h"
|
||||||
#include "graphics/opengl/gldevice.h"
|
#include "graphics/opengl/gldevice.h"
|
||||||
#include "math/intsize.h"
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -206,11 +205,6 @@ protected:
|
||||||
//! Closes the joystick device
|
//! Closes the joystick device
|
||||||
void CloseJoystick();
|
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:
|
protected:
|
||||||
//! Instance manager
|
//! Instance manager
|
||||||
CInstanceManager* m_iMan;
|
CInstanceManager* m_iMan;
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
|
|
||||||
class CImage;
|
class CImage;
|
||||||
|
struct ImageData;
|
||||||
|
|
||||||
|
|
||||||
namespace Gfx {
|
namespace Gfx {
|
||||||
|
@ -279,8 +280,6 @@ public:
|
||||||
//! Destroys the device, releasing every acquired resource
|
//! Destroys the device, releasing every acquired resource
|
||||||
virtual void Destroy() = 0;
|
virtual void Destroy() = 0;
|
||||||
|
|
||||||
//! Returns whether the device has been initialized
|
|
||||||
virtual bool GetWasInit() = 0;
|
|
||||||
//! Returns the last encountered error
|
//! Returns the last encountered error
|
||||||
virtual std::string GetError() = 0;
|
virtual std::string GetError() = 0;
|
||||||
|
|
||||||
|
@ -317,6 +316,8 @@ public:
|
||||||
|
|
||||||
//! Creates a texture from image; the image can be safely removed after that
|
//! Creates a texture from image; the image can be safely removed after that
|
||||||
virtual Gfx::Texture CreateTexture(CImage *image, const Gfx::TextureCreateParams ¶ms) = 0;
|
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
|
//! Deletes a given texture, freeing it from video memory
|
||||||
virtual void DestroyTexture(const Gfx::Texture &texture) = 0;
|
virtual void DestroyTexture(const Gfx::Texture &texture) = 0;
|
||||||
//! Deletes all textures created so far
|
//! Deletes all textures created so far
|
||||||
|
@ -324,8 +325,10 @@ public:
|
||||||
|
|
||||||
//! Returns the maximum number of multitexture stages
|
//! Returns the maximum number of multitexture stages
|
||||||
virtual int GetMaxTextureCount() = 0;
|
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;
|
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
|
//! Returns the (multi)texture at given index
|
||||||
virtual Gfx::Texture GetTexture(int index) = 0;
|
virtual Gfx::Texture GetTexture(int index) = 0;
|
||||||
//! Enables/disables the given texture stage
|
//! Enables/disables the given texture stage
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
#include "common/key.h"
|
#include "common/key.h"
|
||||||
#include "common/logger.h"
|
#include "common/logger.h"
|
||||||
#include "graphics/core/device.h"
|
#include "graphics/core/device.h"
|
||||||
|
#include "graphics/engine/lightman.h"
|
||||||
|
#include "graphics/engine/text.h"
|
||||||
#include "math/geometry.h"
|
#include "math/geometry.h"
|
||||||
|
|
||||||
// Initial size of various vectors
|
// Initial size of various vectors
|
||||||
|
@ -44,23 +46,21 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app)
|
||||||
{
|
{
|
||||||
m_iMan = iMan;
|
m_iMan = iMan;
|
||||||
m_app = app;
|
m_app = app;
|
||||||
m_device = NULL;
|
m_device = nullptr;
|
||||||
|
|
||||||
m_wasInit = false;
|
|
||||||
|
|
||||||
m_iMan = iMan;
|
m_iMan = iMan;
|
||||||
m_iMan->AddInstance(CLASS_ENGINE, this);
|
m_iMan->AddInstance(CLASS_ENGINE, this);
|
||||||
m_app = app;
|
m_app = app;
|
||||||
|
|
||||||
m_lightMan = NULL;
|
m_lightMan = nullptr;
|
||||||
m_text = NULL;
|
m_text = nullptr;
|
||||||
m_particle = NULL;
|
m_particle = nullptr;
|
||||||
m_water = NULL;
|
m_water = nullptr;
|
||||||
m_cloud = NULL;
|
m_cloud = nullptr;
|
||||||
m_lightning = NULL;
|
m_lightning = nullptr;
|
||||||
m_planet = NULL;
|
m_planet = nullptr;
|
||||||
m_sound = NULL;
|
m_sound = nullptr;
|
||||||
m_terrain = NULL;
|
m_terrain = nullptr;
|
||||||
|
|
||||||
m_focus = 0.75f;
|
m_focus = 0.75f;
|
||||||
m_baseTime = 0;
|
m_baseTime = 0;
|
||||||
|
@ -178,17 +178,12 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app)
|
||||||
|
|
||||||
Gfx::CEngine::~CEngine()
|
Gfx::CEngine::~CEngine()
|
||||||
{
|
{
|
||||||
m_iMan = NULL;
|
m_iMan = nullptr;
|
||||||
m_app = NULL;
|
m_app = nullptr;
|
||||||
m_device = NULL;
|
m_device = nullptr;
|
||||||
|
|
||||||
m_sound = NULL;
|
m_sound = nullptr;
|
||||||
m_terrain = NULL;
|
m_terrain = nullptr;
|
||||||
}
|
|
||||||
|
|
||||||
bool Gfx::CEngine::GetWasInit()
|
|
||||||
{
|
|
||||||
return m_wasInit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Gfx::CEngine::GetError()
|
std::string Gfx::CEngine::GetError()
|
||||||
|
@ -196,53 +191,6 @@ std::string Gfx::CEngine::GetError()
|
||||||
return m_error;
|
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)
|
void Gfx::CEngine::SetDevice(Gfx::CDevice *device)
|
||||||
{
|
{
|
||||||
m_device = device;
|
m_device = device;
|
||||||
|
@ -253,8 +201,31 @@ Gfx::CDevice* Gfx::CEngine::GetDevice()
|
||||||
return m_device;
|
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->SetClearColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false);
|
m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false);
|
||||||
|
@ -269,12 +240,38 @@ bool Gfx::CEngine::AfterDeviceSetInit()
|
||||||
return true;
|
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()
|
void Gfx::CEngine::ResetAfterDeviceChanged()
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName, const Gfx::TextureCreateParams ¶ms)
|
Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName, const Gfx::TextureCreateParams ¶ms)
|
||||||
{
|
{
|
||||||
CImage img;
|
CImage img;
|
||||||
|
@ -610,9 +607,38 @@ bool Gfx::CEngine::DrawInterface()
|
||||||
|
|
||||||
DrawMouse();
|
DrawMouse();
|
||||||
|
|
||||||
|
m_text->DrawString("abcdefghijklmnopqrstuvwxyz ąęśćółńż", Gfx::FONT_COLOBOT, 15.0f, Math::Point(0.25f, 0.2f), 1.0f, 0);
|
||||||
|
|
||||||
return true;
|
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()
|
void Gfx::CEngine::DrawMouse()
|
||||||
{
|
{
|
||||||
if (! m_mouseVisible)
|
if (! m_mouseVisible)
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "math/intsize.h"
|
#include "math/intsize.h"
|
||||||
#include "math/matrix.h"
|
#include "math/matrix.h"
|
||||||
#include "math/point.h"
|
#include "math/point.h"
|
||||||
|
#include "math/size.h"
|
||||||
#include "math/vector.h"
|
#include "math/vector.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -514,23 +515,18 @@ public:
|
||||||
CEngine(CInstanceManager *iMan, CApplication *app);
|
CEngine(CInstanceManager *iMan, CApplication *app);
|
||||||
~CEngine();
|
~CEngine();
|
||||||
|
|
||||||
//! Returns whether the device was initialized
|
|
||||||
bool GetWasInit();
|
|
||||||
//! Returns the last error encountered
|
//! Returns the last error encountered
|
||||||
std::string GetError();
|
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
|
//! Sets the device to be used
|
||||||
void SetDevice(Gfx::CDevice *device);
|
void SetDevice(Gfx::CDevice *device);
|
||||||
//! Returns the current device
|
//! Returns the current device
|
||||||
Gfx::CDevice* GetDevice();
|
Gfx::CDevice* GetDevice();
|
||||||
|
|
||||||
//! Performs initialization after a device was created and set
|
//! Performs the initialization; must be called after device was set
|
||||||
bool AfterDeviceSetInit();
|
bool Create();
|
||||||
|
//! Frees all resources before exit
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
//! Resets some states and flushes textures after device was changed (e.g. resoulution changed)
|
//! Resets some states and flushes textures after device was changed (e.g. resoulution changed)
|
||||||
void ResetAfterDeviceChanged();
|
void ResetAfterDeviceChanged();
|
||||||
|
@ -544,6 +540,17 @@ public:
|
||||||
bool Render();
|
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();
|
bool WriteProfile();
|
||||||
|
|
||||||
void SetPause(bool pause);
|
void SetPause(bool pause);
|
||||||
|
@ -769,7 +776,8 @@ public:
|
||||||
Math::Vector GetLookatPt();
|
Math::Vector GetLookatPt();
|
||||||
float GetEyeDirH();
|
float GetEyeDirH();
|
||||||
float GetEyeDirV();
|
float GetEyeDirV();
|
||||||
Math::Point GetDim();
|
Math::IntPoint GetViewportSize();
|
||||||
|
Math::IntPoint GetLastViewportSize();
|
||||||
void UpdateMatProj();
|
void UpdateMatProj();
|
||||||
|
|
||||||
void ApplyChange();
|
void ApplyChange();
|
||||||
|
@ -903,8 +911,9 @@ protected:
|
||||||
bool m_render;
|
bool m_render;
|
||||||
bool m_movieLock;
|
bool m_movieLock;
|
||||||
|
|
||||||
//! Current size of window
|
//! Current size of viewport
|
||||||
Math::IntSize m_size;
|
Math::IntSize m_size;
|
||||||
|
//! Previous size of viewport
|
||||||
Math::IntSize m_lastSize;
|
Math::IntSize m_lastSize;
|
||||||
|
|
||||||
std::vector<Gfx::EngineObjLevel1> m_objectTree;
|
std::vector<Gfx::EngineObjLevel1> m_objectTree;
|
||||||
|
|
|
@ -19,5 +19,480 @@
|
||||||
|
|
||||||
#include "graphics/engine/text.h"
|
#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
|
#pragma once
|
||||||
|
|
||||||
#include "graphics/engine/engine.h"
|
|
||||||
#include "graphics/core/device.h"
|
|
||||||
#include "math/point.h"
|
#include "math/point.h"
|
||||||
|
#include "math/size.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
class CInstanceManager;
|
class CInstanceManager;
|
||||||
|
|
||||||
|
|
||||||
namespace Gfx {
|
namespace Gfx {
|
||||||
|
|
||||||
const float SMALLFONT = 10.0f;
|
class CEngine;
|
||||||
const float BIGFONT = 15.0f;
|
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
|
enum FontType
|
||||||
{
|
{
|
||||||
FONT_COLOBOT = 0,
|
//! Flag for bold font subtype
|
||||||
FONT_COURIER = 1,
|
FONT_BOLD = 0x04,
|
||||||
FONT_BUTTON = 2,
|
//! 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
|
enum FontTitle
|
||||||
{
|
{
|
||||||
TITLE_BIG = 0x04,
|
FONT_TITLE_BIG = 0x01 << 4,
|
||||||
TITLE_NORM = 0x08,
|
FONT_TITLE_NORM = 0x02 << 4,
|
||||||
TITLE_LITTLE = 0x0c,
|
FONT_TITLE_LITTLE = 0x03 << 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
\enum FontColor
|
||||||
|
\brief Font color type (?)
|
||||||
|
|
||||||
|
Bitmask in 3 bits left shifted 6 (mask 0x1c0) */
|
||||||
enum FontColor
|
enum FontColor
|
||||||
{
|
{
|
||||||
COLOR_LINK = 0x10,
|
FONT_COLOR_LINK = 0x01 << 6,
|
||||||
COLOR_TOKEN = 0x20,
|
FONT_COLOR_TOKEN = 0x02 << 6,
|
||||||
COLOR_TYPE = 0x30,
|
FONT_COLOR_TYPE = 0x03 << 6,
|
||||||
COLOR_CONST = 0x40,
|
FONT_COLOR_CONST = 0x04 << 6,
|
||||||
COLOR_REM = 0x50,
|
FONT_COLOR_REM = 0x05 << 6,
|
||||||
COLOR_KEY = 0x60,
|
FONT_COLOR_KEY = 0x06 << 6,
|
||||||
COLOR_TABLE = 0x70,
|
FONT_COLOR_TABLE = 0x07 << 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
const short FONT_MASK = 0x03;
|
/**
|
||||||
const short TITLE_MASK = 0x0c;
|
\enum FontMask
|
||||||
const short COLOR_MASK = 0x70;
|
\brief Masks in FontMetaChar for different attributes */
|
||||||
const short IMAGE_MASK = 0x80;
|
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:
|
public:
|
||||||
CText(CInstanceManager *iMan, Gfx::CEngine* engine);
|
CText(CInstanceManager *iMan, Gfx::CEngine* engine);
|
||||||
~CText();
|
~CText();
|
||||||
|
|
||||||
|
//! Sets the device to be used
|
||||||
void SetDevice(Gfx::CDevice *device);
|
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);
|
//! Returns the last encountered error
|
||||||
void DrawText(char *string, char *format, Math::Point pos, float width, int justif, float size, float stretch, int eol);
|
std::string GetError();
|
||||||
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);
|
|
||||||
|
|
||||||
float RetAscent(float size, FontType font);
|
//! Initializes the font engine; must be called after SetDevice()
|
||||||
float RetDescent(float size, FontType font);
|
bool Create();
|
||||||
float RetHeight(float size, FontType font);
|
//! Frees resources before exit
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
float RetStringWidth(char *string, char *format, int len, float size, float stretch);
|
//! Flushes cached textures
|
||||||
float RetStringWidth(char *string, int len, float size, float stretch, FontType font);
|
void FlushCache();
|
||||||
float RetCharWidth(int character, float offset, float size, float stretch, FontType font);
|
|
||||||
|
|
||||||
int Justif(char *string, char *format, int len, float width, float size, float stretch);
|
//! Draws text (multi-format)
|
||||||
int Justif(char *string, int len, float width, float size, float stretch, FontType font);
|
void DrawText(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
|
||||||
int Detect(char *string, char *format, int len, float offset, float size, float stretch);
|
Math::Point pos, float width, Gfx::JustifyType justify, float size,
|
||||||
int Detect(char *string, int len, float offset, float size, float stretch, FontType font);
|
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:
|
//! Calculates dimensions for text (multi-format)
|
||||||
void DrawString(char *string, char *format, int len, Math::Point pos, float width, float size, float stretch, int eol);
|
void SizeText(const std::string &text, const std::vector<Gfx::FontMetaChar> &format,
|
||||||
void DrawString(char *string, int len, Math::Point pos, float width, float size, float stretch, FontType font, int eol);
|
Math::Point pos, Gfx::JustifyType justify, float size,
|
||||||
void DrawColor(Math::Point pos, float size, float width, int color);
|
Math::Point &start, Math::Point &end);
|
||||||
void DrawChar(int character, Math::Point pos, float size, float stretch, FontType font);
|
//! 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:
|
protected:
|
||||||
CInstanceManager* m_iMan;
|
CInstanceManager* m_iMan;
|
||||||
Gfx::CEngine* m_engine;
|
Gfx::CEngine* m_engine;
|
||||||
Gfx::CDevice* m_device;
|
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
|
}; // namespace Gfx
|
||||||
|
|
|
@ -64,7 +64,6 @@ void Gfx::GLDeviceConfig::LoadDefault()
|
||||||
Gfx::CGLDevice::CGLDevice(const Gfx::GLDeviceConfig &config)
|
Gfx::CGLDevice::CGLDevice(const Gfx::GLDeviceConfig &config)
|
||||||
{
|
{
|
||||||
m_config = config;
|
m_config = config;
|
||||||
m_wasInit = false;
|
|
||||||
m_lighting = false;
|
m_lighting = false;
|
||||||
m_texturing = false;
|
m_texturing = false;
|
||||||
}
|
}
|
||||||
|
@ -74,11 +73,6 @@ Gfx::CGLDevice::~CGLDevice()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Gfx::CGLDevice::GetWasInit()
|
|
||||||
{
|
|
||||||
return m_wasInit;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Gfx::CGLDevice::GetError()
|
std::string Gfx::CGLDevice::GetError()
|
||||||
{
|
{
|
||||||
return m_error;
|
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
|
/* 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. */
|
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
|
// This is mostly done in all modern hardware by default
|
||||||
// DirectX doesn't even allow the option to turn off perspective correction anymore
|
// DirectX doesn't even allow the option to turn off perspective correction anymore
|
||||||
// So turn it on permanently
|
// So turn it on permanently
|
||||||
|
@ -158,8 +150,6 @@ void Gfx::CGLDevice::Destroy()
|
||||||
m_currentTextures.clear();
|
m_currentTextures.clear();
|
||||||
m_texturesEnabled.clear();
|
m_texturesEnabled.clear();
|
||||||
m_textureStageParams.clear();
|
m_textureStageParams.clear();
|
||||||
|
|
||||||
m_wasInit = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx::CGLDevice::ConfigChanged(const Gfx::GLDeviceConfig& newConfig)
|
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() */
|
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 Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCreateParams ¶ms)
|
||||||
{
|
{
|
||||||
Gfx::Texture result;
|
|
||||||
|
|
||||||
ImageData *data = image->GetData();
|
ImageData *data = image->GetData();
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
{
|
{
|
||||||
m_error = "Invalid texture data";
|
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.valid = true;
|
||||||
result.size.w = data->surface->w;
|
result.size.w = data->surface->w;
|
||||||
result.size.h = data->surface->h;
|
result.size.h = data->surface->h;
|
||||||
|
@ -531,6 +526,24 @@ void Gfx::CGLDevice::SetTexture(int index, const Gfx::Texture &texture)
|
||||||
glDisable(GL_TEXTURE_2D);
|
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. */
|
Returns the previously assigned texture or invalid texture if the given stage is not enabled. */
|
||||||
Gfx::Texture Gfx::CGLDevice::GetTexture(int index)
|
Gfx::Texture Gfx::CGLDevice::GetTexture(int index)
|
||||||
|
|
|
@ -73,7 +73,6 @@ public:
|
||||||
CGLDevice(const Gfx::GLDeviceConfig &config);
|
CGLDevice(const Gfx::GLDeviceConfig &config);
|
||||||
virtual ~CGLDevice();
|
virtual ~CGLDevice();
|
||||||
|
|
||||||
virtual bool GetWasInit();
|
|
||||||
virtual std::string GetError();
|
virtual std::string GetError();
|
||||||
|
|
||||||
virtual bool Create();
|
virtual bool Create();
|
||||||
|
@ -100,11 +99,13 @@ public:
|
||||||
virtual bool GetLightEnabled(int index);
|
virtual bool GetLightEnabled(int index);
|
||||||
|
|
||||||
virtual Gfx::Texture CreateTexture(CImage *image, const Gfx::TextureCreateParams ¶ms);
|
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 DestroyTexture(const Gfx::Texture &texture);
|
||||||
virtual void DestroyAllTextures();
|
virtual void DestroyAllTextures();
|
||||||
|
|
||||||
virtual int GetMaxTextureCount();
|
virtual int GetMaxTextureCount();
|
||||||
virtual void SetTexture(int index, const Gfx::Texture &texture);
|
virtual void SetTexture(int index, const Gfx::Texture &texture);
|
||||||
|
virtual void SetTexture(int index, unsigned int textureId);
|
||||||
virtual Gfx::Texture GetTexture(int index);
|
virtual Gfx::Texture GetTexture(int index);
|
||||||
virtual void SetTextureEnabled(int index, bool enabled);
|
virtual void SetTextureEnabled(int index, bool enabled);
|
||||||
virtual bool GetTextureEnabled(int index);
|
virtual bool GetTextureEnabled(int index);
|
||||||
|
@ -163,8 +164,6 @@ private:
|
||||||
private:
|
private:
|
||||||
//! Current config
|
//! Current config
|
||||||
Gfx::GLDeviceConfig m_config;
|
Gfx::GLDeviceConfig m_config;
|
||||||
//! Was initialized?
|
|
||||||
bool m_wasInit;
|
|
||||||
//! Last encountered error
|
//! Last encountered error
|
||||||
std::string m_error;
|
std::string m_error;
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
|
||||||
// Math module namespace
|
// Math module namespace
|
||||||
namespace Math
|
namespace Math
|
||||||
|
@ -30,12 +32,12 @@ namespace Math
|
||||||
const float TOLERANCE = 1e-6f;
|
const float TOLERANCE = 1e-6f;
|
||||||
|
|
||||||
//! Very small number (used in testing/returning some values)
|
//! 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)
|
//! Very big number (used in testing/returning some values)
|
||||||
const float VERY_BIG = 1e6f;
|
const float VERY_BIG_NUM = 1e6f;
|
||||||
|
|
||||||
//! Huge number
|
//! Huge number
|
||||||
const float HUGE = 1.0e+38f;
|
const float HUGE_NUM = 1.0e+38f;
|
||||||
|
|
||||||
//! PI
|
//! PI
|
||||||
const float PI = 3.14159265358979323846f;
|
const float PI = 3.14159265358979323846f;
|
||||||
|
@ -45,6 +47,9 @@ const float DEG_TO_RAD = 0.01745329251994329547f;
|
||||||
//! Radians to degrees multiplier
|
//! Radians to degrees multiplier
|
||||||
const float RAD_TO_DEG = 57.29577951308232286465f;
|
const float RAD_TO_DEG = 57.29577951308232286465f;
|
||||||
|
|
||||||
|
//! Natural logarithm of 2
|
||||||
|
const float LOG_2 = log(2.0f);
|
||||||
|
|
||||||
/* @} */ // end of group
|
/* @} */ // end of group
|
||||||
}; // namespace Math
|
}; // namespace Math
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,14 @@ inline float Rand()
|
||||||
return static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
|
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
|
//! Returns a normalized angle, that is in other words between 0 and 2 * PI
|
||||||
inline float NormAngle(float angle)
|
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 (IsEqual(a.x, b.x))
|
||||||
{
|
{
|
||||||
if (a.y < b.y)
|
if (a.y < b.y)
|
||||||
return HUGE;
|
return Math::HUGE_NUM;
|
||||||
else
|
else
|
||||||
return -HUGE;
|
return -Math::HUGE_NUM;
|
||||||
}
|
}
|
||||||
return (b.y-a.y) * (px-a.x) / (b.x-a.x) + a.y;
|
return (b.y-a.y) * (px-a.x) / (b.x-a.x) + a.y;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "math/intpoint.h"
|
||||||
|
|
||||||
|
|
||||||
// Math module namespace
|
// Math module namespace
|
||||||
namespace Math
|
namespace Math
|
||||||
{
|
{
|
||||||
|
@ -31,9 +34,9 @@ namespace Math
|
||||||
struct IntSize
|
struct IntSize
|
||||||
{
|
{
|
||||||
//! Width
|
//! Width
|
||||||
int w;
|
long w;
|
||||||
//! Height
|
//! Height
|
||||||
int h;
|
long h;
|
||||||
|
|
||||||
//! Constructs a zero size: (0,0)
|
//! Constructs a zero size: (0,0)
|
||||||
inline IntSize()
|
inline IntSize()
|
||||||
|
@ -42,7 +45,7 @@ struct IntSize
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Constructs a size from given dimensions: (w,h)
|
//! 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->w = w;
|
||||||
this->h = h;
|
this->h = h;
|
||||||
|
@ -53,6 +56,12 @@ struct IntSize
|
||||||
{
|
{
|
||||||
w = h = 0;
|
w = h = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Converts Point to Size
|
||||||
|
inline static Math::IntSize FromIntPoint(Math::IntPoint p)
|
||||||
|
{
|
||||||
|
return Math::IntSize(p.x, p.y);
|
||||||
|
}
|
||||||
}; // struct Size
|
}; // struct Size
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,9 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "math/point.h"
|
||||||
|
|
||||||
|
|
||||||
// Math module namespace
|
// Math module namespace
|
||||||
namespace Math
|
namespace Math
|
||||||
{
|
{
|
||||||
|
@ -58,6 +61,12 @@ struct Size
|
||||||
{
|
{
|
||||||
w = h = 0.0f;
|
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
|
}; // struct Size
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue