From 61bfb22f27f5216f989c023a5e39fad7e356d2d6 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 3 Aug 2012 23:23:13 +0200 Subject: [PATCH 01/10] Basic font rendering - added basic font rendering - minor refactoring & fixes --- CMakeLists.txt | 1 + src/CMakeLists.txt | 1 + src/app/app.cpp | 54 ++-- src/app/app.h | 6 - src/graphics/core/device.h | 9 +- src/graphics/engine/engine.cpp | 168 ++++++----- src/graphics/engine/engine.h | 31 +- src/graphics/engine/text.cpp | 477 ++++++++++++++++++++++++++++++- src/graphics/engine/text.h | 267 ++++++++++++++--- src/graphics/opengl/gldevice.cpp | 39 ++- src/graphics/opengl/gldevice.h | 5 +- src/math/const.h | 11 +- src/math/func.h | 8 + src/math/geometry.h | 4 +- src/math/intsize.h | 15 +- src/math/size.h | 9 + 16 files changed, 906 insertions(+), 199 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 98e97325..04b89124 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9bcd288e..25a576e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -176,6 +176,7 @@ graphics/opengl/gldevice.cpp set(LIBS ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} +${SDLTTF_LIBRARY} ${OPENGL_LIBRARY} ${PNG_LIBRARIES} ${OPTIONAL_LIBS} diff --git a/src/app/app.cpp b/src/app/app.cpp index d20232d0..36811726 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -122,6 +122,7 @@ bool CApplication::ParseArguments(int argc, char *argv[]) { waitDataDir = false; m_dataPath = arg; + continue; } if (arg == "-debug") @@ -153,10 +154,6 @@ bool CApplication::Create() // Temporarily -- only in windowed mode m_deviceConfig.fullScreen = false; - // Create the 3D engine - m_engine = new Gfx::CEngine(m_iMan, this); - - /* // Create the sound instance. m_sound = new CSound(m_iMan); @@ -224,20 +221,15 @@ bool CApplication::Create() return false; } + // Create the 3D engine + m_engine = new Gfx::CEngine(m_iMan, this); + m_engine->SetDevice(m_device); + if (! m_engine->Create() ) { SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", - std::string("Error in CEngine::Create() :\n") + - std::string(m_engine->GetError()) ); - m_exitCode = 1; - return false; - } - - if (! m_engine->AfterDeviceSetInit() ) - { - 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(pos.x) / static_cast(m_deviceConfig.size.w), - 1.0f - static_cast(pos.y) / static_cast(m_deviceConfig.size.h) ); -} - -Math::IntPoint CApplication::InterfaceToWindowCoords(Math::Point pos) -{ - return Math::IntPoint(static_cast(pos.x * m_deviceConfig.size.w), - static_cast((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 &resolutions, bool fullScreen, bool resizeable) { @@ -891,7 +873,7 @@ bool CApplication::GetSystemMouseVisibile() void CApplication::SetSystemMousePos(Math::Point pos) { - Math::IntPoint windowPos = InterfaceToWindowCoords(pos); + Math::IntPoint windowPos = m_engine->InterfaceToWindowCoords(pos); SDL_WarpMouse(windowPos.x, windowPos.y); m_systemMousePos = pos; } diff --git a/src/app/app.h b/src/app/app.h index 483aa55c..bba55b23 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -25,7 +25,6 @@ #include "graphics/core/device.h" #include "graphics/engine/engine.h" #include "graphics/opengl/gldevice.h" -#include "math/intsize.h" #include #include @@ -206,11 +205,6 @@ protected: //! Closes the joystick device void CloseJoystick(); - //! Converts window coords to interface coords - Math::Point WindowToInterfaceCoords(Math::IntPoint pos); - //! Converts the interface coords to window coords - Math::IntPoint InterfaceToWindowCoords(Math::Point pos); - protected: //! Instance manager CInstanceManager* m_iMan; diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h index c10b8534..3ab86ddb 100644 --- a/src/graphics/core/device.h +++ b/src/graphics/core/device.h @@ -32,6 +32,7 @@ class CImage; +struct ImageData; namespace Gfx { @@ -279,8 +280,6 @@ public: //! Destroys the device, releasing every acquired resource virtual void Destroy() = 0; - //! Returns whether the device has been initialized - virtual bool GetWasInit() = 0; //! Returns the last encountered error virtual std::string GetError() = 0; @@ -317,6 +316,8 @@ public: //! Creates a texture from image; the image can be safely removed after that virtual Gfx::Texture CreateTexture(CImage *image, const Gfx::TextureCreateParams ¶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 diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index e544ee31..345a15c7 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -25,6 +25,8 @@ #include "common/key.h" #include "common/logger.h" #include "graphics/core/device.h" +#include "graphics/engine/lightman.h" +#include "graphics/engine/text.h" #include "math/geometry.h" // Initial size of various vectors @@ -44,23 +46,21 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) { m_iMan = iMan; m_app = app; - m_device = NULL; - - m_wasInit = false; + m_device = nullptr; m_iMan = iMan; m_iMan->AddInstance(CLASS_ENGINE, this); m_app = app; - m_lightMan = NULL; - m_text = NULL; - m_particle = NULL; - m_water = NULL; - m_cloud = NULL; - m_lightning = NULL; - m_planet = NULL; - m_sound = NULL; - m_terrain = NULL; + m_lightMan = nullptr; + m_text = nullptr; + m_particle = nullptr; + m_water = nullptr; + m_cloud = nullptr; + m_lightning = nullptr; + m_planet = nullptr; + m_sound = nullptr; + m_terrain = nullptr; m_focus = 0.75f; m_baseTime = 0; @@ -178,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(pos.x) / static_cast(m_size.w), + 1.0f - static_cast(pos.y) / static_cast(m_size.h) ); +} + +Math::IntPoint Gfx::CEngine::InterfaceToWindowCoords(Math::Point pos) +{ + return Math::IntPoint(static_cast(pos.x * m_size.w), + static_cast((1.0f - pos.y) * m_size.h)); +} + +Math::Size Gfx::CEngine::WindowToInterfaceSize(Math::IntSize size) +{ + return Math::Size( static_cast(size.w) / static_cast(m_size.w), + static_cast(size.h) / static_cast(m_size.h) ); +} + +Math::IntSize Gfx::CEngine::InterfaceToWindowSize(Math::Size size) +{ + return Math::IntSize(static_cast(size.w * m_size.w), + static_cast(size.h * m_size.h)); +} + void Gfx::CEngine::DrawMouse() { if (! m_mouseVisible) diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 25c5e5d3..79844c60 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -29,6 +29,7 @@ #include "math/intsize.h" #include "math/matrix.h" #include "math/point.h" +#include "math/size.h" #include "math/vector.h" @@ -514,23 +515,18 @@ public: CEngine(CInstanceManager *iMan, CApplication *app); ~CEngine(); - //! Returns whether the device was initialized - bool GetWasInit(); //! Returns the last error encountered std::string GetError(); - //! Performs the first initialization, before a device was set - bool Create(); - //! Frees all resources before exit - void Destroy(); - //! Sets the device to be used void SetDevice(Gfx::CDevice *device); //! Returns the current device Gfx::CDevice* GetDevice(); - //! Performs initialization after a device was created and set - bool AfterDeviceSetInit(); + //! Performs the initialization; must be called after device was set + bool Create(); + //! Frees all resources before exit + void Destroy(); //! Resets some states and flushes textures after device was changed (e.g. resoulution changed) void ResetAfterDeviceChanged(); @@ -544,6 +540,17 @@ public: bool Render(); + //! Converts window coords to interface coords + Math::Point WindowToInterfaceCoords(Math::IntPoint pos); + //! Converts interface coords to window coords + Math::IntPoint InterfaceToWindowCoords(Math::Point pos); + + //! Converts window size to interface size + Math::Size WindowToInterfaceSize(Math::IntSize size); + //! Converts interface size to window size + Math::IntSize InterfaceToWindowSize(Math::Size size); + + bool WriteProfile(); void SetPause(bool pause); @@ -769,7 +776,8 @@ public: Math::Vector GetLookatPt(); float GetEyeDirH(); float GetEyeDirV(); - Math::Point GetDim(); + Math::IntPoint GetViewportSize(); + Math::IntPoint GetLastViewportSize(); void UpdateMatProj(); void ApplyChange(); @@ -903,8 +911,9 @@ protected: bool m_render; bool m_movieLock; - //! Current size of window + //! Current size of viewport Math::IntSize m_size; + //! Previous size of viewport Math::IntSize m_lastSize; std::vector m_objectTree; diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 2a9543c6..eea9fdb8 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -19,5 +19,480 @@ #include "graphics/engine/text.h" +#include "app/app.h" +#include "common/image.h" +#include "common/iman.h" +#include "common/logger.h" +#include "common/stringutils.h" +#include "math/func.h" -// TODO implementation +#include +#include + + +namespace Gfx +{ + +/** + \struct CachedFont + \brief Base TTF font with UTF-8 char cache */ +struct CachedFont +{ + TTF_Font* font; + std::map 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 &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 &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 &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 &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 &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 &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(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(static_cast(font)); + return nullptr; + } + + MultisizeFont* mf = (*it).second; + + auto jt = mf->fonts.find(pointSize); + if (jt != mf->fonts.end()) + { + m_lastCachedFont = (*jt).second; + m_lastFontType = font; + m_lastFontSize = pointSize; + return m_lastCachedFont; + } + + std::string path = CApplication::GetInstance().GetDataFilePath(m_fontPath, mf->fileName); + + m_lastCachedFont = new CachedFont(); + m_lastCachedFont->font = TTF_OpenFont(path.c_str(), pointSize); + if (m_lastCachedFont->font == nullptr) + m_error = std::string("TTF_OpenFont error ") + std::string(TTF_GetError()); + + mf->fonts[pointSize] = m_lastCachedFont; + + return m_lastCachedFont; +} + +Gfx::CharTexture Gfx::CText::CreateCharTexture(const char* str, Gfx::CachedFont* font) +{ + CharTexture texture; + + SDL_Surface* textSurface = nullptr; + SDL_Color white = {255, 255, 255, 0}; + textSurface = TTF_RenderUTF8_Blended(font->font, str, white); + + if (textSurface == nullptr) + { + m_error = "TTF_Render error"; + return texture; + } + + int w = Math::NextPowerOfTwo(textSurface->w); + int h = Math::NextPowerOfTwo(textSurface->h); + + textSurface->flags = textSurface->flags & (~SDL_SRCALPHA); + SDL_Surface* textureSurface = SDL_CreateRGBSurface(0, w, h, 32, 0x00ff0000, 0x0000ff00, + 0x000000ff, 0xff000000); + SDL_BlitSurface(textSurface, NULL, textureSurface, NULL); + + ImageData data; + data.surface = textureSurface; + + Gfx::TextureCreateParams createParams; + createParams.format = Gfx::TEX_IMG_RGBA; + createParams.minFilter = Gfx::TEX_MIN_FILTER_NEAREST; + createParams.magFilter = Gfx::TEX_MAG_FILTER_NEAREST; + createParams.mipmap = false; + + Gfx::Texture tex = m_device->CreateTexture(&data, createParams); + + data.surface = nullptr; + + SDL_FreeSurface(textSurface); + SDL_FreeSurface(textureSurface); + + if (! tex.valid) + { + m_error = "Texture create error"; + return texture; + } + + texture.id = tex.id; + texture.texSize = m_engine->WindowToInterfaceSize(Math::IntSize(textureSurface->w, textureSurface->h)); + texture.charSize = m_engine->WindowToInterfaceSize(Math::IntSize(textSurface->w, textSurface->h)); + + return texture; +} diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h index c2de220f..19d98828 100644 --- a/src/graphics/engine/text.h +++ b/src/graphics/engine/text.h @@ -19,95 +19,268 @@ #pragma once -#include "graphics/engine/engine.h" -#include "graphics/core/device.h" #include "math/point.h" +#include "math/size.h" +#include +#include 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 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 &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 &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 &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 &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 &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 &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 m_fonts; + + Gfx::FontType m_lastFontType; + int m_lastFontSize; + Gfx::CachedFont* m_lastCachedFont; }; }; // namespace Gfx diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index 3a255f4b..cef372f9 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -64,7 +64,6 @@ void Gfx::GLDeviceConfig::LoadDefault() Gfx::CGLDevice::CGLDevice(const Gfx::GLDeviceConfig &config) { m_config = config; - m_wasInit = false; m_lighting = false; m_texturing = false; } @@ -74,11 +73,6 @@ Gfx::CGLDevice::~CGLDevice() { } -bool Gfx::CGLDevice::GetWasInit() -{ - return m_wasInit; -} - std::string Gfx::CGLDevice::GetError() { return m_error; @@ -110,8 +104,6 @@ bool Gfx::CGLDevice::Create() /* NOTE: when not using GLEW, extension testing is not performed, as it is assumed that glext.h is up-to-date and the OpenGL shared library has the required functions present. */ - m_wasInit = true; - // This is mostly done in all modern hardware by default // DirectX doesn't even allow the option to turn off perspective correction anymore // So turn it on permanently @@ -158,8 +150,6 @@ void Gfx::CGLDevice::Destroy() m_currentTextures.clear(); m_texturesEnabled.clear(); m_textureStageParams.clear(); - - m_wasInit = false; } void Gfx::CGLDevice::ConfigChanged(const Gfx::GLDeviceConfig& newConfig) @@ -385,15 +375,20 @@ bool Gfx::CGLDevice::GetLightEnabled(int index) This struct must not be deleted in other way than through DeleteTexture() */ Gfx::Texture Gfx::CGLDevice::CreateTexture(CImage *image, const Gfx::TextureCreateParams ¶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( m_currentTextures.size() )); + + // Enable the given texture stage + glActiveTexture(GL_TEXTURE0 + index); + glEnable(GL_TEXTURE_2D); + + m_currentTextures[index].id = textureId; + + glBindTexture(GL_TEXTURE_2D, textureId); + + // Disable the stage if it is set so + if ( (! m_texturing) || (! m_texturesEnabled[index]) ) + glDisable(GL_TEXTURE_2D); +} + /** Returns the previously assigned texture or invalid texture if the given stage is not enabled. */ Gfx::Texture Gfx::CGLDevice::GetTexture(int index) diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h index 18640004..a41c41ca 100644 --- a/src/graphics/opengl/gldevice.h +++ b/src/graphics/opengl/gldevice.h @@ -73,7 +73,6 @@ public: CGLDevice(const Gfx::GLDeviceConfig &config); virtual ~CGLDevice(); - virtual bool GetWasInit(); virtual std::string GetError(); virtual bool Create(); @@ -100,11 +99,13 @@ public: virtual bool GetLightEnabled(int index); virtual Gfx::Texture CreateTexture(CImage *image, const Gfx::TextureCreateParams ¶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; diff --git a/src/math/const.h b/src/math/const.h index dd7ab0f0..b08a4001 100644 --- a/src/math/const.h +++ b/src/math/const.h @@ -20,6 +20,8 @@ #pragma once +#include + // Math module namespace namespace Math @@ -30,12 +32,12 @@ namespace Math const float TOLERANCE = 1e-6f; //! Very small number (used in testing/returning some values) -const float VERY_SMALL = 1e-6f; +const float VERY_SMALL_NUM = 1e-6f; //! Very big number (used in testing/returning some values) -const float VERY_BIG = 1e6f; +const float VERY_BIG_NUM = 1e6f; //! Huge number -const float HUGE = 1.0e+38f; +const float HUGE_NUM = 1.0e+38f; //! PI const float PI = 3.14159265358979323846f; @@ -45,6 +47,9 @@ const float DEG_TO_RAD = 0.01745329251994329547f; //! Radians to degrees multiplier const float RAD_TO_DEG = 57.29577951308232286465f; +//! Natural logarithm of 2 +const float LOG_2 = log(2.0f); + /* @} */ // end of group }; // namespace Math diff --git a/src/math/func.h b/src/math/func.h index 2127d1a6..e97d9903 100644 --- a/src/math/func.h +++ b/src/math/func.h @@ -127,6 +127,14 @@ inline float Rand() return static_cast(rand()) / static_cast(RAND_MAX); } +//! Returns the next nearest power of two to \a x +inline int NextPowerOfTwo(int x) +{ + double logbase2 = log(static_cast(x)) / Math::LOG_2; + return static_cast(pow(2, ceil(logbase2)) + 0.5); +} + + //! Returns a normalized angle, that is in other words between 0 and 2 * PI inline float NormAngle(float angle) { diff --git a/src/math/geometry.h b/src/math/geometry.h index 61d18681..3a31ad6a 100644 --- a/src/math/geometry.h +++ b/src/math/geometry.h @@ -45,9 +45,9 @@ inline float MidPoint(const Math::Point &a, const Math::Point &b, float px) if (IsEqual(a.x, b.x)) { if (a.y < b.y) - return HUGE; + return Math::HUGE_NUM; else - return -HUGE; + return -Math::HUGE_NUM; } return (b.y-a.y) * (px-a.x) / (b.x-a.x) + a.y; } diff --git a/src/math/intsize.h b/src/math/intsize.h index f4b2431f..d53de85a 100644 --- a/src/math/intsize.h +++ b/src/math/intsize.h @@ -20,6 +20,9 @@ #pragma once +#include "math/intpoint.h" + + // Math module namespace namespace Math { @@ -31,9 +34,9 @@ namespace Math struct IntSize { //! Width - int w; + long w; //! Height - int h; + long h; //! Constructs a zero size: (0,0) inline IntSize() @@ -42,7 +45,7 @@ struct IntSize } //! Constructs a size from given dimensions: (w,h) - inline explicit IntSize(int w, int h) + inline explicit IntSize(long w, long h) { this->w = w; this->h = h; @@ -53,6 +56,12 @@ struct IntSize { w = h = 0; } + + //! Converts Point to Size + inline static Math::IntSize FromIntPoint(Math::IntPoint p) + { + return Math::IntSize(p.x, p.y); + } }; // struct Size diff --git a/src/math/size.h b/src/math/size.h index 781b9a4a..03cffaa5 100644 --- a/src/math/size.h +++ b/src/math/size.h @@ -20,6 +20,9 @@ #pragma once +#include "math/point.h" + + // Math module namespace namespace Math { @@ -58,6 +61,12 @@ struct Size { w = h = 0.0f; } + + //! Converts Point to Size + inline static Math::Size FromPoint(Math::Point p) + { + return Math::Size(p.x, p.y); + } }; // struct Size From f7e78b21e9655604ba6fba1d068a9bf7f00b85a5 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Mon, 6 Aug 2012 20:20:50 +0200 Subject: [PATCH 02/10] Font rendering - implemented rest of CText interface excluding some minor features --- src/common/stringutils.cpp | 10 +- src/graphics/engine/engine.cpp | 37 ++- src/graphics/engine/engine.h | 8 +- src/graphics/engine/text.cpp | 560 +++++++++++++++++++++++++-------- src/graphics/engine/text.h | 67 ++-- src/math/intpoint.h | 6 +- src/math/intsize.h | 6 +- 7 files changed, 523 insertions(+), 171 deletions(-) diff --git a/src/common/stringutils.cpp b/src/common/stringutils.cpp index 585bb46a..12a31790 100644 --- a/src/common/stringutils.cpp +++ b/src/common/stringutils.cpp @@ -135,15 +135,11 @@ int StrUtils::Utf8CharSizeAt(const std::string &str, unsigned int pos) size_t StrUtils::Utf8StringLength(const std::string &str) { size_t result = 0; - for (unsigned int i = 0; i < str.size(); ++i) + unsigned int i = 0; + while (i < str.size()) { - char ch = str[i]; - if ((ch & 0x80) == 0) + i += Utf8CharSizeAt(str, i); ++result; - else if ((ch & 0xC0) == 0xC0) - result += 2; - else - result += 3; } return result; } diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 345a15c7..c5d2a1dd 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -447,6 +447,19 @@ void Gfx::CEngine::SetState(int state, Gfx::Color color) m_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); m_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);*/ } + else if (state & Gfx::ENG_RSTATE_TEXT) + { + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false); + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); + m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); + + m_device->SetTextureEnabled(0, true); + m_device->SetTextureStageParams(0, Gfx::TextureStageParams()); + + m_device->SetBlendFunc(Gfx::BLEND_SRC_ALPHA, Gfx::BLEND_INV_SRC_ALPHA); + } else // normal ? { m_device->SetRenderState(Gfx::RENDER_STATE_FOG, true); @@ -607,11 +620,33 @@ bool Gfx::CEngine::DrawInterface() DrawMouse(); - m_text->DrawString("abcdefghijklmnopqrstuvwxyz ąęśćółńż", Gfx::FONT_COLOBOT, 15.0f, Math::Point(0.25f, 0.2f), 1.0f, 0); + std::vector format; + for (int i = 0; i < 10; ++i) + format.push_back(Gfx::FONT_COLOBOT_BOLD | Gfx::FONT_HIGHLIGHT_CONST); + for (int i = 0; i < 10; ++i) + format.push_back(Gfx::FONT_COLOBOT_ITALIC | Gfx::FONT_HIGHLIGHT_KEY); + for (int i = 0; i < 10; ++i) + format.push_back(Gfx::FONT_COURIER | Gfx::FONT_HIGHLIGHT_LINK); + for (int i = 0; i < 5; ++i) + format.push_back(Gfx::FONT_COURIER_BOLD | Gfx::FONT_HIGHLIGHT_REM); + + m_text->DrawText("abcdefghijklmnopqrstuvwxyz ąęśćółńż", Gfx::FONT_COLOBOT, 15.0f, Math::Point(0.25f, 0.2f), 1.0f, Gfx::TEXT_ALIGN_LEFT, 0); + float h = m_text->GetHeight(Gfx::FONT_COLOBOT, 15.0f); + m_text->DrawText("abcdefghijklmnopqrstuvwxyz ąęśćółńż", format, 13.0f, Math::Point(0.25f, 0.2f - h), 1.0f, Gfx::TEXT_ALIGN_LEFT, 0); return true; } +Math::IntSize Gfx::CEngine::GetWindowSize() +{ + return m_size; +} + +Math::IntSize Gfx::CEngine::GetLastWindowSize() +{ + return m_lastSize; +} + /** Conversion of the position of the mouse from window coords to interface coords: - x: 0=left, 1=right - y: 0=down, 1=up */ diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 79844c60..3f7f4f28 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -408,7 +408,9 @@ enum EngineRenderState //! The transparent color (black = no) ENG_RSTATE_TCOLOR_BLACK = (1<<16), //! The transparent color (white = no) - ENG_RSTATE_TCOLOR_WHITE = (1<<17) + ENG_RSTATE_TCOLOR_WHITE = (1<<17), + //! Mode for rendering text + ENG_RSTATE_TEXT = (1<<18) }; @@ -776,8 +778,8 @@ public: Math::Vector GetLookatPt(); float GetEyeDirH(); float GetEyeDirV(); - Math::IntPoint GetViewportSize(); - Math::IntPoint GetLastViewportSize(); + Math::IntSize GetWindowSize(); + Math::IntSize GetLastWindowSize(); void UpdateMatProj(); void ApplyChange(); diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index eea9fdb8..77515ad1 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -150,118 +150,254 @@ void Gfx::CText::FlushCache() } void Gfx::CText::DrawText(const std::string &text, const std::vector &format, - Math::Point pos, float width, Gfx::JustifyType justify, float size, - float stretch, int eol) + float size, Math::Point pos, float width, Gfx::TextAlign align, + int eol) { - // TODO + float sw = 0.0f; + + if (align == Gfx::TEXT_ALIGN_CENTER) + { + sw = GetStringWidth(text, format, size); + if (sw > width) sw = width; + pos.x -= sw / 2.0f; + } + else if (align == Gfx::TEXT_ALIGN_RIGHT) + { + sw = GetStringWidth(text, format, size); + if (sw > width) sw = width; + pos.x -= sw; + } + + DrawString(text, format, size, pos, width, eol); } 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) + float size, Math::Point pos, float width, Gfx::TextAlign align, + int eol) { - // TODO + float sw = 0.0f; + + if (align == Gfx::TEXT_ALIGN_CENTER) + { + sw = GetStringWidth(text, font, size); + if (sw > width) sw = width; + pos.x -= sw / 2.0f; + } + else if (align == Gfx::TEXT_ALIGN_RIGHT) + { + sw = GetStringWidth(text, font, size); + if (sw > width) sw = width; + pos.x -= sw; + } + + DrawString(text, font, size, pos, width, eol); } void Gfx::CText::SizeText(const std::string &text, const std::vector &format, - Math::Point pos, Gfx::JustifyType justify, float size, + float size, Math::Point pos, Gfx::TextAlign align, Math::Point &start, Math::Point &end) { - // TODO + start = end = pos; + + float sw = GetStringWidth(text, format, size); + end.x += sw; + if (align == Gfx::TEXT_ALIGN_CENTER) + { + start.x -= sw/2.0f; + end.x -= sw/2.0f; + } + else if (align == Gfx::TEXT_ALIGN_RIGHT) + { + start.x -= sw; + end.x -= sw; + } + + start.y -= GetDescent(Gfx::FONT_COLOBOT, size); + end.y += GetAscent(Gfx::FONT_COLOBOT, size); } void Gfx::CText::SizeText(const std::string &text, Gfx::FontType font, - Math::Point pos, Gfx::JustifyType justify, float size, + float size, Math::Point pos, Gfx::TextAlign align, Math::Point &start, Math::Point &end) { - // TODO + start = end = pos; + + float sw = GetStringWidth(text, font, size); + end.x += sw; + if (align == Gfx::TEXT_ALIGN_CENTER) + { + start.x -= sw/2.0f; + end.x -= sw/2.0f; + } + else if (align == Gfx::TEXT_ALIGN_RIGHT) + { + start.x -= sw; + end.x -= sw; + } + + start.y -= GetDescent(font, size); + end.y += GetAscent(font, size); } float Gfx::CText::GetAscent(Gfx::FontType font, float size) { - // TODO - return 0.0f; + assert(font != Gfx::FONT_BUTTON); + + Gfx::CachedFont* cf = GetOrOpenFont(font, size); + assert(cf != nullptr); + Math::IntSize wndSize; + wndSize.h = TTF_FontAscent(cf->font); + Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize); + return ifSize.h; } float Gfx::CText::GetDescent(Gfx::FontType font, float size) { - // TODO - return 0.0f; + assert(font != Gfx::FONT_BUTTON); + + Gfx::CachedFont* cf = GetOrOpenFont(font, size); + assert(cf != nullptr); + Math::IntSize wndSize; + wndSize.h = TTF_FontDescent(cf->font); + Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize); + return ifSize.h; } float Gfx::CText::GetHeight(Gfx::FontType font, float size) { - // TODO - return 0.0f; + assert(font != Gfx::FONT_BUTTON); + + Gfx::CachedFont* cf = GetOrOpenFont(font, size); + assert(cf != nullptr); + Math::IntSize wndSize; + wndSize.h = TTF_FontHeight(cf->font); + Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize); + return ifSize.h; } float Gfx::CText::GetStringWidth(const std::string &text, const std::vector &format, float size) { - // TODO - return 0.0f; + assert(StrUtils::Utf8StringLength(text) == format.size()); + + float width = 0.0f; + unsigned int index = 0; + unsigned int fmtIndex = 0; + while (index < text.length()) + { + Gfx::FontType font = static_cast(format[fmtIndex] & Gfx::FONT_MASK_FONT); + + Gfx::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]; + + width += GetCharWidth(ch, font, size, width); + + index += len; + fmtIndex++; + } + + return width; } float Gfx::CText::GetStringWidth(const std::string &text, Gfx::FontType font, float size) { - // TODO - return 0.0f; + assert(font != Gfx::FONT_BUTTON); + + // TODO: special chars? + + Gfx::CachedFont* cf = GetOrOpenFont(font, size); + assert(cf != nullptr); + Math::IntSize wndSize; + TTF_SizeUTF8(cf->font, text.c_str(), &wndSize.w, &wndSize.h); + Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize); + return ifSize.w; } -float Gfx::CText::GetCharWidth(int character, Gfx::FontType font, float size, float offset) +float Gfx::CText::GetCharWidth(Gfx::UTF8Char ch, Gfx::FontType font, float size, float offset) { - // TODO - return 0.0f; + // TODO: if (font == Gfx::FONT_BUTTON) + if (font == Gfx::FONT_BUTTON) return 0.0f; + + // TODO: special chars? + // TODO: tab sizing + + Gfx::CachedFont* cf = GetOrOpenFont(font, size); + assert(cf != nullptr); + + Gfx::CharTexture tex; + auto it = cf->cache.find(ch); + if (it != cf->cache.end()) + tex = (*it).second; + else + tex = CreateCharTexture(ch, cf); + + return tex.charSize.w; } int Gfx::CText::Justify(const std::string &text, const std::vector &format, float size, float width) { - // TODO - return 0; + assert(StrUtils::Utf8StringLength(text) == format.size()); + + float pos = 0.0f; + int cut = 0; + unsigned int index = 0; + unsigned int fmtIndex = 0; + while (index < text.length()) + { + Gfx::FontType font = static_cast(format[fmtIndex] & Gfx::FONT_MASK_FONT); + + Gfx::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]; + + if (font != Gfx::FONT_BUTTON) + { + if (ch.c1 == '\n') + return index+1; + if (ch.c1 == ' ') + cut = index+1; + } + + pos += GetCharWidth(ch, font, size, pos); + if (pos > width) + { + if (cut == 0) return index; + else return cut; + } + + index += len; + fmtIndex++; + } + + return index; } 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 &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 &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); + assert(font != Gfx::FONT_BUTTON); + float pos = 0.0f; + int cut = 0; unsigned int index = 0; - Math::Point screenPos = pos; while (index < text.length()) { - UTF8Char ch; + Gfx::UTF8Char ch; int len = StrUtils::Utf8CharSizeAt(text, index); if (len >= 1) @@ -273,56 +409,231 @@ void Gfx::CText::DrawString(const std::string &text, Gfx::FontType font, index += len; - DrawChar(ch, font, size, screenPos); + if (ch.c1 == '\n') + return index+1; + + if (ch.c1 == ' ' ) + cut = index+1; + + pos += GetCharWidth(ch, font, size, pos); + if (pos > width) + { + if (cut == 0) return index; + else return cut; + } + } + + return index; +} + +int Gfx::CText::Detect(const std::string &text, const std::vector &format, + float size, float offset) +{ + assert(StrUtils::Utf8StringLength(text) == format.size()); + + float pos = 0.0f; + unsigned int index = 0; + unsigned int fmtIndex = 0; + while (index < text.length()) + { + Gfx::FontType font = static_cast(format[fmtIndex] & Gfx::FONT_MASK_FONT); + + // TODO: if (font == Gfx::FONT_BUTTON) + if (font == Gfx::FONT_BUTTON) continue; + + Gfx::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]; + + if (ch.c1 == '\n') + return index; + + float width = GetCharWidth(ch, font, size, pos); + if (offset <= pos + width/2.0f) + return index; + + pos += width; + index += len; + fmtIndex++; + } + + return index; +} + +int Gfx::CText::Detect(const std::string &text, Gfx::FontType font, float size, float offset) +{ + assert(font != Gfx::FONT_BUTTON); + + float pos = 0.0f; + unsigned int index = 0; + while (index < text.length()) + { + Gfx::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; + + if (ch.c1 == '\n') + return index; + + float width = GetCharWidth(ch, font, size, pos); + if (offset <= pos + width/2.0f) + return index; + + pos += width; + } + + return index; +} + +void Gfx::CText::DrawString(const std::string &text, const std::vector &format, + float size, Math::Point pos, float width, int eol) +{ + assert(StrUtils::Utf8StringLength(text) == format.size()); + + m_engine->SetState(Gfx::ENG_RSTATE_TEXT); + + Gfx::FontType font = Gfx::FONT_COLOBOT; + float start = pos.x; + + unsigned int index = 0; + unsigned int fmtIndex = 0; + while (index < text.length()) + { + font = static_cast(format[fmtIndex] & Gfx::FONT_MASK_FONT); + + // TODO: if (font == Gfx::FONT_BUTTON) + if (font == Gfx::FONT_BUTTON) continue; + + Gfx::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]; + + float offset = pos.x - start; + float cw = GetCharWidth(ch, font, size, offset); + if (offset + cw > width) // exceeds the maximum width? + { + // TODO: special end-of-line char + break; + } + + Gfx::FontHighlight hl = static_cast(format[fmtIndex] & Gfx::FONT_MASK_HIGHLIGHT); + if (hl != Gfx::FONT_HIGHLIGHT_NONE) + { + Math::Size charSize; + charSize.w = GetCharWidth(ch, font, size, offset); + charSize.h = GetHeight(font, size); + DrawHighlight(hl, pos, charSize); + } + + DrawChar(ch, font, size, pos); + + index += len; + fmtIndex++; + } + + // TODO: eol +} + +void Gfx::CText::DrawString(const std::string &text, Gfx::FontType font, + float size, Math::Point pos, float width, int eol) +{ + assert(font != Gfx::FONT_BUTTON); + + m_engine->SetState(Gfx::ENG_RSTATE_TEXT); + + unsigned int index = 0; + while (index < text.length()) + { + Gfx::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, pos); } } -void Gfx::CText::DrawColor(int color, float size, Math::Point pos, float width) +void Gfx::CText::DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Size size) { - // TODO !!! - /* - float h, u1, u2, v1, v2, dp; - int icon; + // Gradient colors + Gfx::Color grad[4]; - int icon = -1; - switch (color) + // TODO: switch to alpha factors + + switch (hl) { - case Gfx::FONT_COLOR_LINK: - icon = 9; + case Gfx::FONT_HIGHLIGHT_LINK: + grad[0] = grad[1] = grad[2] = grad[3] = Gfx::Color(0.0f, 0.0f, 1.0f, 0.5f); 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; + case Gfx::FONT_HIGHLIGHT_TOKEN: + grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f); + grad[2] = grad[3] = Gfx::Color(248.0f / 256.0f, 220.0f / 256.0f, 188.0f / 256.0f, 0.5f); + break; - if ( color == COLOR_LINK ) - { - m_engine->SetState(D3DSTATENORMAL); + case Gfx::FONT_HIGHLIGHT_TYPE: + grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f); + grad[2] = grad[3] = Gfx::Color(169.0f / 256.0f, 234.0f / 256.0f, 169.0f / 256.0f, 0.5f); + break; + + case Gfx::FONT_HIGHLIGHT_CONST: + grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f); + grad[2] = grad[3] = Gfx::Color(248.0f / 256.0f, 176.0f / 256.0f, 169.0f / 256.0f, 0.5f); + break; + + case Gfx::FONT_HIGHLIGHT_REM: + grad[0] = grad[1] = Gfx::Color(248.0f / 256.0f, 248.0f / 256.0f, 248.0f / 256.0f, 0.5f); + grad[2] = grad[3] = Gfx::Color(248.0f / 256.0f, 169.0f / 256.0f, 248.0f / 256.0f, 0.5f); + break; + + case Gfx::FONT_HIGHLIGHT_KEY: + grad[0] = grad[1] = grad[2] = grad[3] = + Gfx::Color(192.0f / 256.0f, 192.0f / 256.0f, 192.0f / 256.0f, 0.5f); + break; + + default: + return; } - 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::IntSize vsize = m_engine->GetWindowSize(); + float h = 0.0f; + if (vsize.h <= 768.0f) // 1024x768 or less? + h = 1.01f / vsize.h; // 1 pixel + else // more than 1024x768? + h = 2.0f / vsize.h; // 2 pixels Math::Point p1, p2; p1.x = pos.x; - p2.x = pos.x + width; + p2.x = pos.x + size.w; - if (color == Gfx::FONT_COLOR_LINK) + if (hl == Gfx::FONT_HIGHLIGHT_LINK) { p1.y = pos.y; p2.y = pos.y + h; // just emphasized @@ -330,45 +641,38 @@ void Gfx::CText::DrawColor(int color, float size, Math::Point pos, float width) else { p1.y = pos.y; - p2.y = pos.y + (16.0f/256.0f)*(size/20.0f); + p2.y = pos.y + size.h; } - u1 = (16.0f/256.0f)*(icon%16); - v1 = (240.0f/256.0f); - u2 = (16.0f/256.0f)+u1; - v2 = (16.0f/256.0f)+v1; + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false); - 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::VertexCol 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)), + Gfx::VertexCol(Math::Vector(p1.x, p1.y, 0.0f), grad[3]), + Gfx::VertexCol(Math::Vector(p2.x, p1.y, 0.0f), grad[2]), + Gfx::VertexCol(Math::Vector(p1.x, p2.y, 0.0f), grad[0]), + Gfx::VertexCol(Math::Vector(p2.x, p2.y, 0.0f), grad[1]) }; 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);*/ + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); } -void Gfx::CText::DrawChar(UTF8Char character, Gfx::FontType font, float size, Math::Point &pos) +void Gfx::CText::DrawChar(Gfx::UTF8Char ch, Gfx::FontType font, float size, Math::Point &pos) { + // TODO: if (font == Gfx::FONT_BUTTON) + if (font == Gfx::FONT_BUTTON) return; + + // TODO: special chars? + CachedFont* cf = GetOrOpenFont(font, size); if (cf == nullptr) return; - auto it = cf->cache.find(character); + auto it = cf->cache.find(ch); CharTexture tex; if (it != cf->cache.end()) { @@ -376,31 +680,32 @@ void Gfx::CText::DrawChar(UTF8Char character, Gfx::FontType font, float size, Ma } else { - char str[] = { character.c1, character.c2, character.c3, '\0' }; - tex = CreateCharTexture(str, cf); + tex = CreateCharTexture(ch, cf); if (tex.id == 0) // invalid return; - cf->cache[character] = tex; + cf->cache[ch] = tex; } + m_device->SetRenderState(Gfx::RENDER_STATE_CULLING, false); + + Math::Point p1(pos.x, pos.y + tex.charSize.h - tex.texSize.h); + Math::Point p2(pos.x + tex.texSize.w, pos.y + tex.charSize.h); + 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)) + Gfx::Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(0.0f, 1.0f)), + Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(1.0f, 1.0f)), + Gfx::Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(0.0f, 0.0f)), + Gfx::Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(1.0f, 0.0f)) }; m_device->SetTexture(0, tex.id); m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4); + m_engine->AddStatisticTriangle(2); pos.x += tex.charSize.w; } @@ -446,12 +751,13 @@ Gfx::CachedFont* Gfx::CText::GetOrOpenFont(Gfx::FontType font, float size) return m_lastCachedFont; } -Gfx::CharTexture Gfx::CText::CreateCharTexture(const char* str, Gfx::CachedFont* font) +Gfx::CharTexture Gfx::CText::CreateCharTexture(Gfx::UTF8Char ch, Gfx::CachedFont* font) { CharTexture texture; SDL_Surface* textSurface = nullptr; SDL_Color white = {255, 255, 255, 0}; + char str[] = { ch.c1, ch.c2, ch.c3, '\0' }; textSurface = TTF_RenderUTF8_Blended(font->font, str, white); if (textSurface == nullptr) diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h index 19d98828..6209c39b 100644 --- a/src/graphics/engine/text.h +++ b/src/graphics/engine/text.h @@ -38,9 +38,9 @@ const float FONT_SIZE_SMALL = 10.0f; const float FONT_SIZE_BIG = 15.0f; /** - \enum TextAlignType + \enum TextAlign \brief Type of text alignment */ -enum JustifyType +enum TextAlign { TEXT_ALIGN_RIGHT, TEXT_ALIGN_LEFT, @@ -86,6 +86,8 @@ enum FontType \enum FontTitle \brief Size of font title + Used internally by CEdit + Bitmask in 2 bits left shifted 4 (mask 0x030) */ enum FontTitle { @@ -95,19 +97,20 @@ enum FontTitle }; /** - \enum FontColor - \brief Font color type (?) + \enum FontHighlight + \brief Type of color highlight for text Bitmask in 3 bits left shifted 6 (mask 0x1c0) */ -enum FontColor +enum FontHighlight { - 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, + FONT_HIGHLIGHT_NONE = 0x00 << 6, + FONT_HIGHLIGHT_LINK = 0x01 << 6, + FONT_HIGHLIGHT_TOKEN = 0x02 << 6, + FONT_HIGHLIGHT_TYPE = 0x03 << 6, + FONT_HIGHLIGHT_CONST = 0x04 << 6, + FONT_HIGHLIGHT_REM = 0x05 << 6, + FONT_HIGHLIGHT_KEY = 0x06 << 6, + FONT_HIGHLIGHT_TABLE = 0x07 << 6, }; /** @@ -119,9 +122,9 @@ enum FontMask FONT_MASK_FONT = 0x00f, //! Mask for FontTitle FONT_MASK_TITLE = 0x030, - //! Mask for FontColor - FONT_MASK_COLOR = 0x1c0, - //! Mask for image bit + //! Mask for FontHighlight + FONT_MASK_HIGHLIGHT = 0x1c0, + //! Mask for image bit (TODO: not used?) FONT_MASK_IMAGE = 0x200 }; @@ -190,7 +193,17 @@ struct MultisizeFont \class CText \brief Text rendering engine - ... */ + CText is responsible for drawing text in 2D interface. Font rendering is done using + textures generated by SDL_ttf from TTF font files. + + All functions rendering text are divided into two types: + - single font - function takes a single Gfx::FontType argument that (along with size) + determines the font to be used for all characters, + - multi-font - function takes the text as one argument and a std::vector of FontMetaChar + with per-character formatting information (font, highlights and some other info used by CEdit) + + All font rendering is done in UTF-8. +*/ class CText { public: @@ -213,20 +226,20 @@ public: //! Draws text (multi-format) void DrawText(const std::string &text, const std::vector &format, - Math::Point pos, float width, Gfx::JustifyType justify, float size, - float stretch, int eol); + float size, Math::Point pos, float width, Gfx::TextAlign align, + 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); + float size, Math::Point pos, float width, Gfx::TextAlign align, + int eol); //! Calculates dimensions for text (multi-format) void SizeText(const std::string &text, const std::vector &format, - Math::Point pos, Gfx::JustifyType justify, float size, + float size, Math::Point pos, Gfx::TextAlign align, 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, + float size, Math::Point pos, Gfx::TextAlign align, Math::Point &start, Math::Point &end); //! Returns the ascent font metric @@ -242,7 +255,7 @@ public: //! 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); + float GetCharWidth(Gfx::UTF8Char ch, Gfx::FontType font, float size, float offset); //! Justifies a line of text (multi-format) int Justify(const std::string &text, const std::vector &format, @@ -256,16 +269,16 @@ public: //! 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! +protected: Gfx::CachedFont* GetOrOpenFont(Gfx::FontType type, float size); - Gfx::CharTexture CreateCharTexture(const char* utf8Char, Gfx::CachedFont* font); + Gfx::CharTexture CreateCharTexture(Gfx::UTF8Char ch, Gfx::CachedFont* font); void DrawString(const std::string &text, const std::vector &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); + void DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Size size); + void DrawChar(Gfx::UTF8Char ch, Gfx::FontType font, float size, Math::Point &pos); protected: CInstanceManager* m_iMan; diff --git a/src/math/intpoint.h b/src/math/intpoint.h index a760bc2a..476e67bc 100644 --- a/src/math/intpoint.h +++ b/src/math/intpoint.h @@ -32,11 +32,11 @@ namespace Math { struct IntPoint { //! X coord - long x; + int x; //! Y coord - long y; + int y; - IntPoint(long aX = 0, long aY = 0) : x(aX), y(aY) {} + IntPoint(int aX = 0, int aY = 0) : x(aX), y(aY) {} }; /* @} */ // end of group diff --git a/src/math/intsize.h b/src/math/intsize.h index d53de85a..c88f09ba 100644 --- a/src/math/intsize.h +++ b/src/math/intsize.h @@ -34,9 +34,9 @@ namespace Math struct IntSize { //! Width - long w; + int w; //! Height - long h; + int h; //! Constructs a zero size: (0,0) inline IntSize() @@ -45,7 +45,7 @@ struct IntSize } //! Constructs a size from given dimensions: (w,h) - inline explicit IntSize(long w, long h) + inline explicit IntSize(int w, int h) { this->w = w; this->h = h; From 878eec8eea26deedf3b1346df71bff391424c325 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Wed, 8 Aug 2012 21:32:44 +0200 Subject: [PATCH 03/10] CTerrain implementation Added rewritten CTerrain implementation Compiles OK, but functions are missing from other classes Also needs testing --- src/graphics/engine/cloud.h | 4 +- src/graphics/engine/engine.cpp | 5 + src/graphics/engine/engine.h | 3 +- src/graphics/engine/particle.h | 6 +- src/graphics/engine/terrain.cpp | 1802 ++++++++++++++++++++++++++++++- src/graphics/engine/terrain.h | 252 +++-- src/graphics/engine/water.h | 14 +- 7 files changed, 1985 insertions(+), 101 deletions(-) diff --git a/src/graphics/engine/cloud.h b/src/graphics/engine/cloud.h index d2d29d74..562f651a 100644 --- a/src/graphics/engine/cloud.h +++ b/src/graphics/engine/cloud.h @@ -56,10 +56,10 @@ public: void Draw(); bool SetLevel(float level); - float RetLevel(); + float GetLevel(); void SetEnable(bool bEnable); - bool RetEnable(); + bool GetEnable(); protected: bool EventFrame(const Event &event); diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index c5d2a1dd..4bf80d27 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -674,6 +674,11 @@ Math::IntSize Gfx::CEngine::InterfaceToWindowSize(Math::Size size) static_cast(size.h * m_size.h)); } +std::string Gfx::CEngine::GetTextureDir() +{ + return m_texPath; +} + void Gfx::CEngine::DrawMouse() { if (! m_mouseVisible) diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 3f7f4f28..cd89a1cf 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -552,6 +552,7 @@ public: //! Converts interface size to window size Math::IntSize InterfaceToWindowSize(Math::Size size); + std::string GetTextureDir(); bool WriteProfile(); @@ -606,7 +607,7 @@ public: bool AddSurface(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material &mat, int state, std::string texName1, std::string texName2, float min, float max, bool globalUpdate); - bool AddQuick(int objRank, Gfx::EngineObjLevel5* buffer, + bool AddQuick(int objRank, const Gfx::EngineObjLevel5& buffer, std::string texName1, std::string texName2, float min, float max, bool globalUpdate); Gfx::EngineObjLevel5* SearchTriangle(int objRank, const Gfx::Material &mat, diff --git a/src/graphics/engine/particle.h b/src/graphics/engine/particle.h index bd9741f1..94aacfc7 100644 --- a/src/graphics/engine/particle.h +++ b/src/graphics/engine/particle.h @@ -260,7 +260,7 @@ public: CParticle(CInstanceManager* iMan, CEngine* engine); ~CParticle(); - void SetGLDevice(CDevice device); + void SetDevice(CDevice* device); void FlushParticle(); void FlushParticle(int sheet); @@ -283,7 +283,7 @@ public: void SetPhase(int channel, ParticlePhase phase, float duration); bool GetPosition(int channel, Math::Vector &pos); - Gfx::Color RetFogColor(Math::Vector pos); + Gfx::Color GetFogColor(Math::Vector pos); void SetFrameUpdate(int sheet, bool bUpdate); void FrameParticle(float rTime); @@ -311,7 +311,7 @@ protected: protected: CInstanceManager* m_iMan; CEngine* m_engine; - CDevice* m_pDevice; + CDevice* m_device; CRobotMain* m_main; CTerrain* m_terrain; CWater* m_water; diff --git a/src/graphics/engine/terrain.cpp b/src/graphics/engine/terrain.cpp index c489321a..6d4fcd39 100644 --- a/src/graphics/engine/terrain.cpp +++ b/src/graphics/engine/terrain.cpp @@ -19,5 +19,1805 @@ #include "graphics/engine/terrain.h" +#include "app/app.h" +#include "common/iman.h" +#include "common/image.h" +#include "common/logger.h" +#include "graphics/engine/engine.h" +#include "graphics/engine/water.h" +#include "math/geometry.h" -// TODO implementation +#include + +#include + +const int LEVEL_MAT_PREALLOCATE_COUNT = 101; +const int FLYING_LIMIT_PREALLOCATE_COUNT = 10; +const int BUILDING_LEVEL_PREALLOCATE_COUNT = 101; + + +Gfx::CTerrain::CTerrain(CInstanceManager* iMan) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_TERRAIN, this); + + m_engine = static_cast( m_iMan->SearchInstance(CLASS_ENGINE) ); + m_water = static_cast( m_iMan->SearchInstance(CLASS_WATER) ); + + m_mosaic = 20; + m_brick = 1 << 4; + m_size = 10.0f; + m_vision = 200.0f; + m_scaleMapping = 0.01f; + m_scaleRelief = 1.0f; + m_subdivMapping = 1; + m_depth = 2; + m_levelMatMax = 0; + m_multiText = true; + m_levelText = false; + m_wind = Math::Vector(0.0f, 0.0f, 0.0f); + m_defHardness = 0.5f; + + m_levelMat.reserve(LEVEL_MAT_PREALLOCATE_COUNT); + m_flyingLimits.reserve(FLYING_LIMIT_PREALLOCATE_COUNT); + m_buildingLevels.reserve(BUILDING_LEVEL_PREALLOCATE_COUNT); +} + +Gfx::CTerrain::~CTerrain() +{ +} + +/** + The terrain is composed of mosaics, themselves composed of bricks. + Each brick is composed of two triangles. + mosaic: number of mosaics along the axes X and Z + brick: number of bricks (power of 2) + size: size of a brick along the axes X and Z + vision: vision before a change of resolution + scaleMapping: scale textures for mapping + +\verbatim + ^ z + | <---> brick*size + +---+---+---+---+ + | | | |_|_| mosaic = 4 + | | | | | | brick = 2 (brickP2=1) + +---+---+---+---+ + |\ \| | | | + |\ \| | | | + +---+---o---+---+---> x + | | | | | + | | | | | + +---+---+---+---+ + | | | | | The land is viewed from above here. + | | | | | + +---+---+---+---+ + <---------------> mosaic*brick*size +\endverbatim */ +bool Gfx::CTerrain::Generate(int mosaic, int brickPow2, float size, float vision, + int depth, float hardness) +{ + m_mosaic = mosaic; + m_brick = 1 << brickPow2; + m_size = size; + m_vision = vision; + m_depth = depth; + m_defHardness = hardness; + + m_engine->SetTerrainVision(vision); + + m_multiText = true; + m_levelText = false; + m_scaleMapping = 1.0f / (m_brick*m_size); + m_subdivMapping = 1; + + int dim = 0; + + dim = (m_mosaic*m_brick+1)*(m_mosaic*m_brick+1); + std::vector(dim).swap(m_relief); + + dim = m_mosaic*m_subdivMapping*m_mosaic*m_subdivMapping; + std::vector(dim).swap(m_texture); + + dim = m_mosaic*m_mosaic; + std::vector(dim).swap(m_objRank); + + return true; +} + + +int Gfx::CTerrain::GetMosaic() +{ + return m_mosaic; +} + +int Gfx::CTerrain::GetBrick() +{ + return m_brick; +} + +float Gfx::CTerrain::GetSize() +{ + return m_size; +} + +float Gfx::CTerrain::GetScaleRelief() +{ + return m_scaleRelief; +} + +bool Gfx::CTerrain::InitTextures(const std::string& baseName, int* table, int dx, int dy) +{ + m_levelText = false; + m_texBaseName = baseName; + size_t pos = baseName.find('.'); + if (pos == baseName.npos) + { + m_texBaseExt = ".png"; + } + else + { + m_texBaseName = m_texBaseName.substr(0, pos); + m_texBaseExt = m_texBaseName.substr(pos); + } + + for (int y = 0; y < m_mosaic*m_subdivMapping; y++) + { + for (int x = 0; x < m_mosaic*m_subdivMapping; x++) + { + m_texture[x+y*m_mosaic] = table[(x%dx)+(y%dy)*dx]; + } + } + return true; +} + + +void Gfx::CTerrain::LevelFlush() +{ + m_levelMat.clear(); + m_levelMatMax = 0; + m_levelID = 1000; + LevelCloseTable(); +} + +void Gfx::CTerrain::LevelMaterial(int id, std::string& baseName, float u, float v, + int up, int right, int down, int left, + float hardness) +{ + LevelOpenTable(); + + if (id == 0) + id = m_levelID++; // puts an ID internal standard + + Gfx::TerrainMaterial tm; + tm.texName = baseName; + tm.id = id; + tm.u = u; + tm.v = v; + tm.mat[0] = up; + tm.mat[1] = right; + tm.mat[2] = down; + tm.mat[3] = left; + tm.hardness = hardness; + + m_levelMat.push_back(tm); + + if (m_levelMatMax < up+1 ) m_levelMatMax = up+1; + if (m_levelMatMax < right+1) m_levelMatMax = right+1; + if (m_levelMatMax < down+1 ) m_levelMatMax = down+1; + if (m_levelMatMax < left+1 ) m_levelMatMax = left+1; + + m_levelText = true; + m_subdivMapping = 4; +} + + +/** + The size of the image must be dimension dx and dy with dx=dy=(mosaic*brick)+1. + The image must be 24 bits/pixel + + Converts coordinated image (x;y) -> world (x;-;z) : + Wx = 5*Ix-400 + Wz = -(5*Iy-400) + + Converts coordinated world (x;-;z) -> image (x;y) : + Ix = (400+Wx)/5 + Iy = (400-Wz)/5 */ +bool Gfx::CTerrain::ResFromPNG(const std::string& fileName) +{ + CImage img; + if (! img.Load(CApplication::GetInstance().GetDataFilePath(m_engine->GetTextureDir(), fileName))) + return false; + + ImageData *data = img.GetData(); + + int size = (m_mosaic*m_brick)+1; + + m_resources.clear(); + + std::vector(3*size*size).swap(m_resources); + + if ( (data->surface->w != size) || (data->surface->h != size) || + (data->surface->format->BytesPerPixel != 3) ) + return false; + + // Assuming the data format is compatible + memcpy(&m_resources[0], data->surface->pixels, 3*size*size); + + return true; +} + +Gfx::TerrainRes Gfx::CTerrain::GetResource(const Math::Vector &p) +{ + if (m_resources.empty()) + return Gfx::TR_NULL; + + int x = static_cast((p.x + (m_mosaic*m_brick*m_size)/2.0f)/m_size); + int y = static_cast((p.z + (m_mosaic*m_brick*m_size)/2.0f)/m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) + return Gfx::TR_NULL; + + int size = (m_mosaic*m_brick)+1; + + int resR = m_resources[3*x+3*size*(size-y-1)]; + int resG = m_resources[3*x+3*size*(size-y-1)+1]; + int resB = m_resources[3*x+3*size*(size-y-1)+2]; + + if (resR == 255 && resG == 0 && resB == 0) return Gfx::TR_STONE; + if (resR == 255 && resG == 255 && resB == 0) return Gfx::TR_URANIUM; + if (resR == 0 && resG == 255 && resB == 0) return Gfx::TR_POWER; + + // TODO key res values + //if (ress == 24) return Gfx::TR_KEY_A; // ~green? + //if (ress == 25) return Gfx::TR_KEY_B; // ~green? + //if (ress == 26) return Gfx::TR_KEY_C; // ~green? + //if (ress == 27) return Gfx::TR_KEY_D; // ~green? + + return TR_NULL; +} + +void Gfx::CTerrain::FlushRelief() +{ + m_relief.clear(); +} + +/** + The size of the image must be dimension dx and dy with dx=dy=(mosaic*brick)+1. + The image must be 24 bits/pixel, but gray scale: + white = ground (y=0) + black = mountain (y=255*scaleRelief) + + Converts coordinated image(x;y) -> world (x;-;z) : + Wx = 5*Ix-400 + Wz = -(5*Iy-400) + + Converts coordinated world (x;-;z) -> image (x;y) : + Ix = (400+Wx)/5 + Iy = (400-Wz)/5 */ +bool Gfx::CTerrain::ReliefFromPNG(const std::string &fileName, float scaleRelief, + bool adjustBorder) +{ + m_scaleRelief = scaleRelief; + + CImage img; + if (! img.Load(CApplication::GetInstance().GetDataFilePath(m_engine->GetTextureDir(), fileName))) + return false; + + ImageData *data = img.GetData(); + + int size = (m_mosaic*m_brick)+1; + + if ( (data->surface->w != size) || (data->surface->h != size) || + (data->surface->format->BytesPerPixel != 3) ) + return false; + + unsigned char* pixels = static_cast(data->surface->pixels); + + float limit = 0.9f; + for (int y = 0; y < size; y++) + { + for (int x = 0; x < size; x++) + { + float level = (255 - pixels[3*x+3*size*(size-y-1)]) * scaleRelief; + + float dist = Math::Max(fabs(static_cast(x-size/2)), + fabs(static_cast(y-size/2))); + dist = dist/ static_cast(size / 2); + if (dist > limit && adjustBorder) + { + dist = (dist-limit)/(1.0f-limit); // 0..1 + if (dist > 1.0f) dist = 1.0f; + float border = 300.0f+Math::Rand()*20.0f; + level = level+dist*(border-level); + } + + m_relief[x+y*size] = level; + } + } + + return true; +} + +bool Gfx::CTerrain::ReliefAddDot(Math::Vector pos, float scaleRelief) +{ + float dim = (m_mosaic*m_brick*m_size)/2.0f; + int size = (m_mosaic*m_brick)+1; + + pos.x = (pos.x+dim)/m_size; + pos.z = (pos.z+dim)/m_size; + + int x = static_cast(pos.x); + int y = static_cast(pos.z); + + if ( x < 0 || x >= size || + y < 0 || y >= size ) return false; + + if (m_relief[x+y*size] < pos.y*scaleRelief) + m_relief[x+y*size] = pos.y*scaleRelief; + + return true; +} + +void Gfx::CTerrain::LimitPos(Math::Vector &pos) +{ +// TODO: #if _TEEN +// dim = (m_mosaic*m_brick*m_size)/2.0f*0.98f; + + float dim = (m_mosaic*m_brick*m_size)/2.0f*0.92f; + + if (pos.x < -dim) pos.x = -dim; + if (pos.x > dim) pos.x = dim; + if (pos.z < -dim) pos.z = -dim; + if (pos.z > dim) pos.z = dim; +} + +void Gfx::CTerrain::AdjustRelief() +{ + if (m_depth == 1) return; + + int ii = m_mosaic*m_brick+1; + int b = 1 << (m_depth-1); + + for (int y = 0; y < m_mosaic*m_brick; y += b) + { + for (int x = 0; x < m_mosaic*m_brick; x += b) + { + int xx = 0; + int yy = 0; + if ((y+yy)%m_brick == 0) + { + float level1 = m_relief[(x+0)+(y+yy)*ii]; + float level2 = m_relief[(x+b)+(y+yy)*ii]; + for (xx = 1; xx < b; xx++) + { + m_relief[(x+xx)+(y+yy)*ii] = ((level2-level1)/b)*xx+level1; + } + } + + yy = b; + if ((y+yy)%m_brick == 0) + { + float level1 = m_relief[(x+0)+(y+yy)*ii]; + float level2 = m_relief[(x+b)+(y+yy)*ii]; + for (xx = 1; xx < b; xx++) + { + m_relief[(x+xx)+(y+yy)*ii] = ((level2-level1)/b)*xx+level1; + } + } + + xx = 0; + if ((x+xx)%m_brick == 0) + { + float level1 = m_relief[(x+xx)+(y+0)*ii]; + float level2 = m_relief[(x+xx)+(y+b)*ii]; + for (yy = 1; yy < b; yy++) + { + m_relief[(x+xx)+(y+yy)*ii] = ((level2-level1)/b)*yy+level1; + } + } + + xx = b; + if ((x+xx)%m_brick == 0) + { + float level1 = m_relief[(x+xx)+(y+0)*ii]; + float level2 = m_relief[(x+xx)+(y+b)*ii]; + for (yy = 1; yy < b; yy++) + { + m_relief[(x+xx)+(y+yy)*ii] = ((level2-level1)/b)*yy+level1; + } + } + } + } +} + +Math::Vector Gfx::CTerrain::GetVector(int x, int y) +{ + Math::Vector p; + p.x = x*m_size - (m_mosaic*m_brick*m_size)/2; + p.z = y*m_size - (m_mosaic*m_brick*m_size)/2; + + if ( !m_relief.empty() && + x >= 0 && x <= m_mosaic*m_brick && + y >= 0 && y <= m_mosaic*m_brick ) + { + p.y = m_relief[x+y*(m_mosaic*m_brick+1)]; + } + else + { + p.y = 0.0f; + } + + return p; +} + +/** Calculates a normal soft, taking into account the six adjacent triangles: + +\verbatim + ^ y + | + b---c---+ + |\ |\ | + | \| \| + a---o---d + |\ |\ | + | \| \| + +---f---e--> x +\endverbatim */ +Gfx::VertexTex2 Gfx::CTerrain::GetVertex(int x, int y, int step) +{ + Gfx::VertexTex2 v; + + Math::Vector o = GetVector(x, y); + v.coord = o; + + Math::Vector a = GetVector(x-step, y ); + Math::Vector b = GetVector(x-step, y+step); + Math::Vector c = GetVector(x, y+step); + Math::Vector d = GetVector(x+step, y ); + Math::Vector e = GetVector(x+step, y-step); + Math::Vector f = GetVector(x, y-step); + + Math::Vector s(0.0f, 0.0f, 0.0f); + + if (x-step >= 0 && y+step <= m_mosaic*m_brick+1) + { + s += Math::NormalToPlane(b,a,o); + s += Math::NormalToPlane(c,b,o); + } + + if (x+step <= m_mosaic*m_brick+1 && y+step <= m_mosaic*m_brick+1) + s += Math::NormalToPlane(d,c,o); + + if (x+step <= m_mosaic*m_brick+1 && y-step >= 0) + { + s += Math::NormalToPlane(e,d,o); + s += Math::NormalToPlane(f,e,o); + } + + if (x-step >= 0 && y-step >= 0) + s += Math::NormalToPlane(a,f,o); + + s = Normalize(s); + v.normal = s; + + if (m_multiText) + { + int brick = m_brick/m_subdivMapping; + Math::Vector oo = GetVector((x/brick)*brick, (y/brick)*brick); + o = GetVector(x, y); + v.texCoord.x = (o.x-oo.x)*m_scaleMapping*m_subdivMapping; + v.texCoord.y = 1.0f - (o.z-oo.z)*m_scaleMapping*m_subdivMapping; + } + else + { + v.texCoord.x = o.x*m_scaleMapping; + v.texCoord.y = o.z*m_scaleMapping; + } + + return v; +} + +/** The origin of mosaic is its center. +\verbatim + ^ z + | + | 2---4---6-- + | |\ |\ |\ + | | \| \| + | 1---3---5--- ... + | + +-------------------> x +\endverbatim */ +bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, + const Gfx::Material &mat, + float min, float max) +{ + std::string texName1; + std::string texName2; + + if ( step == 1 && m_engine->GetGroundSpot() ) + { + int i = (ox/5) + (oy/5)*(m_mosaic/5); + std::stringstream s; + s << "shadow"; + s.width(2); + s.fill('0'); + s << i; + s << ".png"; + texName2 = s.str(); + } + + int brick = m_brick/m_subdivMapping; + + Gfx::VertexTex2 o = GetVertex(ox*m_brick+m_brick/2, oy*m_brick+m_brick/2, step); + int total = ((brick/step)+1)*2; + + float pixel = 1.0f/256.0f; // 1 pixel cover (*) + float dp = 1.0f/512.0f; + + Math::Point uv; + + for (int my = 0; my < m_subdivMapping; my++) + { + for (int mx = 0; mx < m_subdivMapping; mx++) + { + if (m_levelText) + { + int xx = ox*m_brick + mx*(m_brick/m_subdivMapping); + int yy = oy*m_brick + my*(m_brick/m_subdivMapping); + LevelTextureName(xx, yy, texName1, uv); + } + else + { + int i = (ox*m_subdivMapping+mx)+(oy*m_subdivMapping+my)*m_mosaic; + std::stringstream s; + s << m_texBaseName; + s.width(3); + s.fill('0'); + s << m_texture[i]; + s << m_texBaseExt; + texName1 = s.str(); + } + + for (int y = 0; y < brick; y += step) + { + Gfx::EngineObjLevel5 buffer; + buffer.vertices.reserve(total); + + buffer.type = Gfx::ENG_TRIANGLE_TYPE_6S; + buffer.material = mat; + + buffer.state = Gfx::ENG_RSTATE_WRAP; + + buffer.state |= Gfx::ENG_RSTATE_SECOND; + if (step == 1) + buffer.state |= Gfx::ENG_RSTATE_DUAL_BLACK; + + for (int x = 0; x <= brick; x += step) + { + Gfx::VertexTex2 p1 = GetVertex(ox*m_brick+mx*brick+x, oy*m_brick+my*brick+y+0 , step); + Gfx::VertexTex2 p2 = GetVertex(ox*m_brick+mx*brick+x, oy*m_brick+my*brick+y+step, step); + p1.coord.x -= o.coord.x; p1.coord.z -= o.coord.z; + p2.coord.x -= o.coord.x; p2.coord.z -= o.coord.z; + + if (m_multiText) + { + if (x == 0) + { + p1.texCoord.x = 0.0f+(0.5f/256.0f); + p2.texCoord.x = 0.0f+(0.5f/256.0f); + } + if (x == brick) + { + p1.texCoord.x = 1.0f-(0.5f/256.0f); + p2.texCoord.x = 1.0f-(0.5f/256.0f); + } + if (y == 0) + p1.texCoord.y = 1.0f-(0.5f/256.0f); + + if (y == brick - step) + p2.texCoord.y = 0.0f+(0.5f/256.0f); + } + + if (m_levelText) + { + p1.texCoord.x /= m_subdivMapping; // 0..1 -> 0..0.25 + p1.texCoord.y /= m_subdivMapping; + p2.texCoord.x /= m_subdivMapping; + p2.texCoord.y /= m_subdivMapping; + + if (x == 0) + { + p1.texCoord.x = 0.0f+dp; + p2.texCoord.x = 0.0f+dp; + } + if (x == brick) + { + p1.texCoord.x = (1.0f/m_subdivMapping)-dp; + p2.texCoord.x = (1.0f/m_subdivMapping)-dp; + } + if (y == 0) + p1.texCoord.y = (1.0f/m_subdivMapping)-dp; + + if (y == brick - step) + p2.texCoord.y = 0.0f+dp; + + p1.texCoord.x += uv.x; + p1.texCoord.y += uv.y; + p2.texCoord.x += uv.x; + p2.texCoord.y += uv.y; + } + + int xx = mx*(m_brick/m_subdivMapping) + x; + int yy = my*(m_brick/m_subdivMapping) + y; + p1.texCoord2.x = (static_cast(ox%5)*m_brick+xx+0.0f)/(m_brick*5); + p1.texCoord2.y = (static_cast(oy%5)*m_brick+yy+0.0f)/(m_brick*5); + p2.texCoord2.x = (static_cast(ox%5)*m_brick+xx+0.0f)/(m_brick*5); + p2.texCoord2.y = (static_cast(oy%5)*m_brick+yy+1.0f)/(m_brick*5); + +// Correction for 1 pixel cover +// There is 1 pixel cover around each of the 16 surfaces: +// +// |<--------------256-------------->| +// | |<----------254---------->| | +// |---|---|---|-- ... --|---|---|---| +// | 0.0 1.0 | +// | | | | +// 0.0 min max 1.0 +// +// The uv coordinates used for texturing are between min and max (instead of 0 and 1) +// This allows to exclude the pixels situated in a margin of a pixel around the surface + + p1.texCoord2.x = (p1.texCoord2.x+pixel)*(1.0f-pixel)/(1.0f+pixel); + p1.texCoord2.y = (p1.texCoord2.y+pixel)*(1.0f-pixel)/(1.0f+pixel); + p2.texCoord2.x = (p2.texCoord2.x+pixel)*(1.0f-pixel)/(1.0f+pixel); + p2.texCoord2.y = (p2.texCoord2.y+pixel)*(1.0f-pixel)/(1.0f+pixel); + + + buffer.vertices.push_back(p1); + buffer.vertices.push_back(p2); + } + m_engine->AddQuick(objRank, buffer, texName1, texName2, min, max, true); + } + } + } + + Math::Matrix transform; + transform.LoadIdentity(); + transform.Set(1, 4, o.coord.x); + transform.Set(3, 4, o.coord.z); + m_engine->SetObjectTransform(objRank, transform); + + return true; +} + +Gfx::TerrainMaterial* Gfx::CTerrain::LevelSearchMat(int id) +{ + for (int i = 0; i < static_cast( m_levelMat.size() ); i++) + { + if (id == m_levelMat[i].id) + return &m_levelMat[i]; + } + + return nullptr; +} + +void Gfx::CTerrain::LevelTextureName(int x, int y, std::string& name, Math::Point &uv) +{ + x /= m_brick/m_subdivMapping; + y /= m_brick/m_subdivMapping; + + TerrainMaterial* tm = LevelSearchMat(m_levelDot[x+y*m_levelDotSize].id); + if (tm == nullptr) + { + name = "xxx.png"; + uv.x = 0.0f; + uv.y = 0.0f; + } + else + { + name = tm->texName; + uv.x = tm->u; + uv.y = tm->v; + } +} + +float Gfx::CTerrain::LevelGetHeight(int x, int y) +{ + int size = (m_mosaic*m_brick+1); + + if (x < 0 ) x = 0; + if (x >= size) x = size-1; + if (y < 0 ) y = 0; + if (y >= size) y = size-1; + + return m_relief[x+y*size]; +} + +bool Gfx::CTerrain::LevelGetDot(int x, int y, float min, float max, float slope) +{ + float hc = LevelGetHeight(x, y); + float h[4] = + { + LevelGetHeight(x+0, y+1), + LevelGetHeight(x+1, y+0), + LevelGetHeight(x+0, y-1), + LevelGetHeight(x-1, y+0) + }; + + if (hc < min || hc > max) + return false; + + if (slope == 0.0f) + return true; + + if (slope > 0.0f) + { + for (int i = 0; i < 4; i++) + { + if (fabs(hc - h[i]) >= slope) + return false; + } + return true; + } + + if (slope < 0.0f) + { + for (int i = 0; i < 4; i++) + { + if (fabs(hc - h[i]) < -slope) + return false; + } + return true; + } + + return false; +} + + +/** Returns the index within m_levelMat or -1 if there is not. + m_levelMat[i].id gives the identifier. */ +int Gfx::CTerrain::LevelTestMat(char *mat) +{ + for (int i = 0; i < static_cast( m_levelMat.size() ); i++) + { + if ( m_levelMat[i].mat[0] == mat[0] && + m_levelMat[i].mat[1] == mat[1] && + m_levelMat[i].mat[2] == mat[2] && + m_levelMat[i].mat[3] == mat[3] ) return i; + } + + return -1; +} + +void Gfx::CTerrain::LevelSetDot(int x, int y, int id, char *mat) +{ + TerrainMaterial* tm = LevelSearchMat(id); + if (tm == nullptr) return; + + if ( tm->mat[0] != mat[0] || + tm->mat[1] != mat[1] || + tm->mat[2] != mat[2] || + tm->mat[3] != mat[3] ) // id incompatible with mat? + { + int ii = LevelTestMat(mat); + if (ii == -1) return; + id = m_levelMat[ii].id; // looking for a id compatible with mat + } + + // Changes the point + m_levelDot[x+y*m_levelDotSize].id = id; + m_levelDot[x+y*m_levelDotSize].mat[0] = mat[0]; + m_levelDot[x+y*m_levelDotSize].mat[1] = mat[1]; + m_levelDot[x+y*m_levelDotSize].mat[2] = mat[2]; + m_levelDot[x+y*m_levelDotSize].mat[3] = mat[3]; + + // Changes the lower neighbor + if ( (x+0) >= 0 && (x+0) < m_levelDotSize && + (y-1) >= 0 && (y-1) < m_levelDotSize ) + { + int i = (x+0)+(y-1)*m_levelDotSize; + if (m_levelDot[i].mat[0] != mat[2]) + { + m_levelDot[i].mat[0] = mat[2]; + int ii = LevelTestMat(m_levelDot[i].mat); + if (ii != -1) + m_levelDot[i].id = m_levelMat[ii].id; + } + } + + // Modifies the left neighbor + if ( (x-1) >= 0 && (x-1) < m_levelDotSize && + (y+0) >= 0 && (y+0) < m_levelDotSize ) + { + int i = (x-1)+(y+0)*m_levelDotSize; + if (m_levelDot[i].mat[1] != mat[3]) + { + m_levelDot[i].mat[1] = mat[3]; + int ii = LevelTestMat(m_levelDot[i].mat); + if (ii != -1) + m_levelDot[i].id = m_levelMat[ii].id; + } + } + + // Changes the upper neighbor + if ( (x+0) >= 0 && (x+0) < m_levelDotSize && + (y+1) >= 0 && (y+1) < m_levelDotSize ) + { + int i = (x+0)+(y+1)*m_levelDotSize; + if (m_levelDot[i].mat[2] != mat[0]) + { + m_levelDot[i].mat[2] = mat[0]; + int ii = LevelTestMat(m_levelDot[i].mat); + if (ii != -1) + m_levelDot[i].id = m_levelMat[ii].id; + } + } + + // Changes the right neighbor + if ( (x+1) >= 0 && (x+1) < m_levelDotSize && + (y+0) >= 0 && (y+0) < m_levelDotSize ) + { + int i = (x+1)+(y+0)*m_levelDotSize; + if ( m_levelDot[i].mat[3] != mat[1] ) + { + m_levelDot[i].mat[3] = mat[1]; + int ii = LevelTestMat(m_levelDot[i].mat); + if (ii != -1) + m_levelDot[i].id = m_levelMat[ii].id; + } + } +} + +bool Gfx::CTerrain::LevelIfDot(int x, int y, int id, char *mat) +{ + char test[4]; + + // Compatible with lower neighbor? + if ( x+0 >= 0 && x+0 < m_levelDotSize && + y-1 >= 0 && y-1 < m_levelDotSize ) + { + test[0] = mat[2]; + test[1] = m_levelDot[(x+0)+(y-1)*m_levelDotSize].mat[1]; + test[2] = m_levelDot[(x+0)+(y-1)*m_levelDotSize].mat[2]; + test[3] = m_levelDot[(x+0)+(y-1)*m_levelDotSize].mat[3]; + + if ( LevelTestMat(test) == -1 ) return false; + } + + // Compatible with left neighbor? + if ( x-1 >= 0 && x-1 < m_levelDotSize && + y+0 >= 0 && y+0 < m_levelDotSize ) + { + test[0] = m_levelDot[(x-1)+(y+0)*m_levelDotSize].mat[0]; + test[1] = mat[3]; + test[2] = m_levelDot[(x-1)+(y+0)*m_levelDotSize].mat[2]; + test[3] = m_levelDot[(x-1)+(y+0)*m_levelDotSize].mat[3]; + + if ( LevelTestMat(test) == -1 ) return false; + } + + // Compatible with upper neighbor? + if ( x+0 >= 0 && x+0 < m_levelDotSize && + y+1 >= 0 && y+1 < m_levelDotSize ) + { + test[0] = m_levelDot[(x+0)+(y+1)*m_levelDotSize].mat[0]; + test[1] = m_levelDot[(x+0)+(y+1)*m_levelDotSize].mat[1]; + test[2] = mat[0]; + test[3] = m_levelDot[(x+0)+(y+1)*m_levelDotSize].mat[3]; + + if ( LevelTestMat(test) == -1 ) return false; + } + + // Compatible with right neighbor? + if ( x+1 >= 0 && x+1 < m_levelDotSize && + y+0 >= 0 && y+0 < m_levelDotSize ) + { + test[0] = m_levelDot[(x+1)+(y+0)*m_levelDotSize].mat[0]; + test[1] = m_levelDot[(x+1)+(y+0)*m_levelDotSize].mat[1]; + test[2] = m_levelDot[(x+1)+(y+0)*m_levelDotSize].mat[2]; + test[3] = mat[1]; + + if ( LevelTestMat(test) == -1 ) return false; + } + + LevelSetDot(x, y, id, mat); // puts the point + return true; +} + +bool Gfx::CTerrain::LevelPutDot(int x, int y, int id) +{ + char mat[4]; + + x /= m_brick/m_subdivMapping; + y /= m_brick/m_subdivMapping; + + if ( x < 0 || x >= m_levelDotSize || + y < 0 || y >= m_levelDotSize ) return false; + + TerrainMaterial* tm = LevelSearchMat(id); + if (tm == nullptr) return false; + + // Tries without changing neighbors. + if ( LevelIfDot(x, y, id, tm->mat) ) return true; + + // Tries changing a single neighbor (4x). + for (int up = 0; up < m_levelMatMax; up++) + { + mat[0] = up; + mat[1] = tm->mat[1]; + mat[2] = tm->mat[2]; + mat[3] = tm->mat[3]; + + if (LevelIfDot(x, y, id, mat)) return true; + } + + for (int right = 0; right < m_levelMatMax; right++) + { + mat[0] = tm->mat[0]; + mat[1] = right; + mat[2] = tm->mat[2]; + mat[3] = tm->mat[3]; + + if (LevelIfDot(x, y, id, mat)) return true; + } + + for (int down = 0; down < m_levelMatMax; down++) + { + mat[0] = tm->mat[0]; + mat[1] = tm->mat[1]; + mat[2] = down; + mat[3] = tm->mat[3]; + + if (LevelIfDot(x, y, id, mat)) return true; + } + + for (int left = 0; left < m_levelMatMax; left++) + { + mat[0] = tm->mat[0]; + mat[1] = tm->mat[1]; + mat[2] = tm->mat[2]; + mat[3] = left; + + if (LevelIfDot(x, y, id, mat)) return true; + } + + // Tries changing two neighbors (6x). + for (int up = 0; up < m_levelMatMax; up++) + { + for (int down = 0; down < m_levelMatMax; down++) + { + mat[0] = up; + mat[1] = tm->mat[1]; + mat[2] = down; + mat[3] = tm->mat[3]; + + if (LevelIfDot(x, y, id, mat)) return true; + } + } + + for (int right = 0; right < m_levelMatMax; right++) + { + for (int left = 0; left < m_levelMatMax; left++) + { + mat[0] = tm->mat[0]; + mat[1] = right; + mat[2] = tm->mat[2]; + mat[3] = left; + + if (LevelIfDot(x, y, id, mat)) return true; + } + } + + for (int up = 0; up < m_levelMatMax; up++) + { + for (int right = 0; right < m_levelMatMax; right++) + { + mat[0] = up; + mat[1] = right; + mat[2] = tm->mat[2]; + mat[3] = tm->mat[3]; + + if (LevelIfDot(x, y, id, mat)) return true; + } + } + + for (int right = 0; right < m_levelMatMax; right++) + { + for (int down = 0; down < m_levelMatMax; down++) + { + mat[0] = tm->mat[0]; + mat[1] = right; + mat[2] = down; + mat[3] = tm->mat[3]; + + if (LevelIfDot(x, y, id, mat)) return true; + } + } + + for (int down = 0; down < m_levelMatMax; down++) + { + for (int left = 0; left < m_levelMatMax; left++) + { + mat[0] = tm->mat[0]; + mat[1] = tm->mat[1]; + mat[2] = down; + mat[3] = left; + + if (LevelIfDot(x, y, id, mat)) return true; + } + } + + for (int up = 0; up < m_levelMatMax; up++) + { + for (int left = 0; left < m_levelMatMax; left++) + { + mat[0] = up; + mat[1] = tm->mat[1]; + mat[2] = tm->mat[2]; + mat[3] = left; + + if (LevelIfDot(x, y, id, mat)) return true; + } + } + + // Tries changing all the neighbors. + for (int up = 0; up < m_levelMatMax; up++) + { + for (int right = 0; right < m_levelMatMax; right++) + { + for (int down = 0; down < m_levelMatMax; down++) + { + for (int left = 0; left < m_levelMatMax; left++) + { + mat[0] = up; + mat[1] = right; + mat[2] = down; + mat[3] = left; + + if (LevelIfDot(x, y, id, mat)) return true; + } + } + } + } + + GetLogger()->Error("LevelPutDot error\n"); + return false; +} + +bool Gfx::CTerrain::LevelInit(int id) +{ + TerrainMaterial* tm = LevelSearchMat(id); + if (tm == nullptr) return false; + + for (int i = 0; i < m_levelDotSize*m_levelDotSize; i++) + { + m_levelDot[i].id = id; + + for (int j = 0; j < 4; j++) + m_levelDot[i].mat[j] = tm->mat[j]; + } + + return true; +} + +bool Gfx::CTerrain::LevelGenerate(int *id, float min, float max, + float slope, float freq, + Math::Vector center, float radius) +{ + static char random[100] = + { + 84,25,12, 6,34,52,85,38,97,16, + 21,31,65,19,62,40,72,22,48,61, + 56,47, 8,53,73,77, 4,91,26,88, + 76, 1,44,93,39,11,71,17,98,95, + 88,83,18,30, 3,57,28,49,74, 9, + 32,13,96,66,15,70,36,10,59,94, + 45,86, 2,29,63,42,51, 0,79,27, + 54, 7,20,69,89,23,64,43,81,92, + 90,33,46,14,67,35,50, 5,87,60, + 68,55,24,78,41,75,58,80,37,82, + }; + + TerrainMaterial* tm = nullptr; + + int i = 0; + while ( id[i] != 0 ) + { + tm = LevelSearchMat(id[i++]); + if (tm == nullptr) return false; + } + int numID = i; + + int group = m_brick / m_subdivMapping; + + if (radius > 0.0f && radius < 5.0f) // just a square? + { + float dim = (m_mosaic*m_brick*m_size)/2.0f; + + int xx = static_cast((center.x+dim)/m_size); + int yy = static_cast((center.z+dim)/m_size); + + int x = xx/group; + int y = yy/group; + + tm = LevelSearchMat(id[0]); + if (tm != nullptr) + LevelSetDot(x, y, id[0], tm->mat); // puts the point + } + else + { + for (int y = 0; y < m_levelDotSize; y++) + { + for (int x = 0; x < m_levelDotSize; x++) + { + if (radius != 0.0f) + { + Math::Vector pos; + pos.x = (static_cast(x)-m_levelDotSize/2.0f)*group*m_size; + pos.z = (static_cast(y)-m_levelDotSize/2.0f)*group*m_size; + if (Math::DistanceProjected(pos, center) > radius) continue; + } + + if (freq < 100.0f) + { + int rnd = random[(x%10)+(y%10)*10]; + if ( static_cast(rnd) > freq ) continue; + } + + int xx = x*group + group/2; + int yy = y*group + group/2; + + if (LevelGetDot(xx, yy, min, max, slope)) + { + int rnd = random[(x%10)+(y%10)*10]; + int ii = rnd % numID; + LevelPutDot(xx, yy, id[ii]); + } + } + } + } + + return true; +} + +void Gfx::CTerrain::LevelOpenTable() +{ + if (! m_levelText) return; + if (! m_levelDot.empty()) return; // already allocated + + m_levelDotSize = (m_mosaic*m_brick)/(m_brick/m_subdivMapping)+1; + std::vector(m_levelDotSize*m_levelDotSize).swap(m_levelDot); + + for (int i = 0; i < m_levelDotSize * m_levelDotSize; i++) + { + for (int j = 0; j < 4; j++) + m_levelDot[i].mat[j] = 0; + } +} + +void Gfx::CTerrain::LevelCloseTable() +{ + m_levelDot.clear(); +} + +bool Gfx::CTerrain::CreateSquare(bool multiRes, int x, int y) +{ + Gfx::Material mat; + mat.diffuse = Gfx::Color(1.0f, 1.0f, 1.0f); + mat.ambient = Gfx::Color(0.0f, 0.0f, 0.0f); + + int objRank = m_engine->CreateObject(); + m_engine->SetObjectType(objRank, Gfx::ENG_OBJTYPE_TERRAIN); // it is a terrain + + m_objRank[x+y*m_mosaic] = objRank; + + if (multiRes) + { + float min = 0.0f; + float max = m_vision; + max *= m_engine->GetClippingDistance(); + for (int step = 0; step < m_depth; step++) + { + CreateMosaic(x, y, 1 << step, objRank, mat, min, max); + min = max; + max *= 2; + if (step == m_depth-1) max = Math::HUGE_NUM; + } + } + else + { + CreateMosaic(x, y, 1, objRank, mat, 0.0f, Math::HUGE_NUM); + } + + return true; +} + +bool Gfx::CTerrain::CreateObjects(bool multiRes) +{ + AdjustRelief(); + + for (int y = 0; y < m_mosaic; y++) + { + for (int x = 0; x < m_mosaic; x++) + CreateSquare(multiRes, x, y); + } + + return true; +} + +/** ATTENTION: ok only with m_depth = 2! */ +bool Gfx::CTerrain::Terraform(const Math::Vector &p1, const Math::Vector &p2, float height) +{ + float dim = (m_mosaic*m_brick*m_size)/2.0f; + + Math::IntPoint tp1, tp2; + tp1.x = static_cast((p1.x+dim+m_size/2.0f)/m_size); + tp1.y = static_cast((p1.z+dim+m_size/2.0f)/m_size); + tp2.x = static_cast((p2.x+dim+m_size/2.0f)/m_size); + tp2.y = static_cast((p2.z+dim+m_size/2.0f)/m_size); + + if (tp1.x > tp2.x) + { + int x = tp1.x; + tp1.x = tp2.x; + tp2.x = x; + } + + if (tp1.y > tp2.y) + { + int y = tp1.y; + tp1.y = tp2.y; + tp2.y = y; + } + + int size = (m_mosaic*m_brick)+1; + + // Calculates the current average height + float avg = 0.0f; + int nb = 0; + for (int y = tp1.y; y <= tp2.y; y++) + { + for (int x = tp1.x; x <= tp2.x; x++) + { + avg += m_relief[x+y*size]; + nb ++; + } + } + avg /= static_cast(nb); + + // Changes the description of the relief + for (int y = tp1.y; y <= tp2.y; y++) + { + for (int x = tp1.x; x <= tp2.x; x++) + { + m_relief[x+y*size] = avg+height; + + if (x % m_brick == 0 && y % m_depth != 0) + { + m_relief[(x+0)+(y-1)*size] = avg+height; + m_relief[(x+0)+(y+1)*size] = avg+height; + } + + if (y % m_brick == 0 && x % m_depth != 0) + { + m_relief[(x-1)+(y+0)*size] = avg+height; + m_relief[(x+1)+(y+0)*size] = avg+height; + } + } + } + AdjustRelief(); + + Math::IntPoint pp1, pp2; + pp1.x = (tp1.x-2)/m_brick; + pp1.y = (tp1.y-2)/m_brick; + pp2.x = (tp2.x+1)/m_brick; + pp2.y = (tp2.y+1)/m_brick; + + if (pp1.x < 0 ) pp1.x = 0; + if (pp1.x >= m_mosaic) pp1.x = m_mosaic-1; + if (pp1.y < 0 ) pp1.y = 0; + if (pp1.y >= m_mosaic) pp1.y = m_mosaic-1; + + for (int y = pp1.y; y <= pp2.y; y++) + { + for (int x = pp1.x; x <= pp2.x; x++) + { + m_engine->DeleteObject(m_objRank[x+y*m_mosaic]); + CreateSquare(m_multiText, x, y); // recreates the square + } + } + m_engine->Update(); + + return true; +} + +void Gfx::CTerrain::SetWind(Math::Vector speed) +{ + m_wind = speed; +} + +Math::Vector Gfx::CTerrain::GetWind() +{ + return m_wind; +} + +float Gfx::CTerrain::GetFineSlope(const Math::Vector &pos) +{ + Math::Vector n; + if (! GetNormal(n, pos)) return 0.0f; + return fabs(Math::RotateAngle(Math::Point(n.x, n.z).Length(), n.y) - Math::PI/2.0f); +} + +float Gfx::CTerrain::GetCoarseSlope(const Math::Vector &pos) +{ + if (m_relief.empty()) return 0.0f; + + float dim = (m_mosaic*m_brick*m_size)/2.0f; + + int x = static_cast((pos.x+dim)/m_size); + int y = static_cast((pos.z+dim)/m_size); + + if ( x < 0 || x >= m_mosaic*m_brick || + y < 0 || y >= m_mosaic*m_brick ) return 0.0f; + + float level[4] = + { + m_relief[(x+0)+(y+0)*(m_mosaic*m_brick+1)], + m_relief[(x+1)+(y+0)*(m_mosaic*m_brick+1)], + m_relief[(x+0)+(y+1)*(m_mosaic*m_brick+1)], + m_relief[(x+1)+(y+1)*(m_mosaic*m_brick+1)], + }; + + float min = Math::Min(level[0], level[1], level[2], level[3]); + float max = Math::Max(level[0], level[1], level[2], level[3]); + + return atanf((max-min)/m_size); +} + +bool Gfx::CTerrain::GetNormal(Math::Vector &n, const Math::Vector &p) +{ + float dim = (m_mosaic*m_brick*m_size)/2.0f; + + int x = static_cast((p.x+dim)/m_size); + int y = static_cast((p.z+dim)/m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) return false; + + Math::Vector p1 = GetVector(x+0, y+0); + Math::Vector p2 = GetVector(x+1, y+0); + Math::Vector p3 = GetVector(x+0, y+1); + Math::Vector p4 = GetVector(x+1, y+1); + + if ( fabs(p.z - p2.z) < fabs(p.x - p2.x) ) + n = Math::NormalToPlane(p1,p2,p3); + else + n = Math::NormalToPlane(p2,p4,p3); + + return true; +} + +float Gfx::CTerrain::GetFloorLevel(const Math::Vector &p, bool brut, bool water) +{ + float dim = (m_mosaic*m_brick*m_size)/2.0f; + + int x = static_cast((p.x+dim)/m_size); + int y = static_cast((p.z+dim)/m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) return false; + + Math::Vector p1 = GetVector(x+0, y+0); + Math::Vector p2 = GetVector(x+1, y+0); + Math::Vector p3 = GetVector(x+0, y+1); + Math::Vector p4 = GetVector(x+1, y+1); + + Math::Vector ps = p; + if ( fabs(p.z-p2.z) < fabs(p.x-p2.x) ) + { + if ( !IntersectY(p1, p2, p3, ps) ) return 0.0f; + } + else + { + if ( !IntersectY(p2, p4, p3, ps) ) return 0.0f; + } + + if (! brut) AdjustBuildingLevel(ps); + + if (water) // not going underwater? + { + float level = m_water->GetLevel(); + if (ps.y < level) ps.y = level; // not under water + } + + return ps.y; +} + + +/** This height is positive when you are above the ground */ +float Gfx::CTerrain::GetFloorHeight(const Math::Vector &p, bool brut, bool water) +{ + float dim = (m_mosaic*m_brick*m_size)/2.0f; + + int x = static_cast((p.x+dim)/m_size); + int y = static_cast((p.z+dim)/m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) return false; + + Math::Vector p1 = GetVector(x+0, y+0); + Math::Vector p2 = GetVector(x+1, y+0); + Math::Vector p3 = GetVector(x+0, y+1); + Math::Vector p4 = GetVector(x+1, y+1); + + Math::Vector ps = p; + if ( fabs(p.z-p2.z) < fabs(p.x-p2.x) ) + { + if ( !IntersectY(p1, p2, p3, ps) ) return 0.0f; + } + else + { + if ( !IntersectY(p2, p4, p3, ps) ) return 0.0f; + } + + if (! brut) AdjustBuildingLevel(ps); + + if (water) // not going underwater? + { + float level = m_water->GetLevel(); + if ( ps.y < level ) ps.y = level; // not under water + } + + return p.y-ps.y; +} + +bool Gfx::CTerrain::MoveOnFloor(Math::Vector &p, bool brut, bool water) +{ + float dim = (m_mosaic*m_brick*m_size)/2.0f; + + int x = static_cast((p.x + dim) / m_size); + int y = static_cast((p.z + dim) / m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) return false; + + Math::Vector p1 = GetVector(x+0, y+0); + Math::Vector p2 = GetVector(x+1, y+0); + Math::Vector p3 = GetVector(x+0, y+1); + Math::Vector p4 = GetVector(x+1, y+1); + + if (fabs(p.z - p2.z) < fabs(p.x - p2.x)) + { + if (! Math::IntersectY(p1, p2, p3, p)) return false; + } + else + { + if (! Math::IntersectY(p2, p4, p3, p)) return false; + } + + if (! brut) AdjustBuildingLevel(p); + + if (water) // not going underwater? + { + float level = m_water->GetLevel(); + if (p.y < level) p.y = level; // not under water + } + + return true; +} + + +/** Returns false if the initial coordinate was too far */ +bool Gfx::CTerrain::ValidPosition(Math::Vector &p, float marging) +{ + bool ok = true; + + float limit = m_mosaic*m_brick*m_size/2.0f - marging; + + if (p.x < -limit) + { + p.x = -limit; + ok = false; + } + + if (p.z < -limit) + { + p.z = -limit; + ok = false; + } + + if (p.x > limit) + { + p.x = limit; + ok = false; + } + + if (p.z > limit) + { + p.z = limit; + ok = false; + } + + return ok; +} + +void Gfx::CTerrain::FlushBuildingLevel() +{ + m_buildingLevels.clear(); +} + +bool Gfx::CTerrain::AddBuildingLevel(Math::Vector center, float min, float max, + float height, float factor) +{ + int i = 0; + for ( ; i < static_cast( m_buildingLevels.size() ); i++) + { + if ( center.x == m_buildingLevels[i].center.x && + center.z == m_buildingLevels[i].center.z ) + { + break; + } + } + + if (i == static_cast( m_buildingLevels.size() )) + m_buildingLevels.push_back(Gfx::BuildingLevel()); + + m_buildingLevels[i].center = center; + m_buildingLevels[i].min = min; + m_buildingLevels[i].max = max; + m_buildingLevels[i].level = GetFloorLevel(center, true); + m_buildingLevels[i].height = height; + m_buildingLevels[i].factor = factor; + m_buildingLevels[i].bboxMinX = center.x-max; + m_buildingLevels[i].bboxMaxX = center.x+max; + m_buildingLevels[i].bboxMinZ = center.z-max; + m_buildingLevels[i].bboxMaxZ = center.z+max; + + return true; +} + +bool Gfx::CTerrain::UpdateBuildingLevel(Math::Vector center) +{ + for (int i = 0; i < static_cast( m_buildingLevels.size() ); i++) + { + if ( center.x == m_buildingLevels[i].center.x && + center.z == m_buildingLevels[i].center.z ) + { + m_buildingLevels[i].center = center; + m_buildingLevels[i].level = GetFloorLevel(center, true); + return true; + } + } + return false; +} + +bool Gfx::CTerrain::DeleteBuildingLevel(Math::Vector center) +{ + for (int i = 0; i < static_cast( m_buildingLevels.size() ); i++) + { + if ( center.x == m_buildingLevels[i].center.x && + center.z == m_buildingLevels[i].center.z ) + { + for (int j = i+1; j < static_cast( m_buildingLevels.size() ); j++) + m_buildingLevels[j-1] = m_buildingLevels[j]; + + m_buildingLevels.pop_back(); + return true; + } + } + return false; +} + +float Gfx::CTerrain::GetBuildingFactor(const Math::Vector &p) +{ + for (int i = 0; i < static_cast( m_buildingLevels.size() ); i++) + { + if ( p.x < m_buildingLevels[i].bboxMinX || + p.x > m_buildingLevels[i].bboxMaxX || + p.z < m_buildingLevels[i].bboxMinZ || + p.z > m_buildingLevels[i].bboxMaxZ ) continue; + + float dist = Math::DistanceProjected(p, m_buildingLevels[i].center); + + if (dist <= m_buildingLevels[i].max) + return m_buildingLevels[i].factor; + } + return 1.0f; // it is normal on the ground +} + +void Gfx::CTerrain::AdjustBuildingLevel(Math::Vector &p) +{ + for (int i = 0; i < static_cast( m_buildingLevels.size() ); i++) + { + if ( p.x < m_buildingLevels[i].bboxMinX || + p.x > m_buildingLevels[i].bboxMaxX || + p.z < m_buildingLevels[i].bboxMinZ || + p.z > m_buildingLevels[i].bboxMaxZ ) continue; + + float dist = Math::DistanceProjected(p, m_buildingLevels[i].center); + + if (dist > m_buildingLevels[i].max) continue; + + if (dist < m_buildingLevels[i].min) + { + p.y = m_buildingLevels[i].level + m_buildingLevels[i].height; + return; + } + + Math::Vector border; + border.x = ((p.x - m_buildingLevels[i].center.x) * m_buildingLevels[i].max) / + dist + m_buildingLevels[i].center.x; + border.z = ((p.z - m_buildingLevels[i].center.z) * m_buildingLevels[i].max) / + dist + m_buildingLevels[i].center.z; + + float base = GetFloorLevel(border, true); + + p.y = (m_buildingLevels[i].max - dist) / + (m_buildingLevels[i].max - m_buildingLevels[i].min) * + (m_buildingLevels[i].level + m_buildingLevels[i].height-base) + + base; + + return; + } +} + + +// returns the hardness of the ground in a given place. +// The hardness determines the noise (SOUND_STEP and SOUND_BOUM). + +float Gfx::CTerrain::GetHardness(const Math::Vector &p) +{ + float factor = GetBuildingFactor(p); + if (factor != 1.0f) return 1.0f; // on building + + if (m_levelDot.empty()) return m_defHardness; + + float dim = (m_mosaic*m_brick*m_size)/2.0f; + + int x, y; + + x = static_cast((p.x+dim)/m_size); + y = static_cast((p.z+dim)/m_size); + + if ( x < 0 || x > m_mosaic*m_brick || + y < 0 || y > m_mosaic*m_brick ) return m_defHardness; + + x /= m_brick/m_subdivMapping; + y /= m_brick/m_subdivMapping; + + if ( x < 0 || x >= m_levelDotSize || + y < 0 || y >= m_levelDotSize ) return m_defHardness; + + int id = m_levelDot[x+y*m_levelDotSize].id; + TerrainMaterial* tm = LevelSearchMat(id); + if (tm == nullptr) return m_defHardness; + + return tm->hardness; +} + +void Gfx::CTerrain::GroundFlat(Math::Vector pos) +{ + static char table[41*41]; + + + float rapport = 3200.0f/1024.0f; + + for (int y = 0; y <= 40; y++) + { + for (int x = 0; x <= 40; x++) + { + int i = x + y*41; + table[i] = 0; + + Math::Vector p; + p.x = (x-20)*rapport; + p.z = (y-20)*rapport; + p.y = 0.0f; + + if (Math::Point(p.x, p.y).Length() > 20.0f*rapport) + continue; + + float angle = GetFineSlope(pos+p); + + if (angle < FLATLIMIT) + table[i] = 1; + else + table[i] = 2; + } + } + + m_engine->GroundMarkCreate(pos, 40.0f, 0.001f, 15.0f, 0.001f, 41, 41, table); +} + +float Gfx::CTerrain::GetFlatZoneRadius(Math::Vector center, float max) +{ + float angle = GetFineSlope(center); + if (angle >= Gfx::FLATLIMIT) + return 0.0f; + + float ref = GetFloorLevel(center, true); + + float radius = 1.0f; + while (radius <= max) + { + angle = 0.0f; + int nb = static_cast(2.0f*Math::PI*radius); + if (nb < 8) nb = 8; + + for (int i = 0; i < nb; i++) + { + Math::Point c(center.x, center.z); + Math::Point p (center.x+radius, center.z); + p = Math::RotatePoint(c, angle, p); + Math::Vector pos; + pos.x = p.x; + pos.z = p.y; + float h = GetFloorLevel(pos, true); + if ( fabs(h-ref) > 1.0f ) return radius; + + angle += Math::PI*2.0f/8.0f; + } + radius += 1.0f; + } + return max; +} + +void Gfx::CTerrain::SetFlyingMaxHeight(float height) +{ + m_flyingMaxHeight = height; +} + +float Gfx::CTerrain::GetFlyingMaxHeight() +{ + return m_flyingMaxHeight; +} + +void Gfx::CTerrain::FlushFlyingLimit() +{ + m_flyingMaxHeight = 280.0f; + m_flyingLimits.clear(); +} + +void Gfx::CTerrain::AddFlyingLimit(Math::Vector center, + float extRadius, float intRadius, + float maxHeight) +{ + Gfx::FlyingLimit fl; + fl.center = center; + fl.extRadius = extRadius; + fl.intRadius = intRadius; + fl.maxHeight = maxHeight; + m_flyingLimits.push_back(fl); +} + +float Gfx::CTerrain::GetFlyingLimit(Math::Vector pos, bool noLimit) +{ + if (noLimit) + return 280.0f; + + if (m_flyingLimits.empty()) + return m_flyingMaxHeight; + + for (int i = 0; i < static_cast( m_flyingLimits.size() ); i++) + { + float dist = Math::DistanceProjected(pos, m_flyingLimits[i].center); + + if (dist >= m_flyingLimits[i].extRadius) + continue; + + if (dist <= m_flyingLimits[i].intRadius) + return m_flyingLimits[i].maxHeight; + + dist -= m_flyingLimits[i].intRadius; + + float h = dist * (m_flyingMaxHeight - m_flyingLimits[i].maxHeight) / + (m_flyingLimits[i].extRadius - m_flyingLimits[i].intRadius); + + return h + m_flyingLimits[i].maxHeight; + } + + return m_flyingMaxHeight; +} diff --git a/src/graphics/engine/terrain.h b/src/graphics/engine/terrain.h index 8d8b1658..a1985901 100644 --- a/src/graphics/engine/terrain.h +++ b/src/graphics/engine/terrain.h @@ -40,56 +40,72 @@ enum TerrainRes TR_STONE = 1, TR_URANIUM = 2, TR_POWER = 3, - TR_KEYa = 4, - TR_KEYb = 5, - TR_KEYc = 6, - TR_KEYd = 7, + TR_KEY_A = 4, + TR_KEY_B = 5, + TR_KEY_C = 6, + TR_KEY_D = 7, }; - -const short MAXBUILDINGLEVEL = 100; - struct BuildingLevel { - Math::Vector center; - float factor; - float min; - float max; - float level; - float height; - float bboxMinX; - float bboxMaxX; - float bboxMinZ; - float bboxMaxZ; + Math::Vector center; + float factor; + float min; + float max; + float level; + float height; + float bboxMinX; + float bboxMaxX; + float bboxMinZ; + float bboxMaxZ; + + BuildingLevel() + { + factor = min = max = level = height = 0.0f; + bboxMinX = bboxMaxX = bboxMinZ = bboxMaxZ = 0.0f; + } }; - -const short MAXMATTERRAIN = 100; - struct TerrainMaterial { short id; - char texName[20]; + std::string texName; float u,v; float hardness; char mat[4]; // up, right, down, left + + TerrainMaterial() + { + id = 0; + u = v = 0.0f; + hardness = 0.0f; + mat[0] = mat[1] = mat[2] = mat[3] = 0; + } }; struct DotLevel { short id; char mat[4]; // up, right, down, left + + DotLevel() + { + id = 0; + mat[0] = mat[1] = mat[2] = mat[3] = 0; + } }; - -const short MAXFLYINGLIMIT = 10; - struct FlyingLimit { - Math::Vector center; - float extRadius; - float intRadius; - float maxHeight; + Math::Vector center; + float extRadius; + float intRadius; + float maxHeight; + + FlyingLimit() + { + extRadius = intRadius = maxHeight = 0.0f; + } }; @@ -100,72 +116,124 @@ public: CTerrain(CInstanceManager* iMan); ~CTerrain(); - bool Generate(int mosaic, int brickP2, float size, float vision, int depth, float hardness); - bool InitTextures(char* baseName, int* table, int dx, int dy); + //! Generates a new flat terrain + bool Generate(int mosaic, int brickPow2, float size, float vision, int depth, float hardness); + //! Initializes the names of textures to use for the land + bool InitTextures(const std::string& baseName, int* table, int dx, int dy); + //! Empties level void LevelFlush(); - bool LevelMaterial(int id, char* baseName, float u, float v, int up, int right, int down, int left, float hardness); + //! Initializes the names of textures to use for the land + void LevelMaterial(int id, std::string& baseName, float u, float v, int up, int right, int down, int left, float hardness); + //! Initializes all the ground with a material bool LevelInit(int id); + //! Generates a level in the terrain bool LevelGenerate(int *id, float min, float max, float slope, float freq, Math::Vector center, float radius); + //! Initializes a completely flat terrain void FlushRelief(); - bool ReliefFromBMP(const char* filename, float scaleRelief, bool adjustBorder); - bool ReliefFromDXF(const char* filename, float scaleRelief); - bool ResFromBMP(const char* filename); - bool CreateObjects(bool bMultiRes); - bool Terraform(const Math::Vector &p1, const Math::Vector &p2, float height); + //! Load relief from a PNG file + bool ReliefFromPNG(const std::string& filename, float scaleRelief, bool adjustBorder); + //! Load resources from a PNG file + bool ResFromPNG(const std::string& filename); + //! Creates all objects of the terrain within the 3D engine + bool CreateObjects(bool multiRes); + //! Modifies the terrain's relief + bool Terraform(const Math::Vector& p1, const Math::Vector& p2, float height); - void SetWind(Math::Vector speed); - Math::Vector RetWind(); + //@{ + //! Management of the wind + void SetWind(Math::Vector speed); + Math::Vector GetWind(); + //@} - float RetFineSlope(const Math::Vector &pos); - float RetCoarseSlope(const Math::Vector &pos); - bool GetNormal(Math::Vector &n, const Math::Vector &p); - float RetFloorLevel(const Math::Vector &p, bool bBrut=false, bool bWater=false); - float RetFloorHeight(const Math::Vector &p, bool bBrut=false, bool bWater=false); - bool MoveOnFloor(Math::Vector &p, bool bBrut=false, bool bWater=false); - bool ValidPosition(Math::Vector &p, float marging); - TerrainRes RetResource(const Math::Vector &p); + //! Gives the exact slope of the terrain of a place given + float GetFineSlope(const Math::Vector& pos); + //! Gives the approximate slope of the terrain of a specific location + float GetCoarseSlope(const Math::Vector& pos); + //! Gives the normal vector at the position p (x,-,z) of the ground + bool GetNormal(Math::Vector& n, const Math::Vector &p); + //! returns the height of the ground + float GetFloorLevel(const Math::Vector& p, bool brut=false, bool water=false); + //! Returns the height to the ground + float GetFloorHeight(const Math::Vector& p, bool brut=false, bool water=false); + //! Modifies the coordinate "y" of point "p" to rest on the ground floor + bool MoveOnFloor(Math::Vector& p, bool brut=false, bool water=false); + //! Modifies a coordinate so that it is on the ground + bool ValidPosition(Math::Vector& p, float marging); + //! Returns the resource type available underground + Gfx::TerrainRes GetResource(const Math::Vector& p); + //! Adjusts a position so that it does not exceed the boundaries void LimitPos(Math::Vector &pos); + //! Empty the table of elevations void FlushBuildingLevel(); + //! Adds a new elevation for a building bool AddBuildingLevel(Math::Vector center, float min, float max, float height, float factor); + //! Updates the elevation for a building when it was moved up (after a terraforming) bool UpdateBuildingLevel(Math::Vector center); + //! Removes the elevation for a building when it was destroyed bool DeleteBuildingLevel(Math::Vector center); - float RetBuildingFactor(const Math::Vector &p); - float RetHardness(const Math::Vector &p); + //! Returns the influence factor whether a position is on a possible rise + float GetBuildingFactor(const Math::Vector& p); + float GetHardness(const Math::Vector& p); - int RetMosaic(); - int RetBrick(); - float RetSize(); - float RetScaleRelief(); + int GetMosaic(); + int GetBrick(); + float GetSize(); + float GetScaleRelief(); + //! Shows the flat areas on the ground void GroundFlat(Math::Vector pos); - float RetFlatZoneRadius(Math::Vector center, float max); + //! Calculates the radius of the largest flat area available + float GetFlatZoneRadius(Math::Vector center, float max); + //@{ + //! Management of the global max flying height void SetFlyingMaxHeight(float height); - float RetFlyingMaxHeight(); + float GetFlyingMaxHeight(); + //@} + //! Empty the table of flying limits void FlushFlyingLimit(); - bool AddFlyingLimit(Math::Vector center, float extRadius, float intRadius, float maxHeight); - float RetFlyingLimit(Math::Vector pos, bool bNoLimit); + //! Adds a new flying limit + void AddFlyingLimit(Math::Vector center, float extRadius, float intRadius, float maxHeight); + //! Returns the maximum height of flight + float GetFlyingLimit(Math::Vector pos, bool noLimit); protected: + //! Adds a point of elevation in the buffer of relief bool ReliefAddDot(Math::Vector pos, float scaleRelief); + //! Adjust the edges of each mosaic to be compatible with all lower resolutions void AdjustRelief(); - Math::Vector RetVector(int x, int y); - Gfx::VertexTex2 RetVertex(int x, int y, int step); - bool CreateMosaic(int ox, int oy, int step, int objRank, const Gfx::Material &mat, float min, float max); - bool CreateSquare(bool bMultiRes, int x, int y); + //! Calculates a vector of the terrain + Math::Vector GetVector(int x, int y); + //! Calculates a vertex of the terrain + Gfx::VertexTex2 GetVertex(int x, int y, int step); + //! Creates all objects of a mosaic + bool CreateMosaic(int ox, int oy, int step, int objRank, const Gfx::Material& mat, float min, float max); + //! Creates all objects in a mesh square ground + bool CreateSquare(bool multiRes, int x, int y); - TerrainMaterial* LevelSearchMat(int id); - void LevelTextureName(int x, int y, char *name, Math::Point &uv); - float LevelRetHeight(int x, int y); + //! Seeks a materials based on theirs identifier + Gfx::TerrainMaterial* LevelSearchMat(int id); + //! Chooses texture to use for a given square + void LevelTextureName(int x, int y, std::string& name, Math::Point &uv); + //! Returns the height of the terrain + float LevelGetHeight(int x, int y); + //! Decide whether a point is using the materials bool LevelGetDot(int x, int y, float min, float max, float slope); + //! Seeks if material exists int LevelTestMat(char *mat); + //! Modifies the state of a point and its four neighbors, without testing if possible void LevelSetDot(int x, int y, int id, char *mat); + //! Tests if a material can give a place, according to its four neighbors. If yes, puts the point. bool LevelIfDot(int x, int y, int id, char *mat); + //! Modifies the state of a point bool LevelPutDot(int x, int y, int id); + //! Initializes a table with empty levels void LevelOpenTable(); + //! Closes the level table void LevelCloseTable(); + //! Adjusts a position according to a possible rise void AdjustBuildingLevel(Math::Vector &p); protected: @@ -173,39 +241,49 @@ protected: CEngine* m_engine; CWater* m_water; - int m_mosaic; // number of mosaics - int m_brick; // number of bricks per mosaics - float m_size; // size of an item in an brick - float m_vision; // vision before a change of resolution - float* m_relief; // table of the relief - int* m_texture; // table of textures - int* m_objRank; // table of rows of objects - bool m_bMultiText; - bool m_bLevelText; - float m_scaleMapping; // scale of the mapping + //! Number of mosaics + int m_mosaic; + //! Number of bricks per mosaics + int m_brick; + int m_levelDotSize; + //! Size of an item in a brick + float m_size; + //! Vision before a change of resolution + float m_vision; + //! Table of the relief + std::vector m_relief; + //! Table of textures + std::vector m_texture; + //! Table of rows of objects + std::vector m_objRank; + //! Table of resources + std::vector m_resources; + bool m_multiText; + bool m_levelText; + //! Scale of the mapping + float m_scaleMapping; float m_scaleRelief; - int m_subdivMapping; - int m_depth; // number of different resolutions (1,2,3,4) - char m_texBaseName[20]; - char m_texBaseExt[10]; + int m_subdivMapping; + //! Number of different resolutions (1,2,3,4) + int m_depth; + std::string m_texBaseName; + std::string m_texBaseExt; float m_defHardness; - TerrainMaterial m_levelMat[MAXMATTERRAIN+1]; - int m_levelMatTotal; + std::vector m_levelMat; + std::vector m_levelDot; int m_levelMatMax; - int m_levelDotSize; - DotLevel* m_levelDot; int m_levelID; - int m_buildingUsed; - BuildingLevel m_buildingTable[MAXBUILDINGLEVEL]; + std::vector m_buildingLevels; - unsigned char* m_resources; - Math::Vector m_wind; // wind speed + //! Wind speed + Math::Vector m_wind; + //! Global flying height limit float m_flyingMaxHeight; - int m_flyingLimitTotal; - FlyingLimit m_flyingLimit[MAXFLYINGLIMIT]; + //! List of local flight limits + std::vector m_flyingLimits; }; }; // namespace Gfx diff --git a/src/graphics/engine/water.h b/src/graphics/engine/water.h index 67be9dcd..6d3736e4 100644 --- a/src/graphics/engine/water.h +++ b/src/graphics/engine/water.h @@ -72,7 +72,7 @@ public: CWater(CInstanceManager* iMan, Gfx::CEngine* engine); ~CWater(); - void SetGLDevice(Gfx::CDevice device); + void SetDevice(Gfx::CDevice* device); bool EventProcess(const Event &event); void Flush(); bool Create(WaterType type1, WaterType type2, const char *filename, Gfx::Color diffuse, Gfx::Color ambient, float level, float glint, Math::Vector eddy); @@ -80,11 +80,11 @@ public: void DrawSurf(); bool SetLevel(float level); - float RetLevel(); - float RetLevel(CObject* object); + float GetLevel(); + float GetLevel(CObject* object); void SetLava(bool bLava); - bool RetLava(); + bool GetLava(); void AdjustEye(Math::Vector &eye); @@ -92,7 +92,7 @@ protected: bool EventFrame(const Event &event); void LavaFrame(float rTime); void AdjustLevel(Math::Vector &pos, Math::Vector &norm, Math::Point &uv1, Math::Point &uv2); - bool RetWater(int x, int y); + bool GetWater(int x, int y); bool CreateLine(int x, int y, int len); void VaporFlush(); @@ -101,8 +101,8 @@ protected: protected: CInstanceManager* m_iMan; - CEngine* m_engine; - CDevice* m_pDevice; + CEngine* m_engine; + CDevice* m_device; CTerrain* m_terrain; CParticle* m_particule; CSound* m_sound; From c1936514c054d6d7c85843bf2c3e0b97653ef651 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Wed, 8 Aug 2012 23:51:19 +0200 Subject: [PATCH 04/10] CWater and CCloud basic implementation Added rewritten implementation for CWater and CCloud Won't link yet because of missing functions --- src/graphics/engine/cloud.cpp | 267 +++++++++++++- src/graphics/engine/cloud.h | 72 ++-- src/graphics/engine/water.cpp | 640 +++++++++++++++++++++++++++++++++- src/graphics/engine/water.h | 137 +++++--- 4 files changed, 1042 insertions(+), 74 deletions(-) diff --git a/src/graphics/engine/cloud.cpp b/src/graphics/engine/cloud.cpp index d0e5ed80..e46b0742 100644 --- a/src/graphics/engine/cloud.cpp +++ b/src/graphics/engine/cloud.cpp @@ -19,5 +19,270 @@ #include "graphics/engine/cloud.h" +#include "common/iman.h" +#include "graphics/engine/engine.h" +#include "graphics/engine/terrain.h" +#include "math/geometry.h" -// TODO implementation + +const int CLOUD_LINE_PREALLOCATE_COUNT = 100; + +const int DIMEXPAND = 4; // extension of the dimensions + + +Gfx::CCloud::CCloud(CInstanceManager* iMan, Gfx::CEngine* engine) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_CLOUD, this); + + m_engine = engine; + m_terrain = nullptr; + + m_level = 0.0f; + m_wind = Math::Vector(0.0f, 0.0f, 0.0f); + m_subdiv = 8; + m_enable = true; + + m_line.reserve(CLOUD_LINE_PREALLOCATE_COUNT); +} + +Gfx::CCloud::~CCloud() +{ + m_iMan = nullptr; + m_engine = nullptr; + m_terrain = nullptr; +} + +bool Gfx::CCloud::EventProcess(const Event &event) +{ + /* TODO! + if ( event.event == EVENT_FRAME ) + return EventFrame(event); */ + + return true; +} + +bool Gfx::CCloud::EventFrame(const Event &event) +{ + /* TODO! + if (m_engine->GetPause()) return true; + + m_time += event.rTime; + + if (m_level == 0.0f) return true; + + if (m_time - m_lastTest < 0.2f) return true; + + m_lastTest = m_time; */ + + return true; +} + +void Gfx::CCloud::AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep, + Math::Point &uv1, Math::Point &uv2) +{ + uv1.x = (pos.x+20000.0f)/1280.0f; + uv1.y = (pos.z+20000.0f)/1280.0f; + uv1.x -= m_time*(m_wind.x/100.0f); + uv1.y -= m_time*(m_wind.z/100.0f); + + uv2.x = 0.0f; + uv2.y = 0.0f; + + float dist = Math::DistanceProjected(pos, eye); + float factor = powf(dist/deep, 2.0f); + pos.y -= m_level*factor*10.0f; +} + +void Gfx::CCloud::Draw() +{ + /* TODO! + LPDIRECT3DDEVICE7 device; + D3DVERTEX2* vertex; + Math::Matrix* matView; + D3DMATERIAL7 material; + Math::Matrix matrix; + Math::Vector n, pos, p, eye; + Math::Point uv1, uv2; + float iDeep, deep, size, fogStart, fogEnd; + int i, j, u; + + if ( !m_enable ) return; + if ( m_level == 0.0f ) return; + if ( m_lineUsed == 0 ) return; + + vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2); + + iDeep = m_engine->GetDeepView(); + deep = (m_brick*m_size)/2.0f; + m_engine->SetDeepView(deep); + m_engine->SetFocus(m_engine->GetFocus()); + m_engine->UpdateMatProj(); // increases the depth of view + + fogStart = deep*0.15f; + fogEnd = deep*0.24f; + + device = m_engine->GetD3DDevice(); + device->SetRenderState(D3DRENDERSTATE_AMBIENT, 0x00000000); + device->SetRenderState(D3DRENDERSTATE_LIGHTING, false); + device->SetRenderState(D3DRENDERSTATE_ZENABLE, false); + device->SetRenderState(D3DRENDERSTATE_FOGENABLE, true); + device->SetRenderState(D3DRENDERSTATE_FOGSTART, F2DW(fogStart)); + device->SetRenderState(D3DRENDERSTATE_FOGEND, F2DW(fogEnd)); + + matView = m_engine->GetMatView(); + { + D3DMATRIX mat = MAT_TO_D3DMAT(*matView); + device->SetTransform(D3DTRANSFORMSTATE_VIEW, &mat); + } + + ZeroMemory( &material, sizeof(D3DMATERIAL7) ); + material.diffuse = m_diffuse; + material.ambient = m_ambient; + m_engine->SetMaterial(material); + + m_engine->SetTexture(m_filename, 0); + m_engine->SetTexture(m_filename, 1); + + m_engine->SetState(D3DSTATETTb|D3DSTATEFOG|D3DSTATEWRAP); + + matrix.LoadIdentity(); + { + D3DMATRIX mat = MAT_TO_D3DMAT(matrix); + device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); + } + + size = m_size/2.0f; + eye = m_engine->GetEyePt(); + n = Math::Vector(0.0f, -1.0f, 0.0f); + + // Draws all the lines. + for ( i=0 ; iDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL); + m_engine->AddStatisticTriangle(u-2); + } + + m_engine->SetDeepView(iDeep); + m_engine->SetFocus(m_engine->GetFocus()); + m_engine->UpdateMatProj(); // gives depth to initial + + free(vertex); */ +} + +void Gfx::CCloud::CreateLine(int x, int y, int len) +{ + Gfx::CloudLine line; + + line.x = x; + line.y = y; + line.len = len; + + float offset = m_brick*m_size/2.0f - m_size/2.0f; + + line.px1 = m_size* line.x - offset; + line.px2 = m_size*(line.x+line.len) - offset; + line.pz = m_size* line.y - offset; + + m_line.push_back(line); +} + +void Gfx::CCloud::Create(const std::string& fileName, + Gfx::Color diffuse, Gfx::Color ambient, + float level) +{ + m_diffuse = diffuse; + m_ambient = ambient; + m_level = level; + m_time = 0.0f; + m_lastTest = 0.0f; + m_fileName = fileName; + + if (! m_fileName.empty()) + { + m_engine->LoadTexture(m_fileName, 0); + m_engine->LoadTexture(m_fileName, 1); + } + + if (m_terrain == nullptr) + m_terrain = static_cast(m_iMan->SearchInstance(CLASS_TERRAIN)); + + m_wind = m_terrain->GetWind(); + + m_brick = m_terrain->GetBrick()*m_terrain->GetMosaic()*DIMEXPAND; + m_size = m_terrain->GetSize(); + + m_brick /= m_subdiv*DIMEXPAND; + m_size *= m_subdiv*DIMEXPAND; + + if (m_level == 0.0f) + return; + + m_line.clear(); + for (int y = 0; y < m_brick; y++) + CreateLine(0, y, m_brick); + + return; +} + +void Gfx::CCloud::Flush() +{ + m_level = 0.0f; +} + + +void Gfx::CCloud::SetLevel(float level) +{ + m_level = level; + + Create(m_fileName, m_diffuse, m_ambient, m_level); +} + +float Gfx::CCloud::GetLevel() +{ + return m_level; +} + +void Gfx::CCloud::SetEnable(bool enable) +{ + m_enable = enable; +} + +bool Gfx::CCloud::GetEnable() +{ + return m_enable; +} diff --git a/src/graphics/engine/cloud.h b/src/graphics/engine/cloud.h index 562f651a..676dfe82 100644 --- a/src/graphics/engine/cloud.h +++ b/src/graphics/engine/cloud.h @@ -24,6 +24,9 @@ #include "math/point.h" #include "math/vector.h" +#include +#include + class CInstanceManager; @@ -34,13 +37,20 @@ namespace Gfx { class CEngine; class CTerrain; -const short MAXCLOUDLINE = 100; - struct CloudLine { - short x, y; // beginning - short len; // in length x + //! Beginning + short x, y; + //! In length x + short len; float px1, px2, pz; + + CloudLine() + { + x = y = 0; + len = 0; + px1 = px2 = pz = 0; + } }; @@ -51,43 +61,59 @@ public: ~CCloud(); bool EventProcess(const Event &event); + //! Removes all the clouds void Flush(); - bool Create(const char *filename, Gfx::Color diffuse, Gfx::Color ambient, float level); + //! Creates all areas of cloud + void Create(const std::string& fileName, Gfx::Color diffuse, Gfx::Color ambient, float level); + //! Draw the clouds void Draw(); - bool SetLevel(float level); + //! Modifies the cloud level + void SetLevel(float level); + //! Returns the current level of clouds float GetLevel(); - void SetEnable(bool bEnable); + //! Activate management of clouds + void SetEnable(bool enable); bool GetEnable(); protected: + //! Makes the clouds evolve bool EventFrame(const Event &event); - void AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep, Math::Point &uv1, Math::Point &uv2); - bool CreateLine(int x, int y, int len); + //! Adjusts the position to normal, to imitate the clouds at movement + void AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep, + Math::Point &uv1, Math::Point &uv2); + //! Updates the positions, relative to the ground + void CreateLine(int x, int y, int len); protected: - CInstanceManager* m_iMan; - CEngine* m_engine; - CTerrain* m_terrain; + CInstanceManager* m_iMan; + Gfx::CEngine* m_engine; + Gfx::CTerrain* m_terrain; - char m_filename[100]; - float m_level; // overall level - Math::Point m_speed; // feedrate (wind) - Gfx::Color m_diffuse; // diffuse color - Gfx::Color m_ambient; // ambient color + std::string m_fileName; + //! Overall level + float m_level; + //! Feedrate (wind) + Math::Point m_speed; + //! Diffuse color + Gfx::Color m_diffuse; + //! Ambient color + Gfx::Color m_ambient; float m_time; float m_lastTest; int m_subdiv; - Math::Vector m_wind; // wind speed - int m_brick; // brick mosaic - float m_size; // size of a brick element + //! Wind speed + Math::Vector m_wind; + //! Brick mosaic + int m_brick; + //! Size of a brick element + float m_size; - int m_lineUsed; - CloudLine m_line[MAXCLOUDLINE]; + std::vector m_line; - bool m_bEnable; + bool m_enable; }; diff --git a/src/graphics/engine/water.cpp b/src/graphics/engine/water.cpp index a157e829..1f116717 100644 --- a/src/graphics/engine/water.cpp +++ b/src/graphics/engine/water.cpp @@ -19,5 +19,643 @@ #include "graphics/engine/water.h" +#include "common/iman.h" +#include "graphics/engine/engine.h" +#include "graphics/engine/terrain.h" +#include "sound/sound.h" + + +const int WATERLINE_PREALLOCATE_COUNT = 500; + +// TODO: remove the limit? +const int VAPOR_SIZE = 10; + + +Gfx::CWater::CWater(CInstanceManager* iMan, Gfx::CEngine* engine) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_WATER, this); + + m_engine = engine; + m_terrain = nullptr; + m_particule = nullptr; + m_sound = nullptr; + + m_type[0] = WATER_NULL; + m_type[1] = WATER_NULL; + m_level = 0.0f; + m_draw = true; + m_lava = false; + m_color = 0xffffffff; + m_subdiv = 4; + + m_line.reserve(WATERLINE_PREALLOCATE_COUNT); + + std::vector(VAPOR_SIZE).swap(m_vapor); +} + +Gfx::CWater::~CWater() +{ + m_iMan = nullptr; + m_engine = nullptr; + m_terrain = nullptr; + m_particule = nullptr; + m_sound = nullptr; +} + + +bool Gfx::CWater::EventProcess(const Event &event) +{ + /* TODO! + if (event.type == EVENT_FRAME) + return EventFrame(event); +*/ + return true; +} + +bool Gfx::CWater::EventFrame(const Event &event) +{ + /* TODO! + if (m_engine->GetPause()) return true; + + m_time += event.rTime; + + if (m_type[0] == WATER_NULL) return true; + + if (m_lava) + LavaFrame(event.rTime);*/ + + return true; +} + +void Gfx::CWater::LavaFrame(float rTime) +{ + if (m_particule == nullptr) + m_particule = static_cast( m_iMan->SearchInstance(CLASS_PARTICULE) ); + + for (int i = 0; i < static_cast( m_vapor.size() ); i++) + VaporFrame(i, rTime); + + if (m_time - m_lastLava >= 0.1f) + { + Math::Vector eye = m_engine->GetEyePt(); + Math::Vector lookat = m_engine->GetLookatPt(); + + float distance = Math::Rand()*200.0f; + float shift = (Math::Rand()-0.5f)*200.0f; + + Math::Vector dir = Normalize(lookat-eye); + Math::Vector pos = eye + dir*distance; + + Math::Vector perp; + perp.x = -dir.z; + perp.y = dir.y; + perp.z = dir.x; + pos = pos + perp*shift; + + float level = m_terrain->GetFloorLevel(pos, true); + if (level < m_level) + { + pos.y = m_level; + + level = Math::Rand(); + if (level < 0.8f) + { + if ( VaporCreate(Gfx::PARTIFIRE, pos, 0.02f+Math::Rand()*0.06f) ) + m_lastLava = m_time; + } + else if (level < 0.9f) + { + if ( VaporCreate(Gfx::PARTIFLAME, pos, 0.5f+Math::Rand()*3.0f) ) + m_lastLava = m_time; + } + else + { + if ( VaporCreate(Gfx::PARTIVAPOR, pos, 0.2f+Math::Rand()*2.0f) ) + m_lastLava = m_time; + } + } + } +} + +void Gfx::CWater::VaporFlush() +{ + m_vapor.clear(); +} + +bool Gfx::CWater::VaporCreate(Gfx::ParticleType type, Math::Vector pos, float delay) +{ + for (int i = 0; i < static_cast( m_vapor.size() ); i++) + { + if (! m_vapor[i].used) + { + m_vapor[i].used = true; + m_vapor[i].type = type; + m_vapor[i].pos = pos; + m_vapor[i].delay = delay; + m_vapor[i].time = 0.0f; + m_vapor[i].last = 0.0f; + + if (m_vapor[i].type == PARTIFIRE) + m_sound->Play(SOUND_BLUP, pos, 1.0f, 1.0f-Math::Rand()*0.5f); + + if (m_vapor[i].type == PARTIVAPOR) + m_sound->Play(SOUND_PSHHH, pos, 0.3f, 2.0f); + + return true; + } + } + + return false; +} + +void Gfx::CWater::VaporFrame(int i, float rTime) +{ + m_vapor[i].time += rTime; + + if (m_sound == nullptr) + m_sound = static_cast(m_iMan->SearchInstance(CLASS_SOUND)); + + if (m_vapor[i].time <= m_vapor[i].delay) + { + if (m_time-m_vapor[i].last >= m_engine->ParticleAdapt(0.02f)) + { + m_vapor[i].last = m_time; + + if (m_vapor[i].type == PARTIFIRE) + { + for (int j = 0; j < 10; j++) + { + Math::Vector pos = m_vapor[i].pos; + pos.x += (Math::Rand()-0.5f)*2.0f; + pos.z += (Math::Rand()-0.5f)*2.0f; + pos.y -= 1.0f; + Math::Vector speed; + speed.x = (Math::Rand()-0.5f)*6.0f; + speed.z = (Math::Rand()-0.5f)*6.0f; + speed.y = 8.0f+Math::Rand()*5.0f; + Math::Point dim; + dim.x = Math::Rand()*1.5f+1.5f; + dim.y = dim.x; + m_particule->CreateParticle(pos, speed, dim, PARTIERROR, 2.0f, 10.0f); + } + } + else if (m_vapor[i].type == PARTIFLAME) + { + Math::Vector pos = m_vapor[i].pos; + pos.x += (Math::Rand()-0.5f)*8.0f; + pos.z += (Math::Rand()-0.5f)*8.0f; + pos.y -= 2.0f; + Math::Vector speed; + speed.x = (Math::Rand()-0.5f)*2.0f; + speed.z = (Math::Rand()-0.5f)*2.0f; + speed.y = 4.0f+Math::Rand()*4.0f; + Math::Point dim; + dim.x = Math::Rand()*2.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticle(pos, speed, dim, PARTIFLAME); + } + else + { + Math::Vector pos = m_vapor[i].pos; + pos.x += (Math::Rand()-0.5f)*4.0f; + pos.z += (Math::Rand()-0.5f)*4.0f; + pos.y -= 2.0f; + Math::Vector speed; + speed.x = (Math::Rand()-0.5f)*2.0f; + speed.z = (Math::Rand()-0.5f)*2.0f; + speed.y = 8.0f+Math::Rand()*8.0f; + Math::Point dim; + dim.x = Math::Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticle(pos, speed, dim, PARTIVAPOR); + } + } + } + else + { + m_vapor[i].used = false; + } +} + +void Gfx::CWater::AdjustLevel(Math::Vector &pos, Math::Vector &norm, + Math::Point &uv1, Math::Point &uv2) +{ + float t1 = m_time*1.5f + pos.x*0.1f * pos.z*0.2f; + pos.y += sinf(t1)*m_eddy.y; + + t1 = m_time*1.5f; + uv1.x = (pos.x+10000.0f)/40.0f+sinf(t1)*m_eddy.x*0.02f; + uv1.y = (pos.z+10000.0f)/40.0f-cosf(t1)*m_eddy.z*0.02f; + uv2.x = (pos.x+10010.0f)/20.0f+cosf(-t1)*m_eddy.x*0.02f; + uv2.y = (pos.z+10010.0f)/20.0f-sinf(-t1)*m_eddy.z*0.02f; + + t1 = m_time*0.50f + pos.x*2.1f + pos.z*1.1f; + float t2 = m_time*0.75f + pos.x*2.0f + pos.z*1.0f; + norm = Math::Vector(sinf(t1)*m_glint, 1.0f, sinf(t2)*m_glint); +} + +/** This surface prevents to see the sky (background) underwater! */ +void Gfx::CWater::DrawBack() +{ + /* TODO! + LPDIRECT3DDEVICE7 device; + D3DVERTEX2 vertex[4]; // 2 triangles + D3DMATERIAL7 material; + Math::Matrix matrix; + Math::Vector eye, lookat, n, p, p1, p2; + Math::Point uv1, uv2; + float deep, dist; + + if ( !m_bDraw ) return; + if ( m_type[0] == WATER_NULL ) return; + if ( m_lineUsed == 0 ) return; + + eye = m_engine->GetEyePt(); + lookat = m_engine->GetLookatPt(); + + ZeroMemory( &material, sizeof(D3DMATERIAL7) ); + material.diffuse = m_diffuse; + material.ambient = m_ambient; + m_engine->SetMaterial(material); + + m_engine->SetTexture("", 0); + + device = m_engine->GetD3DDevice(); + device->SetRenderState(D3DRENDERSTATE_LIGHTING, false); + device->SetRenderState(D3DRENDERSTATE_ZENABLE, false); + device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); + m_engine->SetState(D3DSTATENORMAL); + + deep = m_engine->GetDeepView(0); + m_engine->SetDeepView(deep*2.0f, 0); + m_engine->SetFocus(m_engine->GetFocus()); + m_engine->UpdateMatProj(); // twice the depth of view + + matrix.LoadIdentity(); + { + D3DMATRIX mat = MAT_TO_D3DMAT(matrix); + device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); + } + + p.x = eye.x; + p.z = eye.z; + dist = Math::DistanceProjected(eye, lookat); + p.x = (lookat.x-eye.x)*deep*1.0f/dist + eye.x; + p.z = (lookat.z-eye.z)*deep*1.0f/dist + eye.z; + + p1.x = (lookat.z-eye.z)*deep*2.0f/dist + p.x; + p1.z = -(lookat.x-eye.x)*deep*2.0f/dist + p.z; + p2.x = -(lookat.z-eye.z)*deep*2.0f/dist + p.x; + p2.z = (lookat.x-eye.x)*deep*2.0f/dist + p.z; + + p1.y = -50.0f; + p2.y = m_level; + + n.x = (lookat.x-eye.x)/dist; + n.z = (lookat.z-eye.z)/dist; + n.y = 0.0f; + + uv1.x = uv1.y = 0.0f; + uv2.x = uv2.y = 0.0f; + + vertex[0] = D3DVERTEX2(Math::Vector(p1.x, p2.y, p1.z), n, uv1.x,uv2.y); + vertex[1] = D3DVERTEX2(Math::Vector(p1.x, p1.y, p1.z), n, uv1.x,uv1.y); + vertex[2] = D3DVERTEX2(Math::Vector(p2.x, p2.y, p2.z), n, uv2.x,uv2.y); + vertex[3] = D3DVERTEX2(Math::Vector(p2.x, p1.y, p2.z), n, uv2.x,uv1.y); + + device->DrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, 4, NULL); + m_engine->AddStatisticTriangle(2); + + m_engine->SetDeepView(deep, 0); + m_engine->SetFocus(m_engine->GetFocus()); + m_engine->UpdateMatProj(); // gives the initial depth of view + + device->SetRenderState(D3DRENDERSTATE_LIGHTING, true); + device->SetRenderState(D3DRENDERSTATE_ZENABLE, true); + device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false);*/ +} + +void Gfx::CWater::DrawSurf() +{ + /* TODO! + LPDIRECT3DDEVICE7 device; + D3DVERTEX2* vertex; // triangles + D3DMATERIAL7 material; + Math::Matrix matrix; + Math::Vector eye, lookat, n, pos, p; + Math::Point uv1, uv2; + bool bUnder; + DWORD flags; + float deep, size, sizez, radius; + int rankview, i, j, u; + + if (! m_draw) return; + if (m_type[0] == Gfx::WATER_NULL) return; + if (m_line.empty()) return; + + vertex = (D3DVERTEX2*)malloc(sizeof(D3DVERTEX2)*(m_brick+2)*2); + + eye = m_engine->GetEyePt(); + lookat = m_engine->GetLookatPt(); + + rankview = m_engine->GetRankView(); + bUnder = ( rankview == 1); + + device = m_engine->GetD3DDevice(); + device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); + + matrix.LoadIdentity(); + { + D3DMATRIX mat = MAT_TO_D3DMAT(matrix); + device->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); + } + + ZeroMemory( &material, sizeof(D3DMATERIAL7) ); + material.diffuse = m_diffuse; + material.ambient = m_ambient; + m_engine->SetMaterial(material); + + m_engine->SetTexture(m_filename, 0); + m_engine->SetTexture(m_filename, 1); + + if ( m_type[rankview] == WATER_TT ) + { + m_engine->SetState(D3DSTATETTb|D3DSTATEDUALw|D3DSTATEWRAP, m_color); + } + if ( m_type[rankview] == WATER_TO ) + { + m_engine->SetState(D3DSTATENORMAL|D3DSTATEDUALw|D3DSTATEWRAP); + } + if ( m_type[rankview] == WATER_CT ) + { + m_engine->SetState(D3DSTATETTb); + } + if ( m_type[rankview] == WATER_CO ) + { + m_engine->SetState(D3DSTATENORMAL); + } + device->SetRenderState(D3DRENDERSTATE_FOGENABLE, true); + + size = m_size/2.0f; + if ( bUnder ) sizez = -size; + else sizez = size; + + // Draws all the lines. + deep = m_engine->GetDeepView(0)*1.5f; + + for ( i=0 ; i deep+radius ) continue; + + D3DVECTOR pD3D = VEC_TO_D3DVEC(p); + device->ComputeSphereVisibility(&pD3D, &radius, 1, 0, &flags); + + if ( flags & D3DSTATUS_CLIPINTERSECTIONALL ) continue; + + u = 0; + p.x = pos.x-size; + p.z = pos.z-sizez; + p.y = pos.y; + AdjustLevel(p, n, uv1, uv2); + if ( bUnder ) n.y = -n.y; + vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); + + p.x = pos.x-size; + p.z = pos.z+sizez; + p.y = pos.y; + AdjustLevel(p, n, uv1, uv2); + if ( bUnder ) n.y = -n.y; + vertex[u++] = D3DVERTEX2(p, n, uv1.x,uv1.y, uv2.x,uv2.y); + + for ( j=0 ; jDrawPrimitive(D3DPT_TRIANGLESTRIP, D3DFVF_VERTEX2, vertex, u, NULL); + m_engine->AddStatisticTriangle(u-2); + } + + free(vertex);*/ +} + +bool Gfx::CWater::GetWater(int x, int y) +{ + x *= m_subdiv; + y *= m_subdiv; + + float size = m_size/m_subdiv; + float offset = m_brick*m_size/2.0f; + + for (int dy = 0; dy <= m_subdiv; dy++) + { + for (int dx = 0; dx <= m_subdiv; dx++) + { + Math::Vector pos; + pos.x = (x+dx)*size - offset; + pos.z = (y+dy)*size - offset; + pos.y = 0.0f; + float level = m_terrain->GetFloorLevel(pos, true); + if (level < m_level+m_eddy.y) + return true; + } + } + return false; +} + +void Gfx::CWater::CreateLine(int x, int y, int len) +{ + Gfx::WaterLine line; + + line.x = x; + line.y = y; + line.len = len; + + float offset = m_brick*m_size/2.0f - m_size/2.0f; + + line.px1 = m_size* line.x - offset; + line.px2 = m_size*(line.x+line.len) - offset; + line.pz = m_size* line.y - offset; + + m_line.push_back(line); +} + +void Gfx::CWater::Create(Gfx::WaterType type1, Gfx::WaterType type2, const std::string& fileName, + Gfx::Color diffuse, Gfx::Color ambient, + float level, float glint, Math::Vector eddy) +{ + m_type[0] = type1; + m_type[1] = type2; + m_diffuse = diffuse; + m_ambient = ambient; + m_level = level; + m_glint = glint; + m_eddy = eddy; + m_time = 0.0f; + m_lastLava = 0.0f; + m_fileName = fileName; + + VaporFlush(); + + if (! m_fileName.empty()) + { + m_engine->LoadTexture(m_fileName, 0); + m_engine->LoadTexture(m_fileName, 1); + } + + if (m_terrain == nullptr) + m_terrain = static_cast(m_iMan->SearchInstance(CLASS_TERRAIN)); + + m_brick = m_terrain->GetBrick()*m_terrain->GetMosaic(); + m_size = m_terrain->GetSize(); + + m_brick /= m_subdiv; + m_size *= m_subdiv; + + if (m_type[0] == WATER_NULL) + return; + + m_line.clear(); + + for (int y = 0; y < m_brick; y++) + { + int len = 0; + for (int x = 0; x < m_brick; x++) + { + if (GetWater(x,y)) // water here? + { + len ++; + if (len >= 5) + { + CreateLine(x-len+1, y, len); + len = 0; + } + } + else // dry? + { + if (len != 0) + { + CreateLine(x-len, y, len); + len = 0; + } + } + } + if (len != 0) + CreateLine(m_brick - len, y, len); + } +} + +void Gfx::CWater::Flush() +{ + m_type[0] = Gfx::WATER_NULL; + m_type[1] = Gfx::WATER_NULL; + m_level = 0.0f; + m_lava = false; +} + +void Gfx::CWater::SetLevel(float level) +{ + m_level = level; + + Create(m_type[0], m_type[1], m_fileName, m_diffuse, m_ambient, + m_level, m_glint, m_eddy); +} + +float Gfx::CWater::GetLevel() +{ + return m_level; +} + +float Gfx::CWater::GetLevel(CObject* object) +{ + /* TODO! + ObjectType type = object->GetType(); + + if ( type == OBJECT_HUMAN || + type == OBJECT_TECH ) + { + return m_level-3.0f; + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEtg || + type == OBJECT_MOBILEft || + type == OBJECT_MOBILEtt || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEit || + type == OBJECT_MOBILEdr ) + { + return m_level-2.0f; + } +*/ + return m_level; +} + +void Gfx::CWater::SetLava(bool lava) +{ + m_lava = lava; +} + +bool Gfx::CWater::GetLava() +{ + return m_lava; +} + +void Gfx::CWater::AdjustEye(Math::Vector &eye) +{ + if (m_lava) + { + if (eye.y < m_level+2.0f) + eye.y = m_level+2.0f; // never under the lava + } + else + { + if (eye.y >= m_level-2.0f && + eye.y <= m_level+2.0f) // close to the surface? + eye.y = m_level+2.0f; // bam, well above + } +} -// TODO implementation diff --git a/src/graphics/engine/water.h b/src/graphics/engine/water.h index 6d3736e4..245baf71 100644 --- a/src/graphics/engine/water.h +++ b/src/graphics/engine/water.h @@ -19,50 +19,64 @@ #pragma once -#include "graphics/engine/engine.h" -#include "graphics/engine/particle.h" #include "common/event.h" +#include "graphics/engine/particle.h" class CInstanceManager; -class CSound; +class CSoundInterface; namespace Gfx { +class CEngine; class CTerrain; - -const short MAXWATERLINE = 500; - struct WaterLine { - short x, y; // beginning - short len; // length by x + //! Beginning + short x, y; + //! Length by x + short len; float px1, px2, pz; + + WaterLine() + { + x = y = 0; + len = 0; + px1 = px2 = pz = 0.0f; + } }; - -const short MAXWATVAPOR = 10; - struct WaterVapor { - bool bUsed; - ParticleType type; - Math::Vector pos; - float delay; - float time; - float last; -}; + bool used; + Gfx::ParticleType type; + Math::Vector pos; + float delay; + float time; + float last; + WaterVapor() + { + used = false; + type = Gfx::PARTIWATER; + delay = time = last = 0.0f; + } +}; enum WaterType { - WATER_NULL = 0, // no water - WATER_TT = 1, // transparent texture - WATER_TO = 2, // opaque texture - WATER_CT = 3, // transparent color - WATER_CO = 4, // opaque color + //! No water + WATER_NULL = 0, + //! Transparent texture + WATER_TT = 1, + //! Opaque texture + WATER_TO = 2, + //! Transparent color + WATER_CT = 3, + //! Opaque color + WATER_CO = 4, }; @@ -74,61 +88,86 @@ public: void SetDevice(Gfx::CDevice* device); bool EventProcess(const Event &event); + //! Removes all the water void Flush(); - bool Create(WaterType type1, WaterType type2, const char *filename, Gfx::Color diffuse, Gfx::Color ambient, float level, float glint, Math::Vector eddy); + //! Creates all expanses of water + void Create(WaterType type1, WaterType type2, const std::string& fileName, + Gfx::Color diffuse, Gfx::Color ambient, float level, float glint, Math::Vector eddy); + //! Draw the back surface of the water void DrawBack(); + //! Draws the flat surface of the water void DrawSurf(); - bool SetLevel(float level); + //! Changes the level of the water + void SetLevel(float level); + //! Returns the current level of water float GetLevel(); + //! Returns the current level of water for a given object float GetLevel(CObject* object); - void SetLava(bool bLava); + //@{ + //! Management of the mode of lava/water + void SetLava(bool lava); bool GetLava(); + //@} + //! Adjusts the eye of the camera, not to be in the water void AdjustEye(Math::Vector &eye); protected: + //! Makes water evolve bool EventFrame(const Event &event); + //! Makes evolve the steam jets on the lava void LavaFrame(float rTime); + //! Adjusts the position to normal, to imitate reflections on an expanse of water at rest void AdjustLevel(Math::Vector &pos, Math::Vector &norm, Math::Point &uv1, Math::Point &uv2); + //! Indicates if there is water in a given position bool GetWater(int x, int y); - bool CreateLine(int x, int y, int len); + //! Updates the positions, relative to the ground + void CreateLine(int x, int y, int len); + //! Removes all the steam jets void VaporFlush(); + //! Creates a new steam bool VaporCreate(ParticleType type, Math::Vector pos, float delay); + //! Makes evolve a steam jet void VaporFrame(int i, float rTime); protected: - CInstanceManager* m_iMan; - CEngine* m_engine; - CDevice* m_device; - CTerrain* m_terrain; - CParticle* m_particule; - CSound* m_sound; + CInstanceManager* m_iMan; + Gfx::CEngine* m_engine; + Gfx::CDevice* m_device; + Gfx::CTerrain* m_terrain; + Gfx::CParticle* m_particule; + CSoundInterface* m_sound; WaterType m_type[2]; - char m_filename[100]; - float m_level; // overall level - float m_glint; // amplitude of reflections - Math::Vector m_eddy; // amplitude of swirls - Gfx::Color m_diffuse; // diffuse color - Gfx::Color m_ambient; // ambient color + std::string m_fileName; + //! Overall level + float m_level; + //! Amplitude of reflections + float m_glint; + //! Amplitude of swirls + Math::Vector m_eddy; + //! Diffuse color + Gfx::Color m_diffuse; + //! Ambient color + Gfx::Color m_ambient; float m_time; float m_lastLava; - int m_subdiv; + int m_subdiv; - int m_brick; // number of brick*mosaics - float m_size; // size of a item in an brick + //! Number of brick*mosaics + int m_brick; + //! Size of a item in an brick + float m_size; - int m_lineUsed; - WaterLine m_line[MAXWATERLINE]; + std::vector m_line; + std::vector m_vapor; - WaterVapor m_vapor[MAXWATVAPOR]; - - bool m_bDraw; - bool m_bLava; - long m_color; + bool m_draw; + bool m_lava; + long m_color; }; }; // namespace Gfx From acff306cc132c4f8cc71f44f85ffd7bdd18a114e Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Thu, 9 Aug 2012 22:49:13 +0200 Subject: [PATCH 05/10] CPlanet implementation Added rewritten CPlanet implementation --- src/graphics/engine/planet.cpp | 164 ++++++++++++++++++++++++++++++++- src/graphics/engine/planet.h | 72 +++++++++------ 2 files changed, 209 insertions(+), 27 deletions(-) diff --git a/src/graphics/engine/planet.cpp b/src/graphics/engine/planet.cpp index 4f1f6145..022de666 100644 --- a/src/graphics/engine/planet.cpp +++ b/src/graphics/engine/planet.cpp @@ -19,5 +19,167 @@ #include "graphics/engine/planet.h" +#include "common/iman.h" +#include "graphics/core/device.h" +#include "graphics/engine/engine.h" -// TODO implementation + +const int PLANET_PREALLOCATE_COUNT = 10; + + +Gfx::CPlanet::CPlanet(CInstanceManager* iMan, Gfx::CEngine* engine) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_PLANET, this); + + m_planet[0].reserve(PLANET_PREALLOCATE_COUNT); + m_planet[1].reserve(PLANET_PREALLOCATE_COUNT); + + m_engine = engine; + Flush(); + +} + +Gfx::CPlanet::~CPlanet() +{ + m_iMan = nullptr; +} + +void Gfx::CPlanet::Flush() +{ + for (int j = 0; j < 2; j++) + m_planet[j].clear(); + + m_planetExist = false; + m_mode = 0; + m_time = 0.0f; +} + +bool Gfx::CPlanet::EventProcess(const Event &event) +{ + if (event.type == EVENT_FRAME) + return EventFrame(event); + + return true; +} + +bool Gfx::CPlanet::EventFrame(const Event &event) +{ + if (m_engine->GetPause()) return true; + + m_time += event.rTime; + + for (int i = 0; i < static_cast( m_planet[m_mode].size() ); i++) + { + float a = m_time*m_planet[m_mode][i].speed; + if (a < 0.0f) + a += Math::PI*1000.0f; + + m_planet[m_mode][i].angle.x = a+m_planet[m_mode][i].start.x; + m_planet[m_mode][i].angle.y = sinf(a)*sinf(m_planet[m_mode][i].dir)+m_planet[m_mode][i].start.y; + } + + return true; +} + +void Gfx::CPlanet::LoadTexture() +{ + for (int j = 0; j < 2; j++) + { + for (int i = 0; i < static_cast( m_planet[j].size() ); i++) + { + m_engine->LoadTexture(m_planet[j][i].name); + } + } +} + +void Gfx::CPlanet::Draw() +{ + Gfx::CDevice* device = m_engine->GetDevice(); + float eyeDirH = m_engine->GetEyeDirH(); + float eyeDirV = m_engine->GetEyeDirV(); + + Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal + float dp = 0.5f/256.0f; + + for (int i = 0; i < static_cast( m_planet[m_mode].size() ); i++) + { + m_engine->SetTexture(m_planet[m_mode][i].name); + + if (m_planet[m_mode][i].transparent) + m_engine->SetState(Gfx::ENG_RSTATE_WRAP | Gfx::ENG_RSTATE_ALPHA); + else + m_engine->SetState(Gfx::ENG_RSTATE_WRAP | Gfx::ENG_RSTATE_TTEXTURE_BLACK); + + Math::Point p1, p2; + + float a = eyeDirH + m_planet[m_mode][i].angle.x; + p1.x = Math::Mod(a, Math::PI*2.0f)-0.5f; + + a = eyeDirV + m_planet[m_mode][i].angle.y; + p1.y = 0.4f+(Math::Mod(a+Math::PI, Math::PI*2.0f)-Math::PI)*(2.0f/Math::PI); + + p1.x -= m_planet[m_mode][i].dim/2.0f*0.75f; + p1.y -= m_planet[m_mode][i].dim/2.0f; + p2.x = p1.x+m_planet[m_mode][i].dim*0.75f; + p2.y = p1.y+m_planet[m_mode][i].dim; + + float u1 = m_planet[m_mode][i].uv1.x + dp; + float v1 = m_planet[m_mode][i].uv1.y + dp; + float u2 = m_planet[m_mode][i].uv2.x - dp; + float v2 = m_planet[m_mode][i].uv2.y - dp; + + Gfx::Vertex quad[4] = + { + 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)) + }; + + device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4); + m_engine->AddStatisticTriangle(2); + } +} + +void Gfx::CPlanet::Create(int mode, Math::Point start, float dim, float speed, + float dir, const std::string& name, Math::Point uv1, Math::Point uv2) +{ + if (mode < 0) mode = 0; + if (mode > 1) mode = 1; + + Gfx::Planet planet; + + planet.start = start; + planet.angle = start; + planet.dim = dim; + planet.speed = speed; + planet.dir = dir; + + planet.name = name; + planet.uv1 = uv1; + planet.uv2 = uv2; + + planet.transparent = planet.name.find("planet") != std::string::npos; + + m_planet[mode].push_back(planet); + + m_planetExist = true; +} + +bool Gfx::CPlanet::PlanetExist() +{ + return m_planetExist; +} + +void Gfx::CPlanet::SetMode(int mode) +{ + if (mode < 0) mode = 0; + if (mode > 1) mode = 1; + m_mode = mode; +} + +int Gfx::CPlanet::GetMode() +{ + return m_mode; +} diff --git a/src/graphics/engine/planet.h b/src/graphics/engine/planet.h index 264d05c7..5ba318b2 100644 --- a/src/graphics/engine/planet.h +++ b/src/graphics/engine/planet.h @@ -22,6 +22,8 @@ #include "common/event.h" #include "math/point.h" +#include + class CInstanceManager; @@ -30,51 +32,69 @@ namespace Gfx { class CEngine; - -const short MAXPLANET = 10; - struct Planet { - char bUsed; // TRUE -> planet exists - Math::Point start; // initial position in degrees - Math::Point angle; // current position in degrees - float dim; // dimensions (0..1) - float speed; // speed - float dir; // direction in the sky - char name[20]; // name of the texture - Math::Point uv1, uv2; // texture mapping - char bTGA; // texture .TGA + //! Initial position in degrees + Math::Point start; + //! Current position in degrees + Math::Point angle; + //! Dimensions (0..1) + float dim; + //! Speed + float speed; + //! Direction in the sky + float dir; + //! Name of the texture + std::string name; + //! Texture mapping + Math::Point uv1, uv2; + //! Transparent texture + bool transparent; + + Planet() + { + dim = speed = dir = 0.0f; + transparent = false; + } }; - - - -class CPlanet { +class CPlanet +{ public: - CPlanet(CInstanceManager* iMan, CEngine* engine); + CPlanet(CInstanceManager* iMan, Gfx::CEngine* engine); ~CPlanet(); + //! Removes all the planets void Flush(); + //! Management of an event bool EventProcess(const Event &event); - bool Create(int mode, Math::Point start, float dim, float speed, float dir, char *name, Math::Point uv1, Math::Point uv2); + //! Creates a new planet + void Create(int mode, Math::Point start, float dim, float speed, float dir, + const std::string& name, Math::Point uv1, Math::Point uv2); + //! Indicates if there is at least one planet bool PlanetExist(); + //! Load all the textures for the planets void LoadTexture(); + //! Draws all the planets void Draw(); + //@{ + //! Choice of mode void SetMode(int mode); - int RetMode(); + int GetMode(); + //@} protected: + //! Makes the planets evolve bool EventFrame(const Event &event); protected: - CInstanceManager* m_iMan; - CEngine* m_engine; + CInstanceManager* m_iMan; + Gfx::CEngine* m_engine; - float m_time; - int m_mode; - Planet m_planet[2][MAXPLANET]; - bool m_bPlanetExist; + float m_time; + int m_mode; + std::vector m_planet[2]; + bool m_planetExist; }; - }; // namespace Gfx From c3ab23ac9dc02d59180f2f1af5f3aa5b50f9f8d8 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Thu, 9 Aug 2012 22:50:04 +0200 Subject: [PATCH 06/10] Graphics stubs - added stubs for functions in CLightning, CParticle and CPyro - cleaned object.h and physics.h headers - created temporary stubs to compile CCamera - other necessary changes to compile successfully --- src/CMakeLists.txt | 2 +- src/common/event.h | 57 +++--- src/graphics/engine/camera.cpp | 81 +++++++-- src/graphics/engine/camera.h | 4 +- src/graphics/engine/cloud.cpp | 8 +- src/graphics/engine/engine.cpp | 129 +++++++++++++- src/graphics/engine/engine.h | 22 ++- src/graphics/engine/lightning.cpp | 68 +++++++- src/graphics/engine/lightning.h | 2 +- src/graphics/engine/particle.cpp | 281 +++++++++++++++++++++++++++++- src/graphics/engine/particle.h | 91 +++++----- src/graphics/engine/pyro.cpp | 158 ++++++++++++++++- src/graphics/engine/pyro.h | 49 +++--- src/graphics/engine/water.cpp | 6 +- src/object/object.h | 220 +++++++++++------------ src/physics/physics.h | 82 ++++----- 16 files changed, 987 insertions(+), 273 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 25a576e4..b998d19c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -67,7 +67,7 @@ common/iman.cpp # common/restext.cpp common/stringutils.cpp graphics/core/color.cpp -# graphics/engine/camera.cpp # new code but depends on other modules +graphics/engine/camera.cpp graphics/engine/cloud.cpp graphics/engine/engine.cpp graphics/engine/lightman.cpp diff --git a/src/common/event.h b/src/common/event.h index 0d9aa7c9..a82282e4 100644 --- a/src/common/event.h +++ b/src/common/event.h @@ -40,9 +40,10 @@ enum EventType EVENT_NULL = 0, //! Event sent on user or system quit request - EVENT_QUIT = 1, + EVENT_QUIT = 1, - //? EVENT_FRAME = 2, + //! Frame update event + EVENT_FRAME = 2, //! Event sent after pressing a mouse button EVENT_MOUSE_BUTTON_DOWN = 3, @@ -669,29 +670,41 @@ struct Event //! If true, the event was produced by system (SDL); else, it has come from user interface bool systemEvent; - //! Additional data for EVENT_KEY_DOWN and EVENT_KEY_UP - KeyEventData key; - //! Additional data for EVENT_MOUSE_BUTTON_DOWN and EVENT_MOUSE_BUTTON_UP - MouseButtonEventData mouseButton; - //! Additional data for EVENT_MOUSE_MOVE - MouseMoveEventData mouseMove; - //! Additional data for EVENT_JOY - JoyAxisEventData joyAxis; - //! Additional data for EVENT_JOY_AXIS - JoyButtonEventData joyButton; - //! Additional data for EVENT_ACTIVE - ActiveEventData active; + union + { + //! Additional data for EVENT_KEY_DOWN and EVENT_KEY_UP + KeyEventData key; + //! Additional data for EVENT_MOUSE_BUTTON_DOWN and EVENT_MOUSE_BUTTON_UP + MouseButtonEventData mouseButton; + //! Additional data for EVENT_MOUSE_MOVE + MouseMoveEventData mouseMove; + //! Additional data for EVENT_JOY + JoyAxisEventData joyAxis; + //! Additional data for EVENT_JOY_AXIS + JoyButtonEventData joyButton; + //! Additional data for EVENT_ACTIVE + ActiveEventData active; + }; - //? long param; // parameter - //? Math::Point pos; // mouse position (0 .. 1) - //? float axeX; // control the X axis (-1 .. 1) - //? float axeY; // control of the Y axis (-1 .. 1) - //? float axeZ; // control the Z axis (-1 .. 1) - //? short keyState; // state of the keyboard (KS_ *) - //? float rTime; // relative time + // TODO: refactor/rewrite + long param; // parameter + Math::Point pos; // mouse position (0 .. 1) + float axeX; // control the X axis (-1 .. 1) + float axeY; // control of the Y axis (-1 .. 1) + float axeZ; // control the Z axis (-1 .. 1) + short keyState; // state of the keyboard (KS_ *) + float rTime; // relative time Event(EventType aType = EVENT_NULL) - : type(aType), systemEvent(false) {} + { + type = aType; + systemEvent = false; + + param = 0; + axeX = axeY = axeZ = 0.0f; + keyState = 0; + rTime = 0.0f; + } }; diff --git a/src/graphics/engine/camera.cpp b/src/graphics/engine/camera.cpp index c7ca5035..2db6398f 100644 --- a/src/graphics/engine/camera.cpp +++ b/src/graphics/engine/camera.cpp @@ -29,6 +29,66 @@ #include "physics/physics.h" +// TODO temporary stubs for CObject and CPhysics + +void CObject::SetTransparency(float) +{ +} + +CObject* CObject::GetFret() +{ + return nullptr; +} + +CObject* CObject::GetPower() +{ + return nullptr; +} + +CObject* CObject::GetTruck() +{ + return nullptr; +} + +ObjectType CObject::GetType() +{ + return OBJECT_NULL; +} + +void CObject::SetGunGoalH(float) +{ +} + +void CObject::GetGlobalSphere(Math::Vector &pos, float &radius) +{ +} + +float CObject::GetAngleY(int) +{ + return 0.0f; +} + +Math::Vector CObject::GetPosition(int) +{ + return Math::Vector(); +} + +void CObject::SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV, + Math::Vector &lookat, Math::Vector &upVec, + Gfx::CameraType type) +{ +} + +CPhysics* CObject::GetPhysics() +{ + return nullptr; +} + +bool CPhysics::GetLand() +{ + return false; +} + //! Changes the level of transparency of an object and objects transported (battery & cargo) void SetTransparency(CObject* obj, float value) { @@ -332,7 +392,7 @@ void Gfx::CCamera::SetType(CameraType type) SetSmooth(Gfx::CAM_SMOOTH_NORM); } -CameraType Gfx::CCamera::GetType() +Gfx::CameraType Gfx::CCamera::GetType() { return m_type; } @@ -342,7 +402,7 @@ void Gfx::CCamera::SetSmooth(CameraSmooth type) m_smooth = type; } -CameraSmooth Gfx::CCamera::GetSmoth() +Gfx::CameraSmooth Gfx::CCamera::GetSmoth() { return m_smooth; } @@ -692,7 +752,7 @@ void Gfx::CCamera::OverFrame(const Event &event) } else { - color = Gfx::Color(0.0f. 0.0f, 0.0f); + color = Gfx::Color(0.0f, 0.0f, 0.0f); } color.a = 0.0f; m_engine->SetOverColor(color, m_overMode); @@ -873,7 +933,7 @@ bool Gfx::CCamera::IsCollisionBack(Math::Vector &eye, Math::Vector lookat) for (int i = 0 ;i < 1000000; i++) { - CObject *obj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + CObject *obj = static_cast( m_iMan->SearchInstance(CLASS_OBJECT, i) ); if (obj == NULL) break; if (obj->GetTruck()) continue; // battery or cargo? @@ -899,7 +959,7 @@ bool Gfx::CCamera::IsCollisionBack(Math::Vector &eye, Math::Vector lookat) iType == OBJECT_SAFE || iType == OBJECT_HUSTON ) continue; - ObjType oType = obj->GetType(); + ObjectType oType = obj->GetType(); if ( oType == OBJECT_HUMAN || oType == OBJECT_TECH || oType == OBJECT_TOTO || @@ -995,7 +1055,6 @@ bool Gfx::CCamera::EventProcess(const Event &event) { switch (event.type) { - // TODO: frame update event case EVENT_FRAME: EventFrame(event); break; @@ -1004,11 +1063,11 @@ bool Gfx::CCamera::EventProcess(const Event &event) EventMouseMove(event); break; - case EVENT_KEY_DOWN: - // TODO: mouse wheel event + // TODO: mouse wheel event + /*case EVENT_KEY_DOWN: if ( event.param == VK_WHEELUP ) EventMouseWheel(+1); if ( event.param == VK_WHEELDOWN ) EventMouseWheel(-1); - break; + break;*/ default: break; @@ -1489,8 +1548,6 @@ bool Gfx::CCamera::EventFrameFix(const Event &event) bool Gfx::CCamera::EventFrameExplo(const Event &event) { - float factor = m_heightEye * 0.5f + 30.0f; - if (m_mouseDirH != 0.0f) m_directionH -= m_mouseDirH * event.rTime * 0.7f * m_speed; @@ -1526,7 +1583,7 @@ bool Gfx::CCamera::EventFrameOnBoard(const Event &event) { Math::Vector lookatPt, upVec; m_cameraObj->SetViewFromHere(m_eyePt, m_directionH, m_directionV, - lookatPt, vUpVec, m_type); + lookatPt, upVec, m_type); Math::Vector eye = m_effectOffset * 0.3f + m_eyePt; Math::Vector lookat = m_effectOffset * 0.3f + lookatPt; diff --git a/src/graphics/engine/camera.h b/src/graphics/engine/camera.h index 935f8b01..ec6afcb2 100644 --- a/src/graphics/engine/camera.h +++ b/src/graphics/engine/camera.h @@ -353,13 +353,13 @@ protected: float m_centeringTime; float m_centeringProgress; - CameraEffect m_effectType; + Gfx::CameraEffect m_effectType; Math::Vector m_effectPos; float m_effectForce; float m_effectProgress; Math::Vector m_effectOffset; - OverEffect m_overType; + Gfx::CameraOverEffect m_overType; float m_overForce; float m_overTime; Gfx::Color m_overColorBase; diff --git a/src/graphics/engine/cloud.cpp b/src/graphics/engine/cloud.cpp index e46b0742..71dd9690 100644 --- a/src/graphics/engine/cloud.cpp +++ b/src/graphics/engine/cloud.cpp @@ -55,16 +55,14 @@ Gfx::CCloud::~CCloud() bool Gfx::CCloud::EventProcess(const Event &event) { - /* TODO! - if ( event.event == EVENT_FRAME ) - return EventFrame(event); */ + if ( event.type == EVENT_FRAME ) + return EventFrame(event); return true; } bool Gfx::CCloud::EventFrame(const Event &event) { - /* TODO! if (m_engine->GetPause()) return true; m_time += event.rTime; @@ -73,7 +71,7 @@ bool Gfx::CCloud::EventFrame(const Event &event) if (m_time - m_lastTest < 0.2f) return true; - m_lastTest = m_time; */ + m_lastTest = m_time; return true; } diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 4bf80d27..c8fa05ca 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -25,8 +25,16 @@ #include "common/key.h" #include "common/logger.h" #include "graphics/core/device.h" +#include "graphics/engine/camera.h" +#include "graphics/engine/cloud.h" #include "graphics/engine/lightman.h" +#include "graphics/engine/lightning.h" +#include "graphics/engine/particle.h" +#include "graphics/engine/planet.h" +#include "graphics/engine/pyro.h" +#include "graphics/engine/terrain.h" #include "graphics/engine/text.h" +#include "graphics/engine/water.h" #include "math/geometry.h" // Initial size of various vectors @@ -207,12 +215,11 @@ bool Gfx::CEngine::Create() 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_planet = new Gfx::CPlanet(m_iMan, this); m_text->SetDevice(m_device); if (! m_text->Create()) @@ -250,7 +257,6 @@ void Gfx::CEngine::Destroy() delete m_text; m_text = nullptr; - /* TODO: delete m_particle; m_particle = nullptr; @@ -264,7 +270,7 @@ void Gfx::CEngine::Destroy() m_lightning = nullptr; delete m_planet; - m_planet = nullptr;*/ + m_planet = nullptr; } void Gfx::CEngine::ResetAfterDeviceChanged() @@ -807,3 +813,118 @@ bool Gfx::CEngine::GetShowStat() return m_showStats; } +void Gfx::CEngine::SetFocus(float focus) +{ + m_focus = focus; +} + + +void Gfx::CEngine::SetOverColor(const Gfx::Color& color, int mode) +{ + // TODO! +} + +void Gfx::CEngine::SetFogColor(const Gfx::Color& color, int rank) +{ + // TODO! +} + +Gfx::Color Gfx::CEngine::GetFogColor(int rank) +{ + // TODO! + return Gfx::Color(); +} + +void Gfx::CEngine::SetViewParams(const Math::Vector& eyePt, const Math::Vector& lookatPt, + const Math::Vector& upVec, float eyeDistance) +{ + // TODO! +} + +void Gfx::CEngine::SetRankView(int rank) +{ + m_rankView = rank; +} + +float Gfx::CEngine::GetEyeDirH() +{ + return m_eyeDirH; +} + +float Gfx::CEngine::GetEyeDirV() +{ + return m_eyeDirV; +} + +float Gfx::CEngine::GetClippingDistance() +{ + return m_clippingDistance; +} + +bool Gfx::CEngine::GetGroundSpot() +{ + return m_groundSpotVisible; +} + +void Gfx::CEngine::SetTerrain(Gfx::CTerrain* terrain) +{ + m_terrain = terrain; +} + +void Gfx::CEngine::SetTerrainVision(float vision) +{ + // TODO! +} + +bool Gfx::CEngine::LoadTexture(const std::string& name, int stage) +{ + // TODO! + return true; +} + +float Gfx::CEngine::ParticleAdapt(float factor) +{ + // TODO! + return 0.0f; +} + +bool Gfx::CEngine::SetObjectType(int objRank, Gfx::EngineObjectType type) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetObjectTransform(int objRank, const Math::Matrix& transform) +{ + // TODO! + return true; +} + +int Gfx::CEngine::CreateObject() +{ + // TODO! + return 0; +} + +bool Gfx::CEngine::DeleteObject(int objRank) +{ + // TODO! + return true; +} + +int Gfx::CEngine::GroundMarkCreate(Math::Vector pos, float radius, float delay1, float delay2, float delay3, int dx, int dy, char* table) +{ + // TODO! + return 0; +} + +bool Gfx::CEngine::AddQuick(int objRank, const Gfx::EngineObjLevel5& buffer, std::string texName1, std::string texName2, float min, float max, bool globalUpdate) +{ + // TODO! + return false; +} + +void Gfx::CEngine::Update() +{ + // TODO! +} diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index cd89a1cf..e61aca65 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -170,7 +170,10 @@ struct EngineObjLevel5 Gfx::EngineTriangleType type; std::vector vertices; - EngineObjLevel5(); + EngineObjLevel5() + { + state = 0; + } }; /** @@ -182,7 +185,10 @@ struct EngineObjLevel4 std::vector up; Gfx::EngineObjLevel3* down; - EngineObjLevel4(); + EngineObjLevel4() + { + reserved = 0; + } }; /** @@ -195,7 +201,10 @@ struct EngineObjLevel3 std::vector up; Gfx::EngineObjLevel2* down; - EngineObjLevel3(); + EngineObjLevel3() + { + min = max = 0.0f; + } }; /** @@ -207,7 +216,10 @@ struct EngineObjLevel2 std::vector up; Gfx::EngineObjLevel1* down; - EngineObjLevel2(); + EngineObjLevel2() + { + objRank = 0; + } }; /** @@ -219,7 +231,7 @@ struct EngineObjLevel1 Gfx::Texture tex2; std::vector up; - EngineObjLevel1(); + EngineObjLevel1() {} }; /** diff --git a/src/graphics/engine/lightning.cpp b/src/graphics/engine/lightning.cpp index 4db5511a..4ecdb3c4 100644 --- a/src/graphics/engine/lightning.cpp +++ b/src/graphics/engine/lightning.cpp @@ -19,5 +19,71 @@ #include "graphics/engine/lightning.h" +#include "common/logger.h" -// TODO implementation + +Gfx::CLightning::CLightning(CInstanceManager* iMan, Gfx::CEngine* engine) +{ + GetLogger()->Info("CLightning::CLightning() stub!\n"); + // TODO! +} + +Gfx::CLightning::~CLightning() +{ + GetLogger()->Info("CLightning::~CLightning() stub!\n"); + // TODO! +} + +void Gfx::CLightning::Flush() +{ + GetLogger()->Info("CLightning::Flush() stub!\n"); + // TODO! +} + +bool Gfx::CLightning::EventProcess(const Event &event) +{ + GetLogger()->Info("CLightning::EventProcess() stub!\n"); + // TODO! + return true; +} + +bool Gfx::CLightning::Create(float sleep, float delay, float magnetic) +{ + GetLogger()->Info("CLightning::Create() stub!\n"); + // TODO! + return true; +} + +bool Gfx::CLightning::GetStatus(float &sleep, float &delay, float &magnetic, float &progress) +{ + GetLogger()->Info("CLightning::GetStatus() stub!\n"); + // TODO! + return true; +} + +bool Gfx::CLightning::SetStatus(float sleep, float delay, float magnetic, float progress) +{ + GetLogger()->Info("CLightning::SetStatus() stub!\n"); + // TODO! + return true; +} + +void Gfx::CLightning::Draw() +{ + GetLogger()->Info("CLightning::Draw() stub!\n"); + // TODO! +} + +bool Gfx::CLightning::EventFrame(const Event &event) +{ + GetLogger()->Info("CLightning::EventFrame() stub!\n"); + // TODO! + return true; +} + +CObject* Gfx::CLightning::SearchObject(Math::Vector pos) +{ + GetLogger()->Info("CLightning::SearchObject() stub!\n"); + // TODO! + return nullptr; +} diff --git a/src/graphics/engine/lightning.h b/src/graphics/engine/lightning.h index 957344c1..9e854be8 100644 --- a/src/graphics/engine/lightning.h +++ b/src/graphics/engine/lightning.h @@ -73,7 +73,7 @@ protected: float m_sleep; float m_delay; float m_magnetic; - BlitzPhase m_phase; + Gfx::BlitzPhase m_phase; float m_time; float m_speed; float m_progress; diff --git a/src/graphics/engine/particle.cpp b/src/graphics/engine/particle.cpp index 84e2f9d7..9a21fe04 100644 --- a/src/graphics/engine/particle.cpp +++ b/src/graphics/engine/particle.cpp @@ -19,5 +19,284 @@ #include "graphics/engine/particle.h" +#include "common/logger.h" -// TODO implementation + +Gfx::CParticle::CParticle(CInstanceManager* iMan, Gfx::CEngine* engine) +{ + GetLogger()->Info("CParticle::CParticle() stub!\n"); + // TODO! +} + +Gfx::CParticle::~CParticle() +{ + GetLogger()->Info("CParticle::~CParticle() stub!\n"); + // TODO! +} + +void Gfx::CParticle::SetDevice(Gfx::CDevice* device) +{ + GetLogger()->Info("CParticle::SetDevice() stub!\n"); + // TODO! +} + +void Gfx::CParticle::FlushParticle() +{ + GetLogger()->Info("CParticle::FlushParticle() stub!\n"); + // TODO! +} + +void Gfx::CParticle::FlushParticle(int sheet) +{ + GetLogger()->Info("CParticle::FlushParticle() stub!\n"); + // TODO! +} + +int Gfx::CParticle::CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point dim, + Gfx::ParticleType type, float duration, float mass, + float windSensitivity, int sheet) +{ + GetLogger()->Info("CParticle::CreateParticle() stub!\n"); + // TODO! + return 0; +} + +int Gfx::CParticle::CreateFrag(Math::Vector pos, Math::Vector speed, Gfx::EngineTriangle *triangle, + Gfx::ParticleType type, float duration, float mass, + float windSensitivity, int sheet) +{ + GetLogger()->Info("CParticle::CreateFrag() stub!\n"); + // TODO! + return 0; +} + +int Gfx::CParticle::CreatePart(Math::Vector pos, Math::Vector speed, Gfx::ParticleType type, + float duration, float mass, float weight, + float windSensitivity, int sheet) +{ + GetLogger()->Info("CParticle::CreatePart() stub!\n"); + // TODO! + return 0; +} + +int Gfx::CParticle::CreateRay(Math::Vector pos, Math::Vector goal, Gfx::ParticleType type, Math::Point dim, + float duration, int sheet) +{ + GetLogger()->Info("CParticle::CreateRay() stub!\n"); + // TODO! + return 0; +} + +int Gfx::CParticle::CreateTrack(Math::Vector pos, Math::Vector speed, Math::Point dim, Gfx::ParticleType type, + float duration, float mass, float length, float width) +{ + GetLogger()->Info("CParticle::CreateTrack() stub!\n"); + // TODO! + return 0; +} + +void Gfx::CParticle::CreateWheelTrace(const Math::Vector &p1, const Math::Vector &p2, const Math::Vector &p3, + const Math::Vector &p4, Gfx::ParticleType type) +{ + GetLogger()->Info("CParticle::CreateWheelTrace() stub!\n"); + // TODO! +} + +void Gfx::CParticle::DeleteParticle(Gfx::ParticleType type) +{ + GetLogger()->Info("CParticle::DeleteParticle() stub!\n"); + // TODO! +} + +void Gfx::CParticle::DeleteParticle(int channel) +{ + GetLogger()->Info("CParticle::DeleteParticle() stub!\n"); + // TODO! +} + +void Gfx::CParticle::SetObjectLink(int channel, CObject *object) +{ + GetLogger()->Info("CParticle::SetObjectLink() stub!\n"); + // TODO! +} + +void Gfx::CParticle::SetObjectFather(int channel, CObject *object) +{ + GetLogger()->Info("CParticle::SetObjectFather() stub!\n"); + // TODO! +} + +void Gfx::CParticle::SetPosition(int channel, Math::Vector pos) +{ + GetLogger()->Info("CParticle::SetPosition() stub!\n"); + // TODO! +} + +void Gfx::CParticle::SetDimension(int channel, Math::Point dim) +{ + GetLogger()->Info("CParticle::SetDimension() stub!\n"); + // TODO! +} + +void Gfx::CParticle::SetZoom(int channel, float zoom) +{ + GetLogger()->Info("CParticle::SetZoom() stub!\n"); + // TODO! +} + +void Gfx::CParticle::SetAngle(int channel, float angle) +{ + GetLogger()->Info("CParticle::SetAngle() stub!\n"); + // TODO! +} + +void Gfx::CParticle::SetIntensity(int channel, float intensity) +{ + GetLogger()->Info("CParticle::SetIntensity() stub!\n"); + // TODO! +} + +void Gfx::CParticle::SetParam(int channel, Math::Vector pos, Math::Point dim, float zoom, float angle, float intensity) +{ + GetLogger()->Info("CParticle::SetParam() stub!\n"); + // TODO! +} + +void Gfx::CParticle::SetPhase(int channel, Gfx::ParticlePhase phase, float duration) +{ + GetLogger()->Info("CParticle::SetPhase() stub!\n"); + // TODO! +} + +bool Gfx::CParticle::GetPosition(int channel, Math::Vector &pos) +{ + GetLogger()->Info("CParticle::GetPosition() stub!\n"); + // TODO! + return true; +} + +Gfx::Color Gfx::CParticle::GetFogColor(Math::Vector pos) +{ + GetLogger()->Info("CParticle::GetFogColor() stub!\n"); + // TODO! + return Gfx::Color(); +} + +void Gfx::CParticle::SetFrameUpdate(int sheet, bool update) +{ + GetLogger()->Info("CParticle::SetFrameUpdate() stub!\n"); + // TODO! +} + +void Gfx::CParticle::FrameParticle(float rTime) +{ + GetLogger()->Info("CParticle::FrameParticle() stub!\n"); + // TODO! +} + +void Gfx::CParticle::DrawParticle(int sheet) +{ + GetLogger()->Info("CParticle::DrawParticle() stub!\n"); + // TODO! +} + +bool Gfx::CParticle::WriteWheelTrace(char *filename, int width, int height, Math::Vector dl, Math::Vector ur) +{ + GetLogger()->Info("CParticle::WriteWheelTrace() stub!\n"); + // TODO! + return true; +} + +void Gfx::CParticle::DeleteRank(int rank) +{ + GetLogger()->Info("CParticle::DeleteRank() stub!\n"); + // TODO! +} + +bool Gfx::CParticle::CheckChannel(int &channel) +{ + GetLogger()->Info("CParticle::CheckChannel() stub!\n"); + // TODO! + return true; +} + +void Gfx::CParticle::DrawParticleTriangle(int i) +{ + GetLogger()->Info("CParticle::DrawParticleTriangle() stub!\n"); + // TODO! +} + +void Gfx::CParticle::DrawParticleNorm(int i) +{ + GetLogger()->Info("CParticle::DrawParticleNorm() stub!\n"); + // TODO! +} + +void Gfx::CParticle::DrawParticleFlat(int i) +{ + GetLogger()->Info("CParticle::DrawParticleFlat() stub!\n"); + // TODO! +} + +void Gfx::CParticle::DrawParticleFog(int i) +{ + GetLogger()->Info("CParticle::DrawParticleFog() stub!\n"); + // TODO! +} + +void Gfx::CParticle::DrawParticleRay(int i) +{ + GetLogger()->Info("CParticle::DrawParticleRay() stub!\n"); + // TODO! +} + +void Gfx::CParticle::DrawParticleSphere(int i) +{ + GetLogger()->Info("CParticle::DrawParticleSphere() stub!\n"); + // TODO! +} + +void Gfx::CParticle::DrawParticleCylinder(int i) +{ + GetLogger()->Info("CParticle::DrawParticleCylinder() stub!\n"); + // TODO! +} + +void Gfx::CParticle::DrawParticleWheel(int i) +{ + GetLogger()->Info("CParticle::DrawParticleWheel() stub!\n"); + // TODO! +} + +CObject* Gfx::CParticle::SearchObjectGun(Math::Vector old, Math::Vector pos, Gfx::ParticleType type, CObject *father) +{ + GetLogger()->Info("CParticle::SearchObjectGun() stub!\n"); + // TODO! + return nullptr; +} + +CObject* Gfx::CParticle::SearchObjectRay(Math::Vector pos, Math::Vector goal, Gfx::ParticleType type, CObject *father) +{ + GetLogger()->Info("CParticle::SearchObjectRay() stub!\n"); + // TODO! + return nullptr; +} + +void Gfx::CParticle::Play(Sound sound, Math::Vector pos, float amplitude) +{ + GetLogger()->Info("CParticle::Play() stub!\n"); + // TODO! +} + +bool Gfx::CParticle::TrackMove(int i, Math::Vector pos, float progress) +{ + GetLogger()->Info("CParticle::TrackMove() stub!\n"); + // TODO! + return true; +} + +void Gfx::CParticle::TrackDraw(int i, Gfx::ParticleType type) +{ + GetLogger()->Info("CParticle::TrackDraw() stub!\n"); + // TODO! +} diff --git a/src/graphics/engine/particle.h b/src/graphics/engine/particle.h index 94aacfc7..89e2c5be 100644 --- a/src/graphics/engine/particle.h +++ b/src/graphics/engine/particle.h @@ -202,26 +202,26 @@ enum ParticlePhase struct Particle { - char bUsed; // TRUE -> particle used - char bRay; // TRUE -> ray with goal - unsigned short uniqueStamp; // unique mark + char used; // TRUE -> particle used + char ray; // TRUE -> ray with goal + unsigned short uniqueStamp; // unique mark short sheet; // sheet (0..n) - ParticleType type; // type PARTI* - ParticlePhase phase; // phase PARPH* + ParticleType type; // type PARTI* + ParticlePhase phase; // phase PARPH* float mass; // mass of the particle (in rebounding) float weight; // weight of the particle (for noise) float duration; // length of life - Math::Vector pos; // absolute position (relative if object links) - Math::Vector goal; // goal position (if bRay) - Math::Vector speed; // speed of displacement + Math::Vector pos; // absolute position (relative if object links) + Math::Vector goal; // goal position (if ray) + Math::Vector speed; // speed of displacement float windSensitivity; short bounce; // number of rebounds - Math::Point dim; // dimensions of the rectangle + Math::Point dim; // dimensions of the rectangle float zoom; // zoom (0..1) float angle; // angle of rotation float intensity; // intensity - Math::Point texSup; // coordinated upper texture - Math::Point texInf; // coordinated lower texture + Math::Point texSup; // coordinated upper texture + Math::Point texInf; // coordinated lower texture float time; // age of the particle (0..n) float phaseTime; // age at the beginning of phase float testTime; // time since last test @@ -233,22 +233,22 @@ struct Particle struct Track { - char bUsed; // TRUE -> drag used - char bDrawParticle; + char used; // TRUE -> drag used + char drawParticle; float step; // duration of not float last; // increase last not memorized float intensity; // intensity at starting (0..1) float width; // tail width - int used; // number of positions in "pos" - int head; // head to write index - Math::Vector pos[MAXTRACKLEN]; + int posUsed; // number of positions in "pos" + int head; // head to write index + Math::Vector pos[MAXTRACKLEN]; float len[MAXTRACKLEN]; }; struct WheelTrace { - ParticleType type; // type PARTI* - Math::Vector pos[4]; // rectangle positions + ParticleType type; // type PARTI* + Math::Vector pos[4]; // rectangle positions float startTime; // beginning of life }; @@ -257,20 +257,29 @@ struct WheelTrace class CParticle { public: - CParticle(CInstanceManager* iMan, CEngine* engine); + CParticle(CInstanceManager* iMan, Gfx::CEngine* engine); ~CParticle(); - void SetDevice(CDevice* device); + void SetDevice(Gfx::CDevice* device); void FlushParticle(); void FlushParticle(int sheet); - int CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point dim, ParticleType type, float duration=1.0f, float mass=0.0f, float windSensitivity=1.0f, int sheet=0); - int CreateFrag(Math::Vector pos, Math::Vector speed, Gfx::EngineTriangle *triangle, ParticleType type, float duration=1.0f, float mass=0.0f, float windSensitivity=1.0f, int sheet=0); - int CreatePart(Math::Vector pos, Math::Vector speed, ParticleType type, float duration=1.0f, float mass=0.0f, float weight=0.0f, float windSensitivity=1.0f, int sheet=0); - int CreateRay(Math::Vector pos, Math::Vector goal, ParticleType type, Math::Point dim, float duration=1.0f, int sheet=0); - int CreateTrack(Math::Vector pos, Math::Vector speed, Math::Point dim, ParticleType type, float duration=1.0f, float mass=0.0f, float length=10.0f, float width=1.0f); - void CreateWheelTrace(const Math::Vector &p1, const Math::Vector &p2, const Math::Vector &p3, const Math::Vector &p4, ParticleType type); - void DeleteParticle(ParticleType type); + int CreateParticle(Math::Vector pos, Math::Vector speed, Math::Point dim, + Gfx::ParticleType type, float duration=1.0f, float mass=0.0f, + float windSensitivity=1.0f, int sheet=0); + int CreateFrag(Math::Vector pos, Math::Vector speed, Gfx::EngineTriangle *triangle, + Gfx::ParticleType type, float duration=1.0f, float mass=0.0f, + float windSensitivity=1.0f, int sheet=0); + int CreatePart(Math::Vector pos, Math::Vector speed, Gfx::ParticleType type, + float duration=1.0f, float mass=0.0f, float weight=0.0f, + float windSensitivity=1.0f, int sheet=0); + int CreateRay(Math::Vector pos, Math::Vector goal, Gfx::ParticleType type, Math::Point dim, + float duration=1.0f, int sheet=0); + int CreateTrack(Math::Vector pos, Math::Vector speed, Math::Point dim, Gfx::ParticleType type, + float duration=1.0f, float mass=0.0f, float length=10.0f, float width=1.0f); + void CreateWheelTrace(const Math::Vector &p1, const Math::Vector &p2, const Math::Vector &p3, + const Math::Vector &p4, Gfx::ParticleType type); + void DeleteParticle(Gfx::ParticleType type); void DeleteParticle(int channel); void SetObjectLink(int channel, CObject *object); void SetObjectFather(int channel, CObject *object); @@ -280,12 +289,12 @@ public: void SetAngle(int channel, float angle); void SetIntensity(int channel, float intensity); void SetParam(int channel, Math::Vector pos, Math::Point dim, float zoom, float angle, float intensity); - void SetPhase(int channel, ParticlePhase phase, float duration); + void SetPhase(int channel, Gfx::ParticlePhase phase, float duration); bool GetPosition(int channel, Math::Vector &pos); Gfx::Color GetFogColor(Math::Vector pos); - void SetFrameUpdate(int sheet, bool bUpdate); + void SetFrameUpdate(int sheet, bool update); void FrameParticle(float rTime); void DrawParticle(int sheet); @@ -302,29 +311,29 @@ protected: void DrawParticleSphere(int i); void DrawParticleCylinder(int i); void DrawParticleWheel(int i); - CObject* SearchObjectGun(Math::Vector old, Math::Vector pos, ParticleType type, CObject *father); - CObject* SearchObjectRay(Math::Vector pos, Math::Vector goal, ParticleType type, CObject *father); + CObject* SearchObjectGun(Math::Vector old, Math::Vector pos, Gfx::ParticleType type, CObject *father); + CObject* SearchObjectRay(Math::Vector pos, Math::Vector goal, Gfx::ParticleType type, CObject *father); void Play(Sound sound, Math::Vector pos, float amplitude); bool TrackMove(int i, Math::Vector pos, float progress); - void TrackDraw(int i, ParticleType type); + void TrackDraw(int i, Gfx::ParticleType type); protected: CInstanceManager* m_iMan; - CEngine* m_engine; - CDevice* m_device; - CRobotMain* m_main; - CTerrain* m_terrain; - CWater* m_water; - CSound* m_sound; + Gfx::CEngine* m_engine; + Gfx::CDevice* m_device; + Gfx::CTerrain* m_terrain; + Gfx::CWater* m_water; + CRobotMain* m_main; + CSound* m_sound; Gfx::Particle m_particule[MAXPARTICULE*MAXPARTITYPE]; Gfx::EngineTriangle m_triangle[MAXPARTICULE]; // triangle if PartiType == 0 - Track m_track[MAXTRACK]; + Gfx::Track m_track[MAXTRACK]; int m_wheelTraceTotal; int m_wheelTraceIndex; - WheelTrace m_wheelTrace[MAXWHEELTRACE]; + Gfx::WheelTrace m_wheelTrace[MAXWHEELTRACE]; int m_totalInterface[MAXPARTITYPE][SH_MAX]; - bool m_bFrameUpdate[SH_MAX]; + bool m_frameUpdate[SH_MAX]; int m_fogTotal; int m_fog[MAXPARTIFOG]; int m_uniqueStamp; diff --git a/src/graphics/engine/pyro.cpp b/src/graphics/engine/pyro.cpp index e699db2a..327befa5 100644 --- a/src/graphics/engine/pyro.cpp +++ b/src/graphics/engine/pyro.cpp @@ -19,5 +19,161 @@ #include "graphics/engine/pyro.h" +#include "common/logger.h" -// TODO implementation + +Gfx::CPyro::CPyro(CInstanceManager* iMan) +{ + GetLogger()->Info("CParticle::CPyro() stub!\n"); + // TODO! +} + +Gfx::CPyro::~CPyro() +{ + GetLogger()->Info("CPyro::~CPyro() stub!"); + // TODO! +} + +void Gfx::CPyro::DeleteObject(bool all) +{ + GetLogger()->Info("CPyro::DeleteObject() stub!"); + // TODO! +} + +bool Gfx::CPyro::Create(Gfx::PyroType type, CObject* pObj, float force) +{ + GetLogger()->Info("CPyro::Create() stub!"); + // TODO! + return true; +} + +bool Gfx::CPyro::EventProcess(const Event &event) +{ + GetLogger()->Info("CPyro::EventProcess() stub!\n"); + // TODO! + return true; +} + +Error Gfx::CPyro::IsEnded() +{ + GetLogger()->Info("CPyro::IsEnded() stub!\n"); + // TODO! + return ERR_OK; +} + +void Gfx::CPyro::CutObjectLink(CObject* pObj) +{ + GetLogger()->Info("CPyro::CutObjectLink() stub!\n"); + // TODO! +} + +void Gfx::CPyro::DisplayError(PyroType type, CObject* pObj) +{ + GetLogger()->Info("CPyro::DisplayError() stub!\n"); + // TODO! +} + +bool Gfx::CPyro::CreateLight(Math::Vector pos, float height) +{ + GetLogger()->Info("CPyro::CreateLight() stub!\n"); + // TODO! + return true; +} + +void Gfx::CPyro::DeleteObject(bool primary, bool secondary) +{ + GetLogger()->Info("CPyro::DeleteObject() stub!\n"); + // TODO! +} + +void Gfx::CPyro::CreateTriangle(CObject* pObj, ObjectType oType, int part) +{ + GetLogger()->Info("CPyro::CreateTriangle() stub!\n"); + // TODO! +} + +void Gfx::CPyro::ExploStart() +{ + GetLogger()->Info("CPyro::ExploStart() stub!\n"); + // TODO! +} +void Gfx::CPyro::ExploTerminate() +{ + GetLogger()->Info("CPyro::ExploTerminate() stub!\n"); + // TODO! +} + +void Gfx::CPyro::BurnStart() +{ + GetLogger()->Info("CPyro::BurnStart() stub!\n"); + // TODO! +} + +void Gfx::CPyro::BurnAddPart(int part, Math::Vector pos, Math::Vector angle) +{ + GetLogger()->Info("CPyro::BurnAddPart() stub!\n"); + // TODO! +} + +void Gfx::CPyro::BurnProgress() +{ + GetLogger()->Info("CPyro::BurnProgress() stub!\n"); + // TODO! +} + +bool Gfx::CPyro::BurnIsKeepPart(int part) +{ + GetLogger()->Info("CPyro::BurnIsKeepPart() stub!\n"); + // TODO! + return true; +} + +void Gfx::CPyro::BurnTerminate() +{ + GetLogger()->Info("CPyro::BurnTerminate() stub!\n"); + // TODO! +} + +void Gfx::CPyro::FallStart() +{ + GetLogger()->Info("CPyro::FallStart() stub!\n"); + // TODO! +} + +CObject* Gfx::CPyro::FallSearchBeeExplo() +{ + GetLogger()->Info("CPyro::FallSearchBeeExplo() stub!\n"); + // TODO! + return nullptr; +} + +void Gfx::CPyro::FallProgress(float rTime) +{ + GetLogger()->Info("CPyro::FallProgress() stub!\n"); + // TODO! +} + +Error Gfx::CPyro::FallIsEnded() +{ + GetLogger()->Info("CPyro::FallIsEnded() stub!\n"); + // TODO! + return ERR_OK; +} + +void Gfx::CPyro::LightOperFlush() +{ + GetLogger()->Info("CPyro::LightOperFlush() stub!\n"); + // TODO! +} + +void Gfx::CPyro::LightOperAdd(float progress, float intensity, float r, float g, float b) +{ + GetLogger()->Info("CPyro::LightOperAdd() stub!\n"); + // TODO! +} + +void Gfx::CPyro::LightOperFrame(float rTime) +{ + GetLogger()->Info("CPyro::LightOperFrame() stub!\n"); + // TODO! +} diff --git a/src/graphics/engine/pyro.h b/src/graphics/engine/pyro.h index d663ca58..35b5c5ff 100644 --- a/src/graphics/engine/pyro.h +++ b/src/graphics/engine/pyro.h @@ -21,9 +21,7 @@ #include "common/misc.h" #include "graphics/engine/engine.h" -//#include "object/object.h" -// TEMPORARILY! -enum ObjectType {}; +#include "object/object.h" class CInstanceManager; @@ -90,13 +88,14 @@ struct PyroLightOper -class CPyro { +class CPyro +{ public: CPyro(CInstanceManager* iMan); ~CPyro(); - void DeleteObject(bool bAll=false); - bool Create(PyroType type, CObject* pObj, float force=1.0f); + void DeleteObject(bool all=false); + bool Create(Gfx::PyroType type, CObject* pObj, float force=1.0f); bool EventProcess(const Event &event); Error IsEnded(); void CutObjectLink(CObject* pObj); @@ -104,7 +103,7 @@ public: protected: void DisplayError(PyroType type, CObject* pObj); bool CreateLight(Math::Vector pos, float height); - void DeleteObject(bool bPrimary, bool bSecondary); + void DeleteObject(bool primary, bool secondary); void CreateTriangle(CObject* pObj, ObjectType oType, int part); @@ -127,21 +126,21 @@ protected: void LightOperFrame(float rTime); protected: - CInstanceManager* m_iMan; - CEngine* m_engine; - CTerrain* m_terrain; - CCamera* m_camera; - CParticle* m_particule; - CLight* m_light; - CObject* m_object; - CDisplayText* m_displayText; - CRobotMain* m_main; - CSound* m_sound; + CInstanceManager* m_iMan; + Gfx::CEngine* m_engine; + Gfx::CTerrain* m_terrain; + Gfx::CCamera* m_camera; + Gfx::CParticle* m_particule; + Gfx::CLightManager* m_lightMan; + CObject* m_object; + CDisplayText* m_displayText; + CRobotMain* m_main; + CSound* m_sound; - Math::Vector m_pos; // center of the effect - Math::Vector m_posPower; // center of the battery - bool m_bPower; // battery exists? - PyroType m_type; + Math::Vector m_pos; // center of the effect + Math::Vector m_posPower; // center of the battery + bool m_power; // battery exists? + Gfx::PyroType m_type; float m_force; float m_size; float m_progress; @@ -153,22 +152,22 @@ protected: int m_lightRank; int m_lightOperTotal; - PyroLightOper m_lightOper[10]; + Gfx::PyroLightOper m_lightOper[10]; float m_lightHeight; ObjectType m_burnType; int m_burnPartTotal; - PyroBurnPart m_burnPart[10]; + Gfx::PyroBurnPart m_burnPart[10]; int m_burnKeepPart[10]; float m_burnFall; float m_fallFloor; float m_fallSpeed; float m_fallBulletTime; - bool m_bFallEnding; + bool m_fallEnding; int m_crashSphereUsed; // number of spheres used - Math::Vector m_crashSpherePos[50]; + Math::Vector m_crashSpherePos[50]; float m_crashSphereRadius[50]; }; diff --git a/src/graphics/engine/water.cpp b/src/graphics/engine/water.cpp index 1f116717..0ec52ebf 100644 --- a/src/graphics/engine/water.cpp +++ b/src/graphics/engine/water.cpp @@ -66,16 +66,14 @@ Gfx::CWater::~CWater() bool Gfx::CWater::EventProcess(const Event &event) { - /* TODO! if (event.type == EVENT_FRAME) return EventFrame(event); -*/ + return true; } bool Gfx::CWater::EventFrame(const Event &event) { - /* TODO! if (m_engine->GetPause()) return true; m_time += event.rTime; @@ -83,7 +81,7 @@ bool Gfx::CWater::EventFrame(const Event &event) if (m_type[0] == WATER_NULL) return true; if (m_lava) - LavaFrame(event.rTime);*/ + LavaFrame(event.rTime); return true; } diff --git a/src/object/object.h b/src/object/object.h index 75283d67..38254120 100644 --- a/src/object/object.h +++ b/src/object/object.h @@ -19,9 +19,9 @@ #pragma once -#include "old/d3dengine.h" -#include "old/camera.h" -#include "old/sound.h" +#include "graphics/engine/engine.h" +#include "graphics/engine/camera.h" +#include "sound/sound.h" class CInstanceManager; @@ -377,16 +377,16 @@ public: int CreatePart(); void DeletePart(int part); void SetObjectRank(int part, int objRank); - int RetObjectRank(int part); + int GetObjectRank(int part); void SetObjectParent(int part, int parent); void SetType(ObjectType type); - ObjectType RetType(); - char* RetName(); + ObjectType GetType(); + char* GetName(); void SetOption(int option); - int RetOption(); + int GetOption(); void SetID(int id); - int RetID(); + int GetID(); bool Write(char *line); bool Read(char *line); @@ -413,203 +413,205 @@ public: bool WriteProgram(int rank, char* filename); bool RunProgram(int rank); - int RetShadowLight(); - int RetEffectLight(); + int GetShadowLight(); + int GetEffectLight(); void FlushCrashShere(); int CreateCrashSphere(Math::Vector pos, float radius, Sound sound, float hardness=0.45f); - int RetCrashSphereTotal(); + int GetCrashSphereTotal(); bool GetCrashSphere(int rank, Math::Vector &pos, float &radius); - float RetCrashSphereHardness(int rank); - Sound RetCrashSphereSound(int rank); + float GetCrashSphereHardness(int rank); + Sound GetCrashSphereSound(int rank); void DeleteCrashSphere(int rank); void SetGlobalSphere(Math::Vector pos, float radius); void GetGlobalSphere(Math::Vector &pos, float &radius); void SetJotlerSphere(Math::Vector pos, float radius); void GetJotlerSphere(Math::Vector &pos, float &radius); void SetShieldRadius(float radius); - float RetShieldRadius(); + float GetShieldRadius(); void SetFloorHeight(float height); void FloorAdjust(); void SetLinVibration(Math::Vector dir); - Math::Vector RetLinVibration(); + Math::Vector GetLinVibration(); void SetCirVibration(Math::Vector dir); - Math::Vector RetCirVibration(); + Math::Vector GetCirVibration(); void SetInclinaison(Math::Vector dir); - Math::Vector RetInclinaison(); + Math::Vector GetInclinaison(); void SetPosition(int part, const Math::Vector &pos); - Math::Vector RetPosition(int part); + Math::Vector GetPosition(int part); void SetAngle(int part, const Math::Vector &angle); - Math::Vector RetAngle(int part); + Math::Vector GetAngle(int part); void SetAngleY(int part, float angle); void SetAngleX(int part, float angle); void SetAngleZ(int part, float angle); - float RetAngleY(int part); - float RetAngleX(int part); - float RetAngleZ(int part); + float GetAngleY(int part); + float GetAngleX(int part); + float GetAngleZ(int part); void SetZoom(int part, float zoom); void SetZoom(int part, Math::Vector zoom); - Math::Vector RetZoom(int part); + Math::Vector GetZoom(int part); void SetZoomX(int part, float zoom); - float RetZoomX(int part); + float GetZoomX(int part); void SetZoomY(int part, float zoom); - float RetZoomY(int part); + float GetZoomY(int part); void SetZoomZ(int part, float zoom); - float RetZoomZ(int part); + float GetZoomZ(int part); - float RetWaterLevel(); + float GetWaterLevel(); void SetTrainer(bool bEnable); - bool RetTrainer(); + bool GetTrainer(); void SetToy(bool bEnable); - bool RetToy(); + bool GetToy(); void SetManual(bool bManual); - bool RetManual(); + bool GetManual(); void SetResetCap(ResetCap cap); - ResetCap RetResetCap(); + ResetCap GetResetCap(); void SetResetBusy(bool bBusy); - bool RetResetBusy(); + bool GetResetBusy(); void SetResetPosition(const Math::Vector &pos); - Math::Vector RetResetPosition(); + Math::Vector GetResetPosition(); void SetResetAngle(const Math::Vector &angle); - Math::Vector RetResetAngle(); + Math::Vector GetResetAngle(); void SetResetRun(int run); - int RetResetRun(); + int GetResetRun(); void SetMasterParticule(int part, int parti); - int RetMasterParticule(int part); + int GetMasterParticule(int part); void SetPower(CObject* power); - CObject* RetPower(); + CObject* GetPower(); void SetFret(CObject* fret); - CObject* RetFret(); + CObject* GetFret(); void SetTruck(CObject* truck); - CObject* RetTruck(); + CObject* GetTruck(); void SetTruckPart(int part); - int RetTruckPart(); + int GetTruckPart(); void InfoFlush(); void DeleteInfo(int rank); void SetInfo(int rank, Info info); - Info RetInfo(int rank); - int RetInfoTotal(); - void SetInfoReturn(float value); - float RetInfoReturn(); + Info GetInfo(int rank); + int GetInfoTotal(); + void SetInfoGeturn(float value); + float GetInfoGeturn(); void SetInfoUpdate(bool bUpdate); - bool RetInfoUpdate(); + bool GetInfoUpdate(); bool SetCmdLine(int rank, float value); - float RetCmdLine(int rank); + float GetCmdLine(int rank); - Math::Matrix* RetRotateMatrix(int part); - Math::Matrix* RetTranslateMatrix(int part); - Math::Matrix* RetTransformMatrix(int part); - Math::Matrix* RetWorldMatrix(int part); + Math::Matrix* GetRotateMatrix(int part); + Math::Matrix* GetTranslateMatrix(int part); + Math::Matrix* GetTransformMatrix(int part); + Math::Matrix* GetWorldMatrix(int part); - void SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV, Math::Vector &lookat, Math::Vector &upVec, CameraType type); + void SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV, + Math::Vector &lookat, Math::Vector &upVec, + Gfx::CameraType type); void SetCharacter(Character* character); void GetCharacter(Character* character); - Character* RetCharacter(); + Character* GetCharacter(); - float RetAbsTime(); + float GetAbsTime(); void SetEnergy(float level); - float RetEnergy(); + float GetEnergy(); void SetCapacity(float capacity); - float RetCapacity(); + float GetCapacity(); void SetShield(float level); - float RetShield(); + float GetShield(); void SetRange(float delay); - float RetRange(); + float GetRange(); void SetTransparency(float value); - float RetTransparency(); + float GetTransparency(); - ObjectMaterial RetMaterial(); + ObjectMaterial GetMaterial(); void SetGadget(bool bMode); - bool RetGadget(); + bool GetGadget(); void SetFixed(bool bFixed); - bool RetFixed(); + bool GetFixed(); void SetClip(bool bClip); - bool RetClip(); + bool GetClip(); bool JostleObject(float force); void StartDetectEffect(CObject *target, bool bFound); void SetVirusMode(bool bEnable); - bool RetVirusMode(); - float RetVirusTime(); + bool GetVirusMode(); + float GetVirusTime(); - void SetCameraType(CameraType type); - CameraType RetCameraType(); + void SetCameraType(Gfx::CameraType type); + Gfx::CameraType GetCameraType(); void SetCameraDist(float dist); - float RetCameraDist(); + float GetCameraDist(); void SetCameraLock(bool bLock); - bool RetCameraLock(); + bool GetCameraLock(); void SetHilite(bool bMode); - bool RetHilite(); + bool GetHilite(); void SetSelect(bool bMode, bool bDisplayError=true); - bool RetSelect(bool bReal=false); + bool GetSelect(bool bReal=false); void SetSelectable(bool bMode); - bool RetSelectable(); + bool GetSelectable(); void SetActivity(bool bMode); - bool RetActivity(); + bool GetActivity(); void SetVisible(bool bVisible); - bool RetVisible(); + bool GetVisible(); void SetEnable(bool bEnable); - bool RetEnable(); + bool GetEnable(); void SetCheckToken(bool bMode); - bool RetCheckToken(); + bool GetCheckToken(); void SetProxyActivate(bool bActivate); - bool RetProxyActivate(); + bool GetProxyActivate(); void SetProxyDistance(float distance); - float RetProxyDistance(); + float GetProxyDistance(); void SetMagnifyDamage(float factor); - float RetMagnifyDamage(); + float GetMagnifyDamage(); void SetParam(float value); - float RetParam(); + float GetParam(); void SetExplo(bool bExplo); - bool RetExplo(); + bool GetExplo(); void SetLock(bool bLock); - bool RetLock(); + bool GetLock(); void SetCargo(bool bCargo); - bool RetCargo(); + bool GetCargo(); void SetBurn(bool bBurn); - bool RetBurn(); + bool GetBurn(); void SetDead(bool bDead); - bool RetDead(); - bool RetRuin(); - bool RetActif(); + bool GetDead(); + bool GetRuin(); + bool GetActif(); void SetGunGoalV(float gunGoal); void SetGunGoalH(float gunGoal); - float RetGunGoalV(); - float RetGunGoalH(); + float GetGunGoalV(); + float GetGunGoalH(); bool StartShowLimit(); void StopShowLimit(); @@ -618,16 +620,16 @@ public: void CreateSelectParticule(); void SetRunScript(CScript* script); - CScript* RetRunScript(); - CBotVar* RetBotVar(); - CPhysics* RetPhysics(); - CBrain* RetBrain(); - CMotion* RetMotion(); - CAuto* RetAuto(); + CScript* GetRunScript(); + CBotVar* GetBotVar(); + CPhysics* GetPhysics(); + CBrain* GetBrain(); + CMotion* GetMotion(); + CAuto* GetAuto(); void SetAuto(CAuto* automat); void SetDefRank(int rank); - int RetDefRank(); + int GetDefRank(); bool GetTooltipName(char* name); @@ -635,17 +637,17 @@ public: CObject* SubDeselList(); void DeleteDeselList(CObject* pObj); - bool CreateShadowCircle(float radius, float intensity, D3DShadowType type=D3DSHADOWNORM); - bool CreateShadowLight(float height, D3DCOLORVALUE color); - bool CreateEffectLight(float height, D3DCOLORVALUE color); + bool CreateShadowCircle(float radius, float intensity, Gfx::EngineShadowType type = Gfx::ENG_SHADOW_NORM); + bool CreateShadowLight(float height, Gfx::Color color); + bool CreateEffectLight(float height, Gfx::Color color); void FlatParent(); - bool RetTraceDown(); + bool GetTraceDown(); void SetTraceDown(bool bDown); - int RetTraceColor(); + int GetTraceColor(); void SetTraceColor(int color); - float RetTraceWidth(); + float GetTraceWidth(); void SetTraceWidth(float width); protected: @@ -663,12 +665,12 @@ protected: protected: CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CLight* m_light; - CTerrain* m_terrain; - CWater* m_water; - CCamera* m_camera; - CParticule* m_particule; + Gfx::CEngine* m_engine; + Gfx::CLightManager* m_lightMan; + Gfx::CTerrain* m_terrain; + Gfx::CWater* m_water; + Gfx::CCamera* m_camera; + Gfx::CParticle* m_particle; CPhysics* m_physics; CBrain* m_brain; CMotion* m_motion; @@ -732,7 +734,7 @@ protected: float m_showLimitRadius; float m_gunGoalV; float m_gunGoalH; - CameraType m_cameraType; + Gfx::CameraType m_cameraType; float m_cameraDist; bool m_bCameraLock; int m_defRank; @@ -767,7 +769,7 @@ protected: int m_infoTotal; Info m_info[OBJECTMAXINFO]; - float m_infoReturn; + float m_infoGeturn; bool m_bInfoUpdate; float m_cmdLine[OBJECTMAXCMDLINE]; diff --git a/src/physics/physics.h b/src/physics/physics.h index 6865b6af..2e1f5eb8 100644 --- a/src/physics/physics.h +++ b/src/physics/physics.h @@ -19,23 +19,27 @@ #pragma once -#include "old/d3dengine.h" #include "common/misc.h" #include "object/object.h" +#include "math/vector.h" class CInstanceManager; -class CD3DEngine; -class CLight; -class CParticule; -class CTerrain; -class CWater; class CCamera; class CObject; class CBrain; class CMotion; class CSound; +namespace Gfx +{ +class CEngine; +class CLight; +class CParticule; +class CTerrain; +class CWater; +}; + enum PhysicsType { @@ -98,64 +102,64 @@ public: void SetMotion(CMotion* motion); void SetType(PhysicsType type); - PhysicsType RetType(); + PhysicsType GetType(); bool Write(char *line); bool Read(char *line); void SetGravity(float value); - float RetGravity(); + float GetGravity(); - float RetFloorHeight(); + float GetFloorHeight(); void SetLinMotion(PhysicsMode mode, Math::Vector value); - Math::Vector RetLinMotion(PhysicsMode mode); + Math::Vector GetLinMotion(PhysicsMode mode); void SetLinMotionX(PhysicsMode mode, float value); void SetLinMotionY(PhysicsMode mode, float value); void SetLinMotionZ(PhysicsMode mode, float value); - float RetLinMotionX(PhysicsMode mode); - float RetLinMotionY(PhysicsMode mode); - float RetLinMotionZ(PhysicsMode mode); + float GetLinMotionX(PhysicsMode mode); + float GetLinMotionY(PhysicsMode mode); + float GetLinMotionZ(PhysicsMode mode); void SetCirMotion(PhysicsMode mode, Math::Vector value); - Math::Vector RetCirMotion(PhysicsMode mode); + Math::Vector GetCirMotion(PhysicsMode mode); void SetCirMotionX(PhysicsMode mode, float value); void SetCirMotionY(PhysicsMode mode, float value); void SetCirMotionZ(PhysicsMode mode, float value); - float RetCirMotionX(PhysicsMode mode); - float RetCirMotionY(PhysicsMode mode); - float RetCirMotionZ(PhysicsMode mode); + float GetCirMotionX(PhysicsMode mode); + float GetCirMotionY(PhysicsMode mode); + float GetCirMotionZ(PhysicsMode mode); - float RetLinStopLength(PhysicsMode sMode=MO_ADVSPEED, PhysicsMode aMode=MO_STOACCEL); - float RetCirStopLength(); - float RetLinMaxLength(float dir); - float RetLinTimeLength(float dist, float dir=1.0f); - float RetLinLength(float dist); + float GetLinStopLength(PhysicsMode sMode=MO_ADVSPEED, PhysicsMode aMode=MO_STOACCEL); + float GetCirStopLength(); + float GetLinMaxLength(float dir); + float GetLinTimeLength(float dist, float dir=1.0f); + float GetLinLength(float dist); void SetMotor(bool bState); - bool RetMotor(); + bool GetMotor(); void SetLand(bool bState); - bool RetLand(); + bool GetLand(); void SetSwim(bool bState); - bool RetSwim(); + bool GetSwim(); void SetCollision(bool bCollision); - bool RetCollision(); + bool GetCollision(); void SetFreeze(bool bFreeze); - bool RetFreeze(); + bool GetFreeze(); void SetReactorRange(float range); - float RetReactorRange(); + float GetReactorRange(); void SetMotorSpeed(Math::Vector speed); void SetMotorSpeedX(float speed); void SetMotorSpeedY(float speed); void SetMotorSpeedZ(float speed); - Math::Vector RetMotorSpeed(); - float RetMotorSpeedX(); - float RetMotorSpeedY(); - float RetMotorSpeedZ(); + Math::Vector GetMotorSpeed(); + float GetMotorSpeedX(); + float GetMotorSpeedY(); + float GetMotorSpeedZ(); void CreateInterface(bool bSelect); - Error RetError(); + Error GetError(); protected: bool EventFrame(const Event &event); @@ -186,12 +190,12 @@ protected: protected: CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CLight* m_light; - CParticule* m_particule; - CTerrain* m_terrain; - CWater* m_water; - CCamera* m_camera; + Gfx::CEngine* m_engine; + Gfx::CLightManager* m_lightMan; + Gfx::CParticle* m_particle; + Gfx::CTerrain* m_terrain; + Gfx::CWater* m_water; + Gfx::CCamera* m_camera; CObject* m_object; CBrain* m_brain; CMotion* m_motion; From 63257034c946d40fb3ecc73a9ee3dc9d1e0a1e34 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Fri, 10 Aug 2012 23:31:42 +0200 Subject: [PATCH 07/10] Partial CEngine implementation - added rewritten implementation for basic modesetting in CEngine - started rewriting proper rendering and object handling in CEngine --- src/app/app.cpp | 21 +- src/app/app.h | 2 +- src/graphics/core/color.h | 6 +- src/graphics/engine/engine.cpp | 2386 +++++++++++++++++++++++++++----- src/graphics/engine/engine.h | 481 ++++--- src/object/object.h | 9 +- 6 files changed, 2403 insertions(+), 502 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 36811726..e1169145 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -573,16 +573,7 @@ int CApplication::Run() } // Update game and render a frame during idle time (no messages are waiting) - bool ok = Render(); - - // If an error occurs, push quit event to the queue - if (! ok) - { - SDL_Event quitEvent; - memset(&quitEvent, 0, sizeof(SDL_Event)); - quitEvent.type = SDL_QUIT; - SDL_PushEvent(&quitEvent); - } + Render(); } } @@ -751,17 +742,13 @@ bool CApplication::ProcessEvent(const Event &event) return true; } -/** Renders the frame and swaps buffers as necessary. Returns \c false on error. */ -bool CApplication::Render() +/** Renders the frame and swaps buffers as necessary */ +void CApplication::Render() { - bool result = m_engine->Render(); - if (! result) - return false; + m_engine->Render(); if (m_deviceConfig.doubleBuf) SDL_GL_SwapBuffers(); - - return true; } void CApplication::StepSimulation(float rTime) diff --git a/src/app/app.h b/src/app/app.h index bba55b23..e7ffd541 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -198,7 +198,7 @@ protected: //! Handles some incoming events bool ProcessEvent(const Event &event); //! Renders the image in window - bool Render(); + void Render(); //! Opens the joystick device bool OpenJoystick(); diff --git a/src/graphics/core/color.h b/src/graphics/core/color.h index 6973644b..0e08de35 100644 --- a/src/graphics/core/color.h +++ b/src/graphics/core/color.h @@ -18,7 +18,6 @@ #pragma once - #include @@ -66,6 +65,11 @@ struct Color { return r == other.r && g == other.g && b == other.b && a == other.a; } + + inline bool operator!=(const Gfx::Color &other) const + { + return ! this->operator==(other); + } }; /** diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index c8fa05ca..4244fb29 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -36,6 +36,8 @@ #include "graphics/engine/text.h" #include "graphics/engine/water.h" #include "math/geometry.h" +#include "sound/sound.h" + // Initial size of various vectors const int OBJECT_PREALLOCATE_COUNT = 1200; @@ -50,6 +52,13 @@ const int LEVEL5_PREALLOCATE_COUNT = 100; const int LEVEL5_VERTEX_PREALLOCATE_COUNT = 200; +// TODO: temporary stub for CInterface +class CInterface +{ +public: + void Draw() {} +}; + Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) { m_iMan = iMan; @@ -60,7 +69,7 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_iMan->AddInstance(CLASS_ENGINE, this); m_app = app; - m_lightMan = nullptr; + m_lightMan = nullptr; m_text = nullptr; m_particle = nullptr; m_water = nullptr; @@ -107,15 +116,14 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_overFront = true; m_overColor = 0; m_overMode = ENG_RSTATE_TCOLOR_BLACK; - m_frontsizeName = ""; // no front image - m_hiliteRank[0] = -1; // empty list + m_highlightRank[0] = -1; // empty list m_eyePt = Math::Vector(0.0f, 0.0f, 0.0f); m_lookatPt = Math::Vector(0.0f, 0.0f, 1.0f); m_drawWorld = true; m_drawFront = false; m_limitLOD[0] = 100.0f; m_limitLOD[1] = 200.0f; - m_particuleDensity = 1.0f; + m_particleDensity = 1.0f; m_clippingDistance = 1.0f; m_lastClippingDistance = m_clippingDistance; m_objectDetail = 1.0f; @@ -186,11 +194,10 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) Gfx::CEngine::~CEngine() { - m_iMan = nullptr; - m_app = nullptr; - m_device = nullptr; - - m_sound = nullptr; + m_iMan = nullptr; + m_app = nullptr; + m_device = nullptr; + m_sound = nullptr; m_terrain = nullptr; } @@ -209,6 +216,16 @@ Gfx::CDevice* Gfx::CEngine::GetDevice() return m_device; } +void Gfx::CEngine::SetTerrain(Gfx::CTerrain* terrain) +{ + m_terrain = terrain; +} + +Gfx::CText* Gfx::CEngine::GetText() +{ + return m_text; +} + bool Gfx::CEngine::Create() { m_size = m_lastSize = m_app->GetVideoConfig().size; @@ -228,15 +245,18 @@ bool Gfx::CEngine::Create() return false; } + m_device->SetClearColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)); + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false); + m_device->SetShadeModel(Gfx::SHADE_SMOOTH); + m_device->SetFillMode(Gfx::FILL_FILL); + + SetFocus(m_focus); m_matWorldInterface.LoadIdentity(); m_matViewInterface.LoadIdentity(); + Math::LoadOrthoProjectionMatrix(m_matProjInterface, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f); - m_device->SetClearColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)); - - m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false); - Gfx::TextureCreateParams params; params.format = Gfx::TEX_IMG_RGB; params.minFilter = Gfx::TEX_MIN_FILTER_NEAREST; @@ -274,71 +294,599 @@ void Gfx::CEngine::Destroy() } void Gfx::CEngine::ResetAfterDeviceChanged() +{ + // TODO reload textures, reset device state, etc. +} + +bool Gfx::CEngine::ProcessEvent(const Event &event) +{ + if (event.type == EVENT_MOUSE_MOVE) + { + m_mousePos = event.mouseMove.pos; + } + else if (event.type == EVENT_KEY_DOWN) + { + // !! Debug, to be removed later !! + + if (event.key.key == KEY(F1)) + { + m_mouseVisible = !m_mouseVisible; + m_app->SetSystemMouseVisible(! m_app->GetSystemMouseVisibile()); + } + else if (event.key.key == KEY(F2)) + { + int index = static_cast(m_mouseType); + m_mouseType = static_cast( (index + 1) % Gfx::ENG_MOUSE_COUNT ); + } + } + + // By default, pass on all events + return true; +} + +void Gfx::CEngine::FrameMove(float rTime) +{ + m_lightMan->UpdateProgression(rTime); + m_particle->FrameParticle(rTime); + ComputeDistance(); + UpdateGeometry(); + + if (m_groundMark.draw) + { + if (m_groundMark.phase == Gfx::ENG_GR_MARK_PHASE_INC) // growing? + { + m_groundMark.intensity += rTime*(1.0f/m_groundMark.delay[0]); + if (m_groundMark.intensity >= 1.0f) + { + m_groundMark.intensity = 1.0f; + m_groundMark.fix = 0.0f; + m_groundMark.phase = Gfx::ENG_GR_MARK_PHASE_FIX; + } + } + else if (m_groundMark.phase == Gfx::ENG_GR_MARK_PHASE_FIX) // fixed? + { + m_groundMark.fix += rTime*(1.0f/m_groundMark.delay[1]); + if (m_groundMark.fix >= 1.0f) + m_groundMark.phase = Gfx::ENG_GR_MARK_PHASE_DEC; + } + else if (m_groundMark.phase == Gfx::ENG_GR_MARK_PHASE_DEC) // decay? + { + m_groundMark.intensity -= rTime*(1.0f/m_groundMark.delay[2]); + if (m_groundMark.intensity < 0.0f) + { + m_groundMark.intensity = 0.0f; + m_groundMark.phase = Gfx::ENG_GR_MARK_PHASE_NULL; + m_groundMark.draw = false; + } + } + } + + if (m_sound == nullptr) + m_sound = static_cast( m_iMan->SearchInstance(CLASS_SOUND) ); + + m_sound->FrameMove(rTime); +} + +void Gfx::CEngine::StepSimulation(float rTime) +{ + m_app->StepSimulation(rTime); +} + +void Gfx::CEngine::TimeInit() +{ + /* TODO! + m_baseTime = timeGetTime(); + m_lastTime = 0; + m_absTime = 0.0f;*/ +} + +void Gfx::CEngine::TimeEnterGel() +{ + /* TODO! + m_stopTime = timeGetTime();*/ +} + +void Gfx::CEngine::TimeExitGel() +{ + /* TODO! + m_baseTime += timeGetTime() - m_stopTime;*/ +} + +float Gfx::CEngine::TimeGet() +{ + /* TODO! + float aTime = (timeGetTime()-m_baseTime)*0.001f; // in ms + float rTime = (aTime - m_lastTime)*m_speed; + m_absTime += rTime; + m_lastTime = aTime; + + return rTime;*/ + return 0.0f; +} + +bool Gfx::CEngine::WriteScreenShot(const std::string& fileName, int width, int height) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::ReadSettings() +{ + // TODO! + return true; +} + +bool Gfx::CEngine::WriteSettings() +{ + // TODO! + return true; +} + +void Gfx::CEngine::SetPause(bool pause) +{ + m_pause = pause; +} + +bool Gfx::CEngine::GetPause() +{ + return m_pause; +} + +void Gfx::CEngine::SetMovieLock(bool lock) +{ + m_movieLock = lock; +} + +bool Gfx::CEngine::GetMovieLock() +{ + return m_movieLock; +} + +void Gfx::CEngine::SetShowStats(bool show) +{ + m_showStats = show; +} + +bool Gfx::CEngine::GetShowStats() +{ + return m_showStats; +} + +void Gfx::CEngine::SetRenderEnable(bool enable) +{ + m_render = enable; +} + +Math::IntSize Gfx::CEngine::GetWindowSize() +{ + return m_size; +} + +Math::IntSize Gfx::CEngine::GetLastWindowSize() +{ + return m_lastSize; +} + +Math::Point Gfx::CEngine::WindowToInterfaceCoords(Math::IntPoint pos) +{ + return Math::Point( static_cast(pos.x) / static_cast(m_size.w), + 1.0f - static_cast(pos.y) / static_cast(m_size.h) ); +} + +Math::IntPoint Gfx::CEngine::InterfaceToWindowCoords(Math::Point pos) +{ + return Math::IntPoint(static_cast(pos.x * m_size.w), + static_cast((1.0f - pos.y) * m_size.h)); +} + +Math::Size Gfx::CEngine::WindowToInterfaceSize(Math::IntSize size) +{ + return Math::Size( static_cast(size.w) / static_cast(m_size.w), + static_cast(size.h) / static_cast(m_size.h) ); +} + +Math::IntSize Gfx::CEngine::InterfaceToWindowSize(Math::Size size) +{ + return Math::IntSize(static_cast(size.w * m_size.w), + static_cast(size.h * m_size.h)); +} + +std::string Gfx::CEngine::GetTextureDir() +{ + return m_texPath; +} + +void Gfx::CEngine::AddStatisticTriangle(int count) +{ + m_statisticTriangle += count; +} + +int Gfx::CEngine::GetStatisticTriangle() +{ + return m_statisticTriangle; +} + + + +/******************************************************* + Object management + *******************************************************/ + + + +int Gfx::CEngine::CreateObject() +{ + // TODO! + return 0; +} + +void Gfx::CEngine::FlushObject() +{ + // TODO! +} + +bool Gfx::CEngine::DeleteObject(int objRank) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetDrawWorld(int objRank, bool draw) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetDrawFront(int objRank, bool draw) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::AddTriangle(int objRank, Gfx::VertexTex2* vertex, int nb, + const Gfx::Material& mat, int state, + std::string texName1, std::string texName2, + float min, float max, bool globalUpdate) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::AddSurface(int objRank, Gfx::VertexTex2* vertex, int nb, + const Gfx::Material& mat, int state, + std::string texName1, std::string texName2, + float min, float max, bool globalUpdate) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::AddQuick(int objRank, const Gfx::EngineObjLevel5& buffer, + std::string texName1, std::string texName2, + float min, float max, bool globalUpdate) +{ + // TODO! + return true; +} + +Gfx::EngineObjLevel5* Gfx::CEngine::SearchTriangle(int objRank, const Gfx::Material& mat, + int state, std::string texName1, + std::string texName2, float min, float max) +{ + // TODO! + return nullptr; +} + +void Gfx::CEngine::ChangeLOD() +{ + // TODO! +} + +bool Gfx::CEngine::ChangeSecondTexture(int objRank, const std::string& texName2) +{ + // TODO! + return true; +} + +int Gfx::CEngine::GetTotalTriangles(int objRank) +{ + // TODO! + return 0; +} + +int Gfx::CEngine::GetTriangles(int objRank, float min, float max, Gfx::EngineTriangle* buffer, int size, float percent) +{ + // TODO! + return 0; +} + +bool Gfx::CEngine::GetBBox(int objRank, Math::Vector& min, Math::Vector& max) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::ChangeTextureMapping(int objRank, const Gfx::Material& mat, int state, + const std::string& texName1, const std::string& texName2, + float min, float max, Gfx::EngineTextureMapping mode, + float au, float bu, float av, float bv) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::TrackTextureMapping(int objRank, const Gfx::Material& mat, int state, + const std::string& texName1, const std::string& texName2, + float min, float max, Gfx::EngineTextureMapping mode, + float pos, float factor, float tl, float ts, float tt) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetObjectTransform(int objRank, const Math::Matrix& transform) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::GetObjectTransform(int objRank, Math::Matrix& transform) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetObjectType(int objRank, Gfx::EngineObjectType type) +{ + // TODO! + return true; +} + +Gfx::EngineObjectType Gfx::CEngine::GetObjectType(int objRank) +{ + // TODO! + return Gfx::ENG_OBJTYPE_FIX; +} + +bool Gfx::CEngine::SetObjectTransparency(int objRank, float value) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::ShadowCreate(int objRank) +{ + // TODO! + return true; +} + +void Gfx::CEngine::ShadowDelete(int objRank) +{ + // TODO! +} + +bool Gfx::CEngine::SetObjectShadowHide(int objRank, bool hide) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetObjectShadowType(int objRank, Gfx::EngineShadowType type) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetObjectShadowPos(int objRank, const Math::Vector& pos) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetObjectShadowNormal(int objRank, const Math::Vector& n) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetObjectShadowAngle(int objRank, float angle) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetObjectShadowRadius(int objRank, float radius) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetObjectShadowIntensity(int objRank, float intensity) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetObjectShadowHeight(int objRank, float h) +{ + // TODO! + return true; +} + +float Gfx::CEngine::GetObjectShadowRadius(int objRank) +{ + // TODO! + return 0.0f; +} + +bool Gfx::CEngine::GetHighlight(Math::Point &p1, Math::Point &p2) +{ + p1 = m_highlightP1; + p2 = m_highlightP2; + return m_highlight; +} + +void Gfx::CEngine::SetHighlightRank(int *rankList) +{ + int i = 0; + while ( *rankList != -1 ) + { + m_highlightRank[i++] = *rankList++; + } + m_highlightRank[i] = -1; // terminator +} + +bool Gfx::CEngine::GetBBox2D(int objRank, Math::Point &min, Math::Point &max) +{ + min.x = 1000000.0f; + min.y = 1000000.0f; + max.x = -1000000.0f; + max.y = -1000000.0f; + + for (int i = 0; i < 8; i++) + { + Math::Vector p; + + if ( i & (1<<0) ) p.x = m_objects[objRank].bboxMin.x; + else p.x = m_objects[objRank].bboxMax.x; + if ( i & (1<<1) ) p.y = m_objects[objRank].bboxMin.y; + else p.y = m_objects[objRank].bboxMax.y; + if ( i & (1<<2) ) p.z = m_objects[objRank].bboxMin.z; + else p.z = m_objects[objRank].bboxMax.z; + + Math::Vector pp; + if (TransformPoint(pp, objRank, p)) + { + if (pp.x < min.x) min.x = pp.x; + if (pp.x > max.x) max.x = pp.x; + if (pp.y < min.y) min.y = pp.y; + if (pp.y > max.y) max.y = pp.y; + } + } + + if ( min.x == 1000000.0f || + min.y == 1000000.0f || + max.x == -1000000.0f || + max.y == -1000000.0f ) return false; + + return true; +} + +void Gfx::CEngine::GroundSpotFlush() { // TODO } -Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName, const Gfx::TextureCreateParams ¶ms) +int Gfx::CEngine::GroundSpotCreate() { - CImage img; - if (! img.Load(m_app->GetDataFilePath(m_texPath, texName))) - { - std::stringstream str; - str << "Couldn't load texture '" << texName << "': " << img.GetError(); - m_error = str.str(); - return Gfx::Texture(); // invalid texture - } - - Gfx::Texture result = m_device->CreateTexture(&img, params); - - if (! result.valid) - { - std::stringstream str; - str << "Couldn't load texture '" << texName << "': " << m_device->GetError(); - m_error = str.str(); - return result; - } - - m_texNameMap[texName] = result; - m_revTexNameMap[result] = texName; - - return result; + // TODO! + return 0; } -Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName) +void Gfx::CEngine::GroundSpotDelete(int rank) { - return CreateTexture(texName, m_defaultTexParams); + // TODO! } -void Gfx::CEngine::DestroyTexture(const std::string &texName) +bool Gfx::CEngine::SetObjectGroundSpotPos(int rank, const Math::Vector& pos) { - std::map::iterator it = m_texNameMap.find(texName); - if (it == m_texNameMap.end()) - return; - - std::map::iterator revIt = m_revTexNameMap.find((*it).second); - - m_device->DestroyTexture((*it).second); - - m_revTexNameMap.erase(revIt); - m_texNameMap.erase(it); + // TODO! + return true; } -void Gfx::CEngine::SetTexture(const std::string &name, int stage) +bool Gfx::CEngine::SetObjectGroundSpotRadius(int rank, float radius) { - std::map::iterator it = m_texNameMap.find(name); - if (it != m_texNameMap.end()) - m_device->SetTexture(stage, (*it).second); - - // TODO if not present... + // TODO! + return true; } -void Gfx::CEngine::SetMaterial(const Gfx::Material &mat) +bool Gfx::CEngine::SetObjectGroundSpotColor(int rank, const Gfx::Color& color) { - m_device->SetMaterial(mat); + // TODO! + return true; } -void Gfx::CEngine::SetState(int state, Gfx::Color color) +bool Gfx::CEngine::SetObjectGroundSpotMinMax(int rank, float min, float max) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::SetObjectGroundSpotSmooth(int rank, float smooth) +{ + // TODO! + return true; +} + +int Gfx::CEngine::GroundMarkCreate(Math::Vector pos, float radius, + float delay1, float delay2, float delay3, + int dx, int dy, char* table) +{ + // TODO! + return 0; +} + +bool Gfx::CEngine::GroundMarkDelete(int rank) +{ + // TODO! + return true; +} + +void Gfx::CEngine::ComputeDistance() +{ + // TODO! +} + +void Gfx::CEngine::UpdateGeometry() +{ + // TODO! +} + +void Gfx::CEngine::Update() +{ + ComputeDistance(); + UpdateGeometry(); +} + +bool Gfx::CEngine::DetectBBox(int objRank, Math::Point mouse) +{ + // TODO! + return true; +} + +int Gfx::CEngine::DetectObject(Math::Point mouse) +{ + // TODO! + return 0; +} + +bool Gfx::CEngine::DetectTriangle(Math::Point mouse, Gfx::VertexTex2* triangle, int objRank, float& dist) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::IsVisible(int objRank) +{ + // TODO! + return true; +} + +bool Gfx::CEngine::TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p3D) +{ + // TODO! + return true; +} + + + +/******************************************************* + Mode setting + *******************************************************/ + + + +void Gfx::CEngine::SetState(int state, const Gfx::Color& color) { if ( state == m_lastState && color == m_lastColor ) return; @@ -545,144 +1093,1528 @@ void Gfx::CEngine::SetState(int state, Gfx::Color color) m_device->SetGlobalAmbient(m_ambientColor[m_rankView]); } -bool Gfx::CEngine::ProcessEvent(const Event &event) +void Gfx::CEngine::SetMaterial(const Gfx::Material &mat) { - if (event.type == EVENT_MOUSE_MOVE) - { - m_mousePos = event.mouseMove.pos; - } - else if (event.type == EVENT_KEY_DOWN) - { - // !! Debug, to be removed later !! + m_device->SetMaterial(mat); +} - if (event.key.key == KEY(F1)) - { - m_mouseVisible = !m_mouseVisible; - m_app->SetSystemMouseVisible(! m_app->GetSystemMouseVisibile()); - } - else if (event.key.key == KEY(F2)) - { - int index = static_cast(m_mouseType); - m_mouseType = static_cast( (index + 1) % Gfx::ENG_MOUSE_COUNT ); - } +void Gfx::CEngine::SetViewParams(const Math::Vector& eyePt, const Math::Vector& lookatPt, + const Math::Vector& upVec, float eyeDistance) +{ + m_eyePt = eyePt; + m_lookatPt = lookatPt; + m_eyeDirH = Math::RotateAngle(eyePt.x - lookatPt.x, eyePt.z - lookatPt.z); + m_eyeDirV = Math::RotateAngle(Math::DistanceProjected(eyePt, lookatPt), eyePt.y - lookatPt.y); + + Math::LoadViewMatrix(m_matView, eyePt, lookatPt, upVec); + + if (m_sound == nullptr) + m_sound = static_cast( m_iMan->SearchInstance(CLASS_SOUND) ); + + m_sound->SetListener(eyePt, lookatPt); +} + +Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName, const Gfx::TextureCreateParams ¶ms) +{ + CImage img; + if (! img.Load(m_app->GetDataFilePath(m_texPath, texName))) + { + std::stringstream str; + str << "Couldn't load texture '" << texName << "': " << img.GetError(); + m_error = str.str(); + return Gfx::Texture(); // invalid texture } - // By default, pass on all events + Gfx::Texture result = m_device->CreateTexture(&img, params); + + if (! result.valid) + { + std::stringstream str; + str << "Couldn't load texture '" << texName << "': " << m_device->GetError(); + m_error = str.str(); + return result; + } + + m_texNameMap[texName] = result; + m_revTexNameMap[result] = texName; + + return result; +} + +Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName) +{ + return CreateTexture(texName, m_defaultTexParams); +} + +void Gfx::CEngine::DestroyTexture(const std::string &texName) +{ + std::map::iterator it = m_texNameMap.find(texName); + if (it == m_texNameMap.end()) + return; + + std::map::iterator revIt = m_revTexNameMap.find((*it).second); + + m_device->DestroyTexture((*it).second); + + m_revTexNameMap.erase(revIt); + m_texNameMap.erase(it); +} + +bool Gfx::CEngine::LoadTexture(const std::string& name, int stage) +{ + std::map::iterator it = m_texNameMap.find(name); + if (it != m_texNameMap.end()) + { + m_device->SetTexture(stage, (*it).second); + return true; + } + + // TODO if not present... + return false; +} + +bool Gfx::CEngine::LoadAllTextures() +{ + // TODO! return true; } -bool Gfx::CEngine::Render() +bool Gfx::CEngine::SetTexture(const std::string& name, int stage) { + // TODO! + return true; +} + +void Gfx::CEngine::SetLimitLOD(int rank, float limit) +{ + m_limitLOD[rank] = limit; +} + +float Gfx::CEngine::GetLimitLOD(int rank, bool last) +{ + float limit = 0.0f; + + if (last) + { + limit = m_limitLOD[rank]; + limit *= m_lastSize.w/640.0f; // limit further if large window! + limit += m_limitLOD[0]*(m_lastObjectDetail*2.0f); + } + else + { + limit = m_limitLOD[rank]; + limit *= m_size.w/640.0f; // limit further if large window! + limit += m_limitLOD[0]*(m_objectDetail*2.0f); + } + + if (limit < 0.0f) limit = 0.0f; + + return limit; +} + +void Gfx::CEngine::SetTerrainVision(float vision) +{ + m_terrainVision = vision; +} + +void Gfx::CEngine::SetFocus(float focus) +{ + m_focus = focus; + m_size = m_app->GetVideoConfig().size; + + float aspect = (static_cast(m_size.h)) / m_size.w; + Math::LoadProjectionMatrix(m_matProj, m_focus, aspect, 0.5f, m_deepView[0]); +} + +float Gfx::CEngine::GetFocus() +{ + return m_focus; +} + +void Gfx::CEngine::SetGroundSpot(bool mode) +{ + m_groundSpotVisible = mode; +} + +bool Gfx::CEngine::GetGroundSpot() +{ + return m_groundSpotVisible; +} + +void Gfx::CEngine::SetShadow(bool mode) +{ + m_shadowVisible = mode; +} + +bool Gfx::CEngine::GetShadow() +{ + return m_shadowVisible; +} + +void Gfx::CEngine::SetDirty(bool mode) +{ + m_dirty = mode; +} + +bool Gfx::CEngine::GetDirty() +{ + return m_dirty; +} + +void Gfx::CEngine::SetFog(bool mode) +{ + m_fog = mode; +} + +bool Gfx::CEngine::GetFog() +{ + return m_fog; +} + +bool Gfx::CEngine::GetStateColor() +{ + return m_stateColor; +} + +void Gfx::CEngine::SetSecondTexture(int texNum) +{ + m_secondTexNum = texNum; +} + +int Gfx::CEngine::GetSecondTexture() +{ + return m_secondTexNum; +} + +void Gfx::CEngine::SetRankView(int rank) +{ + if (rank < 0) rank = 0; + if (rank > 1) rank = 1; + + if (m_rankView == 0 && rank == 1) // enters the water? + m_lightMan->AdaptLightColor(m_waterAddColor, +1.0f); + + if (m_rankView == 1 && rank == 0) // out of the water? + m_lightMan->AdaptLightColor(m_waterAddColor, -1.0f); + + m_rankView = rank; +} + +int Gfx::CEngine::GetRankView() +{ + return m_rankView; +} + +void Gfx::CEngine::SetDrawWorld(bool draw) +{ + m_drawWorld = draw; +} + +void Gfx::CEngine::SetDrawFront(bool draw) +{ + m_drawFront = draw; +} + +void Gfx::CEngine::SetAmbientColor(const Gfx::Color& color, int rank) +{ + m_ambientColor[rank] = color; +} + +Gfx::Color Gfx::CEngine::GetAmbientColor(int rank) +{ + return m_ambientColor[rank]; +} + +void Gfx::CEngine::SetWaterAddColor(const Gfx::Color& color) +{ + m_waterAddColor = color; +} + +Gfx::Color Gfx::CEngine::GetWaterAddColor() +{ + return m_waterAddColor; +} + +void Gfx::CEngine::SetFogColor(const Gfx::Color& color, int rank) +{ + m_fogColor[rank] = color; +} + +Gfx::Color Gfx::CEngine::GetFogColor(int rank) +{ + return m_fogColor[rank]; +} + +void Gfx::CEngine::SetDeepView(float length, int rank, bool ref) +{ + if (ref) + length *= m_clippingDistance; + + m_deepView[rank] = length; +} + +float Gfx::CEngine::GetDeepView(int rank) +{ + return m_deepView[rank]; +} + +void Gfx::CEngine::SetFogStart(float start, int rank) +{ + m_fogStart[rank] = start; +} + +float Gfx::CEngine::GetFogStart(int rank) +{ + return m_fogStart[rank]; +} + + +void Gfx::CEngine::SetBackground(const std::string& name, Gfx::Color up, Gfx::Color down, + Gfx::Color cloudUp, Gfx::Color cloudDown, + bool full, bool quarter) +{ + m_backgroundName = name; + m_backgroundColorUp = up; + m_backgroundColorDown = down; + m_backgroundCloudUp = cloudUp; + m_backgroundCloudDown = cloudDown; + m_backgroundFull = full; + m_backgroundQuarter = quarter; +} + +void Gfx::CEngine::GetBackground(std::string& name, Gfx::Color& up, Gfx::Color& down, + Gfx::Color& cloudUp, Gfx::Color& cloudDown, + bool &full, bool &quarter) +{ + name = m_backgroundName; + up = m_backgroundColorUp; + down = m_backgroundColorDown; + cloudUp = m_backgroundCloudUp; + cloudDown = m_backgroundCloudDown; + full = m_backgroundFull; + quarter = m_backgroundQuarter; +} + +void Gfx::CEngine::SetForegroundImageName(const std::string& name) +{ + if (! m_foregroundImageName.empty()) + DestroyTexture(m_foregroundImageName); + + m_foregroundImageName = name; +} + +void Gfx::CEngine::SetOverFront(bool front) +{ + m_overFront = front; +} + +void Gfx::CEngine::SetOverColor(const Gfx::Color& color, int mode) +{ + m_overColor = color; + m_overMode = mode; +} + +void Gfx::CEngine::SetParticleDensity(float value) +{ + if (value < 0.0f) value = 0.0f; + if (value > 2.0f) value = 2.0f; + m_particleDensity = value; +} + +float Gfx::CEngine::GetParticleDensity() +{ + return m_particleDensity; +} + +float Gfx::CEngine::ParticleAdapt(float factor) +{ + if (m_particleDensity == 0.0f) + return 1000000.0f; + + return factor / m_particleDensity; +} + +void Gfx::CEngine::SetClippingDistance(float value) +{ + if (value < 0.5f) value = 0.5f; + if (value > 2.0f) value = 2.0f; + m_clippingDistance = value; +} + +float Gfx::CEngine::GetClippingDistance() +{ + return m_clippingDistance; +} + +void Gfx::CEngine::SetObjectDetail(float value) +{ + if ( value < 0.0f ) value = 0.0f; + if ( value > 2.0f ) value = 2.0f; + m_objectDetail = value; +} + +float Gfx::CEngine::GetObjectDetail() +{ + return m_objectDetail; +} + +void Gfx::CEngine::SetGadgetQuantity(float value) +{ + if (value < 0.0f) value = 0.0f; + if (value > 1.0f) value = 1.0f; + + m_gadgetQuantity = value; +} + +float Gfx::CEngine::GetGadgetQuantity() +{ + return m_gadgetQuantity; +} + +void Gfx::CEngine::SetTextureQuality(int value) +{ + if (value < 0) value = 0; + if (value > 2) value = 2; + + if (value != m_textureQuality) + { + m_textureQuality = value; + LoadAllTextures(); + } +} + +int Gfx::CEngine::GetTextureQuality() +{ + return m_textureQuality; +} + +void Gfx::CEngine::SetTotoMode(bool present) +{ + m_totoMode = present; +} + +bool Gfx::CEngine::GetTotoMode() +{ + return m_totoMode; +} + +void Gfx::CEngine::SetLensMode(bool present) +{ + m_lensMode = present; +} + +bool Gfx::CEngine::GetLensMode() +{ + return m_lensMode; +} + +void Gfx::CEngine::SetWaterMode(bool present) +{ + m_waterMode = present; +} + +bool Gfx::CEngine::GetWaterMode() +{ + return m_waterMode; +} + +void Gfx::CEngine::SetLightingMode(bool present) +{ + m_lightMode = present; +} + +bool Gfx::CEngine::GetLightingMode() +{ + return m_lightMode; +} + +void Gfx::CEngine::SetSkyMode(bool present) +{ + m_skyMode = present; +} + +bool Gfx::CEngine::GetSkyMode() +{ + return m_skyMode; +} + +void Gfx::CEngine::SetBackForce(bool present) +{ + m_backForce = present; +} + +bool Gfx::CEngine::GetBackForce() +{ + return m_backForce; +} + +void Gfx::CEngine::SetPlanetMode(bool present) +{ + m_planetMode = present; +} + +bool Gfx::CEngine::GetPlanetMode() +{ + return m_planetMode; +} + +void Gfx::CEngine::SetLightMode(bool present) +{ + m_lightMode = present; +} + +bool Gfx::CEngine::GetLightMode() +{ + return m_lightMode; +} + +void Gfx::CEngine::SetEditIndentMode(bool autoIndent) +{ + m_editIndentMode = autoIndent; +} + +bool Gfx::CEngine::GetEditIndentMode() +{ + return m_editIndentMode; +} + +void Gfx::CEngine::SetEditIndentValue(int value) +{ + m_editIndentValue = value; +} + +int Gfx::CEngine::GetEditIndentValue() +{ + return m_editIndentValue; +} + +void Gfx::CEngine::SetSpeed(float speed) +{ + m_speed = speed; +} + +float Gfx::CEngine::GetSpeed() +{ + return m_speed; +} + +void Gfx::CEngine::SetTracePrecision(float factor) +{ + m_tracePrecision = factor; +} + +float Gfx::CEngine::GetTracePrecision() +{ + return m_tracePrecision; +} + +void Gfx::CEngine::SetMouseVisible(bool visible) +{ + m_mouseVisible = visible; +} + +bool Gfx::CEngine::GetMouseVisible() +{ + return m_mouseVisible; +} + +void Gfx::CEngine::SetMousePos(Math::Point pos) +{ + m_mousePos = pos; +} + +Math::Point Gfx::CEngine::GetMousePos() +{ + return m_mousePos; +} + +void Gfx::CEngine::SetMouseType(Gfx::EngineMouseType type) +{ + m_mouseType = type; +} + +Gfx::EngineMouseType Gfx::CEngine::GetMouseType() +{ + return m_mouseType; +} + +const Math::Matrix& Gfx::CEngine::GetMatView() +{ + return m_matView; +} + +Math::Vector Gfx::CEngine::GetEyePt() +{ + return m_eyePt; +} + +Math::Vector Gfx::CEngine::GetLookatPt() +{ + return m_lookatPt; +} + +float Gfx::CEngine::GetEyeDirH() +{ + return m_eyeDirH; +} + +float Gfx::CEngine::GetEyeDirV() +{ + return m_eyeDirV; +} + +bool Gfx::CEngine::IsVisiblePoint(const Math::Vector &pos) +{ + return Math::Distance(m_eyePt, pos) <= m_deepView[0]; +} + +void Gfx::CEngine::UpdateMatProj() +{ + m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProj); +} + +void Gfx::CEngine::ApplyChange() +{ + m_deepView[0] /= m_lastClippingDistance; + m_deepView[1] /= m_lastClippingDistance; + + SetFocus(m_focus); + ChangeLOD(); + + m_deepView[0] *= m_clippingDistance; + m_deepView[1] *= m_clippingDistance; +} + + + +/******************************************************* + Rendering + *******************************************************/ + + + +/** + This function sets up render states, clears the + viewport, and renders the scene. */ +void Gfx::CEngine::Render() +{ + /* TODO! + D3DObjLevel1* p1; + D3DObjLevel2* p2; + D3DObjLevel3* p3; + D3DObjLevel4* p4; + D3DObjLevel5* p5; + D3DVERTEX2* pv; + int l1, l2, l3, l4, l5, objRank;*/ + + if (! m_render) return; + m_statisticTriangle = 0; - m_lastState = -1; - SetState(Gfx::ENG_RSTATE_NORMAL); + m_lastColor = 999; + m_lastMaterial = Gfx::Material(); + m_lightMan->UpdateLights(); + + Gfx::Color color; + if (m_skyMode && m_cloud->GetLevel() != 0.0f) // clouds? + color = m_backgroundCloudDown; + else + color = m_backgroundColorDown; + + m_device->SetClearColor(color); + + // Begin the scene m_device->BeginScene(); - SetUp3DView(); - if (! Draw3DScene() ) - return false; + if (m_drawWorld) + { + Draw3DScene(); + } - SetUpInterfaceView(); - if (! DrawInterface() ) - return false; + DrawInterface(); + // End the scene m_device->EndScene(); - - return true; } -void Gfx::CEngine::SetUp3DView() +void Gfx::CEngine::Draw3DScene() { - // TODO + if (m_groundSpotVisible) + UpdateGroundSpotTextures(); + + DrawBackground(); // draws the background + if (m_planetMode) DrawPlanet(); // draws the planets + if (m_skyMode) m_cloud->Draw(); // draws the clouds + + + // Display the objects + + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, true); + m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, true); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, true); + + float fogStart = m_deepView[m_rankView]*m_fogStart[m_rankView]; + float fogEnd = m_deepView[m_rankView]; + m_device->SetFogParams(Gfx::FOG_LINEAR, m_fogColor[m_rankView], fogStart, fogEnd, 1.0f); + + m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProj); + m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matView); + + if (m_waterMode) m_water->DrawBack(); // draws water background + + if (m_shadowVisible) + { + // Draw the field + // TODO! + /* + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + SetTexture(p2->texName1, 0); + SetTexture(p2->texName2, 1); + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + objRank = p3->objRank; + if ( m_objectParam[objRank].type != TYPETERRAIN ) continue; + if ( !m_objectParam[objRank].bDrawWorld ) continue; + + { + D3DMATRIX mat = MAT_TO_D3DMAT(m_objectParam[objRank].transform); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); + } + + if ( !IsVisible(objRank) ) continue; + m_light->LightUpdate(m_objectParam[objRank].type); + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( m_objectParam[objRank].distance < p4->min || + m_objectParam[objRank].distance >= p4->max ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + SetMaterial(p6->material); + SetState(p6->state); + if ( p6->type == D3DTYPE6T ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed/3; + } + if ( p6->type == D3DTYPE6S ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed-2; + } + } + } + } + } + }*/ + + // Draws the shadows + DrawShadow(); + } + + // Draw objects + bool transparent = false; + /* TODO! + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + SetTexture(p2->texName1, 0); + SetTexture(p2->texName2, 1); + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + objRank = p3->objRank; + if ( m_bShadow && m_objectParam[objRank].type == TYPETERRAIN ) continue; + if ( !m_objectParam[objRank].bDrawWorld ) continue; + + { + D3DMATRIX mat = MAT_TO_D3DMAT(m_objectParam[objRank].transform); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); + } + + if ( !IsVisible(objRank) ) continue; + m_light->LightUpdate(m_objectParam[objRank].type); + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( m_objectParam[objRank].distance < p4->min || + m_objectParam[objRank].distance >= p4->max ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + SetMaterial(p6->material); + if ( m_objectParam[objRank].transparency != 0.0f ) // transparent ? + { + transparent = true; + continue; + } + SetState(p6->state); + if ( p6->type == D3DTYPE6T ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed/3; + } + if ( p6->type == D3DTYPE6S ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed-2; + } + } + } + } + } + }*/ + + if (transparent) + { + int tState = 0; + Gfx::Color tColor; + if (m_stateColor) + { + tState = Gfx::ENG_RSTATE_TTEXTURE_BLACK | Gfx::ENG_RSTATE_2FACE; + tColor = Gfx::Color(68.0f / 255.0f, 68.0f / 255.0f, 68.0f / 255.0f, 68.0f / 255.0f); + } + else + { + tState = Gfx::ENG_RSTATE_TCOLOR_BLACK; + tColor = Gfx::Color(136.0f / 255.0f, 136.0f / 255.0f, 136.0f / 255.0f, 136.0f / 255.0f); + } + + // Draw transparent objects. + /* TODO! + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + SetTexture(p2->texName1, 0); + SetTexture(p2->texName2, 1); + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + objRank = p3->objRank; + if ( m_bShadow && m_objectParam[objRank].type == TYPETERRAIN ) continue; + if ( !m_objectParam[objRank].bDrawWorld ) continue; + + { + D3DMATRIX mat = MAT_TO_D3DMAT(m_objectParam[objRank].transform); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); + } + + if ( !IsVisible(objRank) ) continue; + m_light->LightUpdate(m_objectParam[objRank].type); + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( m_objectParam[objRank].distance < p4->min || + m_objectParam[objRank].distance >= p4->max ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + SetMaterial(p6->material); + if ( m_objectParam[objRank].transparency == 0.0f ) continue; + SetState(tState, tColor); + if ( p6->type == D3DTYPE6T ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed/3; + } + if ( p6->type == D3DTYPE6S ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed-2; + } + } + } + } + } + } */ + } + + m_lightMan->UpdateLightsEnableState(Gfx::ENG_OBJTYPE_TERRAIN); + + if (m_waterMode) m_water->DrawSurf(); // draws water surface + + m_particle->DrawParticle(Gfx::SH_WORLD); // draws the particles of the 3D world + m_lightning->Draw(); // draws lightning + if (m_lensMode) DrawForegroundImage(); // draws the foreground + if (! m_overFront) DrawOverColor(); // draws the foreground color } -bool Gfx::CEngine::Draw3DScene() +void Gfx::CEngine::DrawInterface() { - // TODO - return true; -} + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false); + m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); -void Gfx::CEngine::SetUpInterfaceView() -{ - m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_matWorldInterface); m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface); m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProjInterface); + m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_matWorldInterface); + + // Draw the entire interface + CInterface* interface = static_cast( m_iMan->SearchInstance(CLASS_INTERFACE) ); + if (interface != nullptr) + interface->Draw(); + + m_particle->DrawParticle(Gfx::SH_INTERFACE); // draws the particles of the interface + + // 3D objects drawn in front of interface + if (m_drawFront) + { + // Display the objects + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, true); + + m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProj); + + m_device->SetGlobalAmbient(m_ambientColor[m_rankView]); + m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, true); + + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, true); + + float fogStart = m_deepView[m_rankView]*m_fogStart[m_rankView]; + float fogEnd = m_deepView[m_rankView]; + m_device->SetFogParams(Gfx::FOG_LINEAR, m_fogColor[m_rankView], fogStart, fogEnd, 1.0f); + + m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matView); + + // TODO! + /* + for (int l1 = 0; l1 < m_objectTree.size(); l1++) + { + Gfx::EngineObjLevel1* p1 = &m_objectTree[l1]; + p2 = p1->table[l1]; + if ( p2 == 0 ) continue; + SetTexture(p2->texName1, 0); + SetTexture(p2->texName2, 1); + for ( l2=0 ; l2totalUsed ; l2++ ) + { + p3 = p2->table[l2]; + if ( p3 == 0 ) continue; + objRank = p3->objRank; + if ( !m_objectParam[objRank].bDrawFront ) continue; + + { + D3DMATRIX mat = MAT_TO_D3DMAT(m_objectParam[objRank].transform); + m_pD3DDevice->SetTransform(D3DTRANSFORMSTATE_WORLD, &mat); + } + + if ( !IsVisible(objRank) ) continue; + m_light->LightUpdate(m_objectParam[objRank].type); + for ( l3=0 ; l3totalUsed ; l3++ ) + { + p4 = p3->table[l3]; + if ( p4 == 0 ) continue; + if ( m_objectParam[objRank].distance < p4->min || + m_objectParam[objRank].distance >= p4->max ) continue; + for ( l4=0 ; l4totalUsed ; l4++ ) + { + p5 = p4->table[l4]; + if ( p5 == 0 ) continue; + for ( l5=0 ; l5totalUsed ; l5++ ) + { + p6 = p5->table[l5]; + if ( p6 == 0 ) continue; + SetMaterial(p6->material); + SetState(p6->state); + if ( p6->type == D3DTYPE6T ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed/3; + } + if ( p6->type == D3DTYPE6S ) + { + pv = &p6->vertex[0]; + m_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, + D3DFVF_VERTEX2, + pv, p6->totalUsed, + NULL); + m_statisticTriangle += p6->totalUsed-2; + } + } + } + } + } + }*/ + + m_particle->DrawParticle(Gfx::SH_FRONT); // draws the particles of the 3D world + + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false); + m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + + m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface); + m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProjInterface); + m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_matWorldInterface); + } + + // Draw foreground color + if (m_overFront) + DrawOverColor(); + + // Mouse & highlight at the end + DrawMouse(); + DrawHighlight(); } -bool Gfx::CEngine::DrawInterface() +void Gfx::CEngine::UpdateGroundSpotTextures() { - Gfx::VertexCol vertices[3] = + // TODO! +} + +void Gfx::CEngine::DrawShadow() +{ + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); + m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false); + + Math::Matrix matrix; + matrix.LoadIdentity(); + m_device->SetTransform(Gfx::TRANSFORM_WORLD, matrix); + + + Gfx::Material material; + material.diffuse = Gfx::Color(1.0f, 1.0f, 1.0f); + material.ambient = Gfx::Color(0.5f, 0.5f, 0.5f); + SetMaterial(material); + + // TODO: wtf? + SetTexture("text.png"); + + Math::Point ts, ti; + + float dp = 0.5f/256.0f; + ts.y = 192.0f/256.0f; + ti.y = 224.0f/256.0f; + ts.y += dp; + ti.y -= dp; + + Math::Vector n(0.0f, 1.0f, 0.0f); + + float startDeepView = m_deepView[m_rankView]*m_fogStart[m_rankView]; + float endDeepView = m_deepView[m_rankView]; + + float lastIntensity = -1.0f; + for (int i = 0; i < static_cast( m_shadow.size() ); i++) { - Gfx::VertexCol(Math::Vector( 0.25f, 0.25f, 0.0f), Gfx::Color(1.0f, 0.0f, 0.0f)), - Gfx::VertexCol(Math::Vector( 0.75f, 0.25f, 0.0f), Gfx::Color(0.0f, 1.0f, 0.0f)), - Gfx::VertexCol(Math::Vector( 0.5f, 0.75f, 0.0f), Gfx::Color(0.0f, 0.0f, 1.0f)) + if (m_shadow[i].hide) continue; + + Math::Vector pos = m_shadow[i].pos; // pos = center of the shadow on the ground + + if (m_eyePt.y == pos.y) continue; // camera at the same level? + + float d = 0.0f; + float D = 0.0f; + + // h is the height above the ground to which the shadow + // will be drawn. + if (m_eyePt.y > pos.y) // camera on? + { + float height = m_eyePt.y-pos.y; + float h = m_shadow[i].radius; + float max = height*0.5f; + if ( h > max ) h = max; + if ( h > 4.0f ) h = 4.0f; + + D = Math::Distance(m_eyePt, pos); + if ( D >= endDeepView ) continue; + d = D*h/height; + + pos.x += (m_eyePt.x-pos.x)*d/D; + pos.z += (m_eyePt.z-pos.z)*d/D; + pos.y += h; + } + else // camera underneath? + { + float height = pos.y-m_eyePt.y; + float h = m_shadow[i].radius; + float max = height*0.1f; + if ( h > max ) h = max; + if ( h > 4.0f ) h = 4.0f; + + D = Math::Distance(m_eyePt, pos); + if ( D >= endDeepView ) continue; + d = D*h/height; + + pos.x += (m_eyePt.x-pos.x)*d/D; + pos.z += (m_eyePt.z-pos.z)*d/D; + pos.y -= h; + } + + // The hFactor decreases the intensity and size increases more + // the object is high relative to the ground. + float hFactor = m_shadow[i].height/20.0f; + if ( hFactor < 0.0f ) hFactor = 0.0f; + if ( hFactor > 1.0f ) hFactor = 1.0f; + hFactor = powf(1.0f-hFactor, 2.0f); + if ( hFactor < 0.2f ) hFactor = 0.2f; + + float radius = m_shadow[i].radius*1.5f; + radius *= 2.0f-hFactor; // greater if high + radius *= 1.0f-d/D; // smaller if close + + + Math::Vector corner[4]; + + if (m_shadow[i].type == Gfx::ENG_SHADOW_NORM) + { + corner[0].x = +radius; + corner[0].z = +radius; + corner[0].y = 0.0f; + + corner[1].x = -radius; + corner[1].z = +radius; + corner[1].y = 0.0f; + + corner[2].x = +radius; + corner[2].z = -radius; + corner[2].y = 0.0f; + + corner[3].x = -radius; + corner[3].z = -radius; + corner[3].y = 0.0f; + + ts.x = 64.0f/256.0f; + ti.x = 96.0f/256.0f; + } + else + { + Math::Point rot; + + rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(radius, radius)); + corner[0].x = rot.x; + corner[0].z = rot.y; + corner[0].y = 0.0f; + + rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(-radius, radius)); + corner[1].x = rot.x; + corner[1].z = rot.y; + corner[1].y = 0.0f; + + rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(radius, -radius)); + corner[2].x = rot.x; + corner[2].z = rot.y; + corner[2].y = 0.0f; + + rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(-radius, -radius)); + corner[3].x = rot.x; + corner[3].z = rot.y; + corner[3].y = 0.0f; + + if (m_shadow[i].type == Gfx::ENG_SHADOW_WORM) + { + ts.x = 96.0f/256.0f; + ti.x = 128.0f/256.0f; + } + else + { + ts.x = 64.0f/256.0f; + ti.x = 96.0f/256.0f; + } + } + + corner[0] = Math::CrossProduct(corner[0], m_shadow[i].normal); + corner[1] = Math::CrossProduct(corner[1], m_shadow[i].normal); + corner[2] = Math::CrossProduct(corner[2], m_shadow[i].normal); + corner[3] = Math::CrossProduct(corner[3], m_shadow[i].normal); + + corner[0] += pos; + corner[1] += pos; + corner[2] += pos; + corner[3] += pos; + + ts.x += dp; + ti.x -= dp; + + Gfx::Vertex vertex[4] = + { + Gfx::Vertex(corner[1], n, Math::Point(ts.x, ts.y)), + Gfx::Vertex(corner[0], n, Math::Point(ti.x, ts.y)), + Gfx::Vertex(corner[3], n, Math::Point(ts.x, ti.y)), + Gfx::Vertex(corner[2], n, Math::Point(ti.x, ti.y)) + }; + + float intensity = (0.5f+m_shadow[i].intensity*0.5f)*hFactor; + + // Decreases the intensity of the shade if you're in the area + // between the beginning and the end of the fog. + if ( D > startDeepView ) + intensity *= 1.0f-(D-startDeepView)/(endDeepView-startDeepView); + + if (intensity == 0.0f) continue; + + if (lastIntensity != intensity) // intensity changed? + { + lastIntensity = intensity; + SetState(Gfx::ENG_RSTATE_TTEXTURE_WHITE, Gfx::Color(intensity, intensity, intensity, intensity)); + } + + m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, vertex, 4); + AddStatisticTriangle(2); + } + + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, true); + m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, true); +} + +void Gfx::CEngine::DrawBackground() +{ + if (m_skyMode && m_cloud->GetLevel() != 0.0f) // clouds ? + { + if (m_backgroundCloudUp != m_backgroundCloudDown) // degraded? + DrawBackgroundGradient(m_backgroundCloudUp, m_backgroundCloudDown); + } + else + { + if (m_backgroundColorUp != m_backgroundColorDown) // degraded? + DrawBackgroundGradient(m_backgroundColorUp, m_backgroundColorDown); + } + + if (m_backForce || (m_skyMode && m_backgroundName[0] != 0) ) + { + DrawBackgroundImage(); // image + } +} + +void Gfx::CEngine::DrawBackgroundGradient(const Gfx::Color& up, const Gfx::Color& down) +{ + Math::Point p1(0.0f, 0.5f); + Math::Point p2(1.0f, 1.0f); + + Gfx::Color color[3] = + { + up, + down, + Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f) }; - m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLES, vertices, 3); + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); + m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false); - DrawMouse(); + SetState(Gfx::ENG_RSTATE_NORMAL); - std::vector format; - for (int i = 0; i < 10; ++i) - format.push_back(Gfx::FONT_COLOBOT_BOLD | Gfx::FONT_HIGHLIGHT_CONST); - for (int i = 0; i < 10; ++i) - format.push_back(Gfx::FONT_COLOBOT_ITALIC | Gfx::FONT_HIGHLIGHT_KEY); - for (int i = 0; i < 10; ++i) - format.push_back(Gfx::FONT_COURIER | Gfx::FONT_HIGHLIGHT_LINK); - for (int i = 0; i < 5; ++i) - format.push_back(Gfx::FONT_COURIER_BOLD | Gfx::FONT_HIGHLIGHT_REM); + m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface); + m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProjInterface); + m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_matWorldInterface); - m_text->DrawText("abcdefghijklmnopqrstuvwxyz ąęśćółńż", Gfx::FONT_COLOBOT, 15.0f, Math::Point(0.25f, 0.2f), 1.0f, Gfx::TEXT_ALIGN_LEFT, 0); - float h = m_text->GetHeight(Gfx::FONT_COLOBOT, 15.0f); - m_text->DrawText("abcdefghijklmnopqrstuvwxyz ąęśćółńż", format, 13.0f, Math::Point(0.25f, 0.2f - h), 1.0f, Gfx::TEXT_ALIGN_LEFT, 0); + Gfx::VertexCol vertex[4] = + { + Gfx::VertexCol(Math::Vector(p1.x, p1.y, 0.0f), color[1], color[2]), + Gfx::VertexCol(Math::Vector(p1.x, p2.y, 0.0f), color[0], color[2]), + Gfx::VertexCol(Math::Vector(p2.x, p1.y, 0.0f), color[1], color[2]), + Gfx::VertexCol(Math::Vector(p2.x, p2.y, 0.0f), color[0], color[2]) + }; - return true; + m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, vertex, 4); + AddStatisticTriangle(2); } -Math::IntSize Gfx::CEngine::GetWindowSize() +void Gfx::CEngine::DrawBackgroundImageQuarter(Math::Point p1, Math::Point p2, const std::string& name) { - return m_size; + Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal + + float u1, u2, v1, v2; + if (m_backgroundFull) + { + u1 = 0.0f; + v1 = 0.0f; + u2 = 1.0f; + v2 = 1.0f; + + if (m_backgroundQuarter) + { + u1 += 0.5f/512.0f; + v1 += 0.5f/384.0f; + u2 -= 0.5f/512.0f; + v2 -= 0.5f/384.0f; + } + } + else + { + float h = 0.5f; // visible area vertically (1=all) + float a = m_eyeDirV-Math::PI*0.15f; + if (a > Math::PI ) a -= Math::PI*2.0f; // a = -Math::PI..Math::PI + if (a > Math::PI/4.0f) a = Math::PI/4.0f; + if (a < -Math::PI/4.0f) a = -Math::PI/4.0f; + + u1 = -m_eyeDirH/Math::PI; + u2 = u1+1.0f/Math::PI; + + v1 = (1.0f-h)*(0.5f+a/(2.0f*Math::PI/4.0f))+0.1f; + v2 = v1+h; + } + + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); + m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + + SetTexture(name); + SetState(Gfx::ENG_RSTATE_WRAP); + + m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface); + m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProjInterface); + m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_matWorldInterface); + + Gfx::Vertex vertex[4] = + { + 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, vertex, 4); + AddStatisticTriangle(2); } -Math::IntSize Gfx::CEngine::GetLastWindowSize() +void QuarterName(std::string& buffer, const std::string& name, int quarter) { - return m_lastSize; + size_t pos = name.find('.'); + if (pos == std::string::npos) + { + buffer = name; + return; + } + + buffer = name.substr(0, pos) + std::string(1, static_cast('a' + quarter)) + name.substr(pos); } -/** 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) +void Gfx::CEngine::DrawBackgroundImage() { - return Math::Point( static_cast(pos.x) / static_cast(m_size.w), - 1.0f - static_cast(pos.y) / static_cast(m_size.h) ); + Math::Point p1, p2; + std::string name; + + if (m_backgroundQuarter) + { + p1.x = 0.0f; + p1.y = 0.5f; + p2.x = 0.5f; + p2.y = 1.0f; + QuarterName(name, m_backgroundName, 0); + DrawBackgroundImageQuarter(p1, p2, name); + + p1.x = 0.5f; + p1.y = 0.5f; + p2.x = 1.0f; + p2.y = 1.0f; + QuarterName(name, m_backgroundName, 1); + DrawBackgroundImageQuarter(p1, p2, name); + + p1.x = 0.0f; + p1.y = 0.0f; + p2.x = 0.5f; + p2.y = 0.5f; + QuarterName(name, m_backgroundName, 2); + DrawBackgroundImageQuarter(p1, p2, name); + + p1.x = 0.5f; + p1.y = 0.0f; + p2.x = 1.0f; + p2.y = 0.5f; + QuarterName(name, m_backgroundName, 3); + DrawBackgroundImageQuarter(p1, p2, name); + } + else + { + p1.x = 0.0f; + p1.y = 0.0f; + p2.x = 1.0f; + p2.y = 1.0f; + DrawBackgroundImageQuarter(p1, p2, m_backgroundName); + } } -Math::IntPoint Gfx::CEngine::InterfaceToWindowCoords(Math::Point pos) +void Gfx::CEngine::DrawPlanet() { - return Math::IntPoint(static_cast(pos.x * m_size.w), - static_cast((1.0f - pos.y) * m_size.h)); + if (! m_planet->PlanetExist()) return; + + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); + m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + + m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface); + m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProjInterface); + m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_matWorldInterface); + + m_planet->Draw(); // draws the planets } -Math::Size Gfx::CEngine::WindowToInterfaceSize(Math::IntSize size) +void Gfx::CEngine::DrawForegroundImage() { - return Math::Size( static_cast(size.w) / static_cast(m_size.w), - static_cast(size.h) / static_cast(m_size.h) ); + if (m_foregroundImageName.empty()) return; + + Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal + + Math::Point p1(0.0f, 0.0f); + Math::Point p2(1.0f, 1.0f); + + float u1 = -m_eyeDirH/(Math::PI*0.6f)+Math::PI*0.5f; + float u2 = u1+0.50f; + + float v1 = 0.2f; + float v2 = 1.0f; + + + Gfx::Vertex vertex[4] = + { + 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->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); + m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false ); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + + SetTexture(m_foregroundImageName); + SetState(Gfx::ENG_RSTATE_CLAMP | Gfx::ENG_RSTATE_TTEXTURE_BLACK); + + m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface); + m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProjInterface); + m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_matWorldInterface); + + m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, vertex, 4); + AddStatisticTriangle(2); } -Math::IntSize Gfx::CEngine::InterfaceToWindowSize(Math::Size size) +void Gfx::CEngine::DrawOverColor() { - return Math::IntSize(static_cast(size.w * m_size.w), - static_cast(size.h * m_size.h)); + if (! m_stateColor) return; + + // TODO: fuzzy compare? + if ( (m_overColor == Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f) && m_overMode == Gfx::ENG_RSTATE_TCOLOR_BLACK) || + (m_overColor == Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f) && m_overMode == Gfx::ENG_RSTATE_TCOLOR_WHITE) ) return; + + Math::Point p1(0.0f, 0.0f); + Math::Point p2(1.0f, 1.0f); + + Gfx::Color color[3] = + { + m_overColor, + m_overColor, + Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f) + }; + + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); + m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false); + + SetState(m_overMode); + + m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface); + m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProjInterface); + m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_matWorldInterface); + + Gfx::VertexCol vertex[4] = + { + Gfx::VertexCol(Math::Vector(p1.x, p1.y, 0.0f), color[1],color[2]), + Gfx::VertexCol(Math::Vector(p1.x, p2.y, 0.0f), color[0],color[2]), + Gfx::VertexCol(Math::Vector(p2.x, p1.y, 0.0f), color[1],color[2]), + Gfx::VertexCol(Math::Vector(p2.x, p2.y, 0.0f), color[0],color[2]) + }; + + m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, vertex, 4); + AddStatisticTriangle(2); } -std::string Gfx::CEngine::GetTextureDir() +void Gfx::CEngine::DrawHighlight() { - return m_texPath; + Math::Point min, max; + min.x = 1000000.0f; + min.y = 1000000.0f; + max.x = -1000000.0f; + max.y = -1000000.0f; + + int i = 0; + while (m_highlightRank[i] != -1) + { + Math::Point omin, omax; + if (GetBBox2D(m_highlightRank[i++], omin, omax)) + { + min.x = Math::Min(min.x, omin.x); + min.y = Math::Min(min.y, omin.y); + max.x = Math::Max(max.x, omax.x); + max.y = Math::Max(max.y, omax.y); + } + } + + if ( min.x == 1000000.0f || + min.y == 1000000.0f || + max.x == -1000000.0f || + max.y == -1000000.0f ) + { + m_highlight = false; // not highlighted + } + else + { + m_highlightP1 = min; + m_highlightP2 = max; + m_highlight = true; + } + + // TODO: draw highlight! } void Gfx::CEngine::DrawMouse() @@ -752,179 +2684,3 @@ void Gfx::CEngine::DrawMouseSprite(Math::Point pos, Math::Point size, int icon) m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, vertex, 4); AddStatisticTriangle(2); } - -bool Gfx::CEngine::GetPause() -{ - return m_pause; -} - -Math::Vector Gfx::CEngine::GetLookatPt() -{ - return m_lookatPt; -} - -Math::Vector Gfx::CEngine::GetEyePt() -{ - return m_eyePt; -} - -void Gfx::CEngine::SetMouseVisible(bool visible) -{ - m_mouseVisible = visible; -} - -bool Gfx::CEngine::GetMouseVisible() -{ - return m_mouseVisible; -} - -void Gfx::CEngine::SetMousePos(Math::Point pos) -{ - m_mousePos = pos; -} - -Math::Point Gfx::CEngine::GetMousePos() -{ - return m_mousePos; -} - -void Gfx::CEngine::SetMouseType(Gfx::EngineMouseType type) -{ - m_mouseType = type; -} - -Gfx::EngineMouseType Gfx::CEngine::GetMouseType() -{ - return m_mouseType; -} - -void Gfx::CEngine::AddStatisticTriangle(int count) -{ - m_statisticTriangle += count; -} - -void Gfx::CEngine::SetShowStat(bool show) -{ - m_showStats = show; -} - -bool Gfx::CEngine::GetShowStat() -{ - return m_showStats; -} - -void Gfx::CEngine::SetFocus(float focus) -{ - m_focus = focus; -} - - -void Gfx::CEngine::SetOverColor(const Gfx::Color& color, int mode) -{ - // TODO! -} - -void Gfx::CEngine::SetFogColor(const Gfx::Color& color, int rank) -{ - // TODO! -} - -Gfx::Color Gfx::CEngine::GetFogColor(int rank) -{ - // TODO! - return Gfx::Color(); -} - -void Gfx::CEngine::SetViewParams(const Math::Vector& eyePt, const Math::Vector& lookatPt, - const Math::Vector& upVec, float eyeDistance) -{ - // TODO! -} - -void Gfx::CEngine::SetRankView(int rank) -{ - m_rankView = rank; -} - -float Gfx::CEngine::GetEyeDirH() -{ - return m_eyeDirH; -} - -float Gfx::CEngine::GetEyeDirV() -{ - return m_eyeDirV; -} - -float Gfx::CEngine::GetClippingDistance() -{ - return m_clippingDistance; -} - -bool Gfx::CEngine::GetGroundSpot() -{ - return m_groundSpotVisible; -} - -void Gfx::CEngine::SetTerrain(Gfx::CTerrain* terrain) -{ - m_terrain = terrain; -} - -void Gfx::CEngine::SetTerrainVision(float vision) -{ - // TODO! -} - -bool Gfx::CEngine::LoadTexture(const std::string& name, int stage) -{ - // TODO! - return true; -} - -float Gfx::CEngine::ParticleAdapt(float factor) -{ - // TODO! - return 0.0f; -} - -bool Gfx::CEngine::SetObjectType(int objRank, Gfx::EngineObjectType type) -{ - // TODO! - return true; -} - -bool Gfx::CEngine::SetObjectTransform(int objRank, const Math::Matrix& transform) -{ - // TODO! - return true; -} - -int Gfx::CEngine::CreateObject() -{ - // TODO! - return 0; -} - -bool Gfx::CEngine::DeleteObject(int objRank) -{ - // TODO! - return true; -} - -int Gfx::CEngine::GroundMarkCreate(Math::Vector pos, float radius, float delay1, float delay2, float delay3, int dx, int dy, char* table) -{ - // TODO! - return 0; -} - -bool Gfx::CEngine::AddQuick(int objRank, const Gfx::EngineObjLevel5& buffer, std::string texName1, std::string texName2, float min, float max, bool globalUpdate) -{ - // TODO! - return false; -} - -void Gfx::CEngine::Update() -{ - // TODO! -} diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index e61aca65..d01a679e 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -1,5 +1,5 @@ // * This file is part of the COLOBOT source code -// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2001-2008, Daniel ROUX& EPSITEC SA, www.epsitec.ch // * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify @@ -41,7 +41,7 @@ class CApplication; class CInstanceManager; class CObject; -class CSound; +class CSoundInterface; namespace Gfx { @@ -310,12 +310,14 @@ struct EngineGroundSpot \brief Phase of life of an EngineGroundMark */ enum EngineGroundMarkPhase { + //! Null phase + ENG_GR_MARK_PHASE_NULL = 0, //! Increase ENG_GR_MARK_PHASE_INC = 1, //! Fixed ENG_GR_MARK_PHASE_FIX = 2, //! Decrease - ENG_GR_MARK_PHASE_DEC = 2 + ENG_GR_MARK_PHASE_DEC = 3 }; /** @@ -526,17 +528,24 @@ struct EngineMouse class CEngine { public: - CEngine(CInstanceManager *iMan, CApplication *app); + CEngine(CInstanceManager* iMan, CApplication* app); ~CEngine(); //! Returns the last error encountered std::string GetError(); //! Sets the device to be used - void SetDevice(Gfx::CDevice *device); + void SetDevice(Gfx::CDevice* device); //! Returns the current device Gfx::CDevice* GetDevice(); + //! Sets the terrain object + void SetTerrain(Gfx::CTerrain* terrain); + + //! Returns the text rendering engine + CText* GetText(); + + //! Performs the initialization; must be called after device was set bool Create(); //! Frees all resources before exit @@ -545,16 +554,68 @@ public: //! Resets some states and flushes textures after device was changed (e.g. resoulution changed) void ResetAfterDeviceChanged(); - void SetTerrain(Gfx::CTerrain* terrain); + + //! Called once per frame, the call is the entry point for rendering + void Render(); + //! Processes incoming event - bool ProcessEvent(const Event &event); + bool ProcessEvent(const Event& event); - //! Renders a single frame - bool Render(); + //! Called once per frame, the call is the entry point for animating the scene + void FrameMove(float rTime); + //! Evolved throughout the game + void StepSimulation(float rTime); + //! Initialize timestamps at the beginning of animation + void TimeInit(); + //! Suspend animation + void TimeEnterGel(); + //! Resume animation + void TimeExitGel(); + //! Returns the relative time since last animation update + float TimeGet(); + + + //! Writes a screenshot containing the current frame + bool WriteScreenShot(const std::string& fileName, int width, int height); + + + //! Reads settings from INI + bool ReadSettings(); + //! Writes settings to INI + bool WriteSettings(); + + //@{ + //! Management of game pause mode + void SetPause(bool pause); + bool GetPause(); + //@} + + //@{ + //! Management of lock for the duration of movie sequence + void SetMovieLock(bool lock); + bool GetMovieLock(); + //@} + + //@{ + //! Management of displaying statistic information + void SetShowStats(bool show); + bool GetShowStats(); + //@} + + //! Enables/disables rendering + void SetRenderEnable(bool enable); + + //! Returns current size of viewport window + Math::IntSize GetWindowSize(); + //! Returns the last size of viewport window + Math::IntSize GetLastWindowSize(); //! Converts window coords to interface coords + /** 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 WindowToInterfaceCoords(Math::IntPoint pos); //! Converts interface coords to window coords Math::IntPoint InterfaceToWindowCoords(Math::Point pos); @@ -564,83 +625,51 @@ public: //! Converts interface size to window size Math::IntSize InterfaceToWindowSize(Math::Size size); + //! Returns the name of directory with textures std::string GetTextureDir(); - bool WriteProfile(); - - void SetPause(bool pause); - bool GetPause(); - - void SetMovieLock(bool lock); - bool GetMovieLock(); - - void SetShowStat(bool show); - bool GetShowStat(); - - void SetRenderEnable(bool enable); - - int OneTimeSceneInit(); - int InitDeviceObjects(); - int DeleteDeviceObjects(); - int RestoreSurfaces(); - int FrameMove(float rTime); - void StepSimulation(float rTime); - int FinalCleanup(); + //! Increments the triangle counter for the current frame void AddStatisticTriangle(int nb); + //! Returns the number of triangles in current frame int GetStatisticTriangle(); - void SetHiliteRank(int *rankList); - bool GetHilite(Math::Point &p1, Math::Point &p2); - bool GetSpriteCoord(int &x, int &y); - void SetInfoText(int line, char* text); - char* GetInfoText(int line); - void FirstExecuteAdapt(bool first); - bool GetFullScreen(); - Math::Matrix* GetMatView(); - Math::Matrix* GetMatLeftView(); - Math::Matrix* GetMatRightView(); + /* *************** Object management *************** */ - void TimeInit(); - void TimeEnterGel(); - void TimeExitGel(); - float TimeGet(); - - int GetRestCreate(); int CreateObject(); void FlushObject(); bool DeleteObject(int objRank); bool SetDrawWorld(int objRank, bool draw); bool SetDrawFront(int objRank, bool draw); - bool AddTriangle(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material &mat, + bool AddTriangle(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material& mat, int state, std::string texName1, std::string texName2, float min, float max, bool globalUpdate); - bool AddSurface(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material &mat, + bool AddSurface(int objRank, Gfx::VertexTex2* vertex, int nb, const Gfx::Material& mat, int state, std::string texName1, std::string texName2, float min, float max, bool globalUpdate); bool AddQuick(int objRank, const Gfx::EngineObjLevel5& buffer, std::string texName1, std::string texName2, float min, float max, bool globalUpdate); - Gfx::EngineObjLevel5* SearchTriangle(int objRank, const Gfx::Material &mat, + Gfx::EngineObjLevel5* SearchTriangle(int objRank, const Gfx::Material& mat, int state, std::string texName1, std::string texName2, float min, float max); void ChangeLOD(); - bool ChangeSecondTexture(int objRank, char* texName2); + bool ChangeSecondTexture(int objRank, const std::string& texName2); int GetTotalTriangles(int objRank); int GetTriangles(int objRank, float min, float max, Gfx::EngineTriangle* buffer, int size, float percent); - bool GetBBox(int objRank, Math::Vector &min, Math::Vector &max); - bool ChangeTextureMapping(int objRank, const Gfx::Material &mat, int state, - const std::string &texName1, const std::string &texName2, + bool GetBBox(int objRank, Math::Vector& min, Math::Vector& max); + bool ChangeTextureMapping(int objRank, const Gfx::Material& mat, int state, + const std::string& texName1, const std::string& texName2, float min, float max, Gfx::EngineTextureMapping mode, float au, float bu, float av, float bv); - bool TrackTextureMapping(int objRank, const Gfx::Material &mat, int state, - const std::string &texName1, const std::string &texName2, + bool TrackTextureMapping(int objRank, const Gfx::Material& mat, int state, + const std::string& texName1, const std::string& texName2, float min, float max, Gfx::EngineTextureMapping mode, float pos, float factor, float tl, float ts, float tt); - bool SetObjectTransform(int objRank, const Math::Matrix &transform); - bool GetObjectTransform(int objRank, Math::Matrix &transform); + bool SetObjectTransform(int objRank, const Math::Matrix& transform); + bool GetObjectTransform(int objRank, Math::Matrix& transform); bool SetObjectType(int objRank, Gfx::EngineObjectType type); Gfx::EngineObjectType GetObjectType(int objRank); bool SetObjectTransparency(int objRank, float value); @@ -649,20 +678,25 @@ public: void ShadowDelete(int objRank); bool SetObjectShadowHide(int objRank, bool hide); bool SetObjectShadowType(int objRank, Gfx::EngineShadowType type); - bool SetObjectShadowPos(int objRank, const Math::Vector &pos); - bool SetObjectShadowNormal(int objRank, const Math::Vector &n); + bool SetObjectShadowPos(int objRank, const Math::Vector& pos); + bool SetObjectShadowNormal(int objRank, const Math::Vector& n); bool SetObjectShadowAngle(int objRank, float angle); bool SetObjectShadowRadius(int objRank, float radius); bool SetObjectShadowIntensity(int objRank, float intensity); bool SetObjectShadowHeight(int objRank, float h); float GetObjectShadowRadius(int objRank); + //! Lists the ranks of objects and subobjects selected + void SetHighlightRank(int* rankList); + //! Returns the highlighted rectangle + bool GetHighlight(Math::Point& p1, Math::Point& p2); + void GroundSpotFlush(); int GroundSpotCreate(); void GroundSpotDelete(int rank); - bool SetObjectGroundSpotPos(int rank, const Math::Vector &pos); + bool SetObjectGroundSpotPos(int rank, const Math::Vector& pos); bool SetObjectGroundSpotRadius(int rank, float radius); - bool SetObjectGroundSpotColor(int rank, const Gfx::Color &color); + bool SetObjectGroundSpotColor(int rank, const Gfx::Color& color); bool SetObjectGroundSpotMinMax(int rank, float min, float max); bool SetObjectGroundSpotSmooth(int rank, float smooth); @@ -671,217 +705,347 @@ public: int dx, int dy, char* table); bool GroundMarkDelete(int rank); + //! Updates the state after creating objects void Update(); - void SetViewParams(const Math::Vector &eyePt, const Math::Vector &lookatPt, - const Math::Vector &upVec, float eyeDistance); - Gfx::Texture CreateTexture(const std::string &texName, - const Gfx::TextureCreateParams ¶ms); - Gfx::Texture CreateTexture(const std::string &texName); - void DestroyTexture(const std::string &texName); + /* *************** Mode setting *************** */ - bool LoadTexture(const std::string &name, int stage = 0); + //! Sets the current rendering state + void SetState(int state, const Gfx::Color& color = Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)); + + //! Sets the current material + void SetMaterial(const Gfx::Material& mat); + + //! Specifies the location and direction of view + void SetViewParams(const Math::Vector& eyePt, const Math::Vector& lookatPt, + const Math::Vector& upVec, float eyeDistance); + + Gfx::Texture CreateTexture(const std::string& texName, + const Gfx::TextureCreateParams& params); + Gfx::Texture CreateTexture(const std::string& texName); + void DestroyTexture(const std::string& texName); + bool LoadTexture(const std::string& name, int stage = 0); bool LoadAllTextures(); + bool SetTexture(const std::string& name, int stage = 0); + //@{ + //! Border management (distance limits) depends of the resolution (LOD = level-of-detail) void SetLimitLOD(int rank, float limit); float GetLimitLOD(int rank, bool last=false); + //@} + //! Defines of the distance field of vision void SetTerrainVision(float vision); + //@{ + //! Management of camera angle + /** + 0.75 = normal + 1.50 = wide-angle */ + void SetFocus(float focus); + float GetFocus(); + //@} + + //@{ + //! Management of the global mode of marking void SetGroundSpot(bool mode); bool GetGroundSpot(); + //@} + + //@{ + //! Management of the global mode of shading void SetShadow(bool mode); bool GetShadow(); + //@} + + //@{ + //! Management of the global mode of contamination void SetDirty(bool mode); bool GetDirty(); + //@} + + //@{ + //! Management of the global mode of horizontal fog patches void SetFog(bool mode); bool GetFog(); + //@} + + //! Indicates whether it is possible to give a color SetState bool GetStateColor(); + //@{ + //! Management of the global mode of secondary texturing void SetSecondTexture(int texNum); int GetSecondTexture(); + //@} + //@{ + //! Management of view mode void SetRankView(int rank); int GetRankView(); + //@} + //! Whether to draw the world void SetDrawWorld(bool draw); + + //! Whether to draw the world on the interface void SetDrawFront(bool draw); - void SetAmbientColor(const Gfx::Color &color, int rank = 0); + //@{ + //! Ambient color management + void SetAmbientColor(const Gfx::Color& color, int rank = 0); Gfx::Color GetAmbientColor(int rank = 0); + //@} - void SetWaterAddColor(const Gfx::Color &color); + //@{ + //! Color management under water + void SetWaterAddColor(const Gfx::Color& color); Gfx::Color GetWaterAddColor(); + //@} - void SetFogColor(const Gfx::Color &color, int rank = 0); + //@{ + //! Management of the fog color + void SetFogColor(const Gfx::Color& color, int rank = 0); Gfx::Color GetFogColor(int rank = 0); + //@} + //@{ + //! Management of the depth of field. + /** Beyond this distance, nothing is visible. + Shortly (according SetFogStart), one enters the fog. */ void SetDeepView(float length, int rank = 0, bool ref=false); float GetDeepView(int rank = 0); + //@} + + //@{ + //! Management the start of fog. + /** With 0.0, the fog from the point of view (fog max). + With 1.0, the fog from the depth of field (no fog). */ void SetFogStart(float start, int rank = 0); float GetFogStart(int rank = 0); + //@} - void SetBackground(const std::string &name, Gfx::Color up = Gfx::Color(), Gfx::Color down = Gfx::Color(), + //@{ + //! Management of the background image to use + void SetBackground(const std::string& name, Gfx::Color up = Gfx::Color(), Gfx::Color down = Gfx::Color(), Gfx::Color cloudUp = Gfx::Color(), Gfx::Color cloudDown = Gfx::Color(), bool full = false, bool quarter = false); - void GetBackground(const std::string &name, Gfx::Color &up, Gfx::Color &down, - Gfx::Color &cloudUp, Gfx::Color &cloudDown, - bool &full, bool &quarter); - void SetFrontsizeName(char *name); - void SetOverFront(bool front); - void SetOverColor(const Gfx::Color &color = Gfx::Color(), int mode = ENG_RSTATE_TCOLOR_BLACK); + void GetBackground(std::string& name, Gfx::Color& up, Gfx::Color& down, + Gfx::Color& cloudUp, Gfx::Color& cloudDown, + bool& full, bool& quarter); + //@} + //! Specifies the foreground image + void SetForegroundImageName(const std::string& name); + //! Specifies whether to draw the foreground + void SetOverFront(bool front); + //! Sets the foreground overlay color + void SetOverColor(const Gfx::Color& color = Gfx::Color(), int mode = ENG_RSTATE_TCOLOR_BLACK); + + //@{ + //! Management of the particle density void SetParticleDensity(float value); float GetParticleDensity(); + //@} + + //! Adapts particle factor according to particle density float ParticleAdapt(float factor); + //@{ + //! Management of the distance of clipping. void SetClippingDistance(float value); float GetClippingDistance(); + //@} + //@{ + //! Management of objects detals. void SetObjectDetail(float value); float GetObjectDetail(); + //@} + //@{ + //! The amount of management objects gadgets void SetGadgetQuantity(float value); float GetGadgetQuantity(); + //@} + //@{ + //! Management the quality of textures void SetTextureQuality(int value); int GetTextureQuality(); + //@} + //@{ + //! Management mode of toto void SetTotoMode(bool present); bool GetTotoMode(); + //@} + //@{ + //! Management the mode of foreground void SetLensMode(bool present); bool GetLensMode(); + //@} + //@{ + //! Management the mode of water void SetWaterMode(bool present); bool GetWaterMode(); + //@} void SetLightingMode(bool present); bool GetLightingMode(); + //@{ + //! Management the mode of sky void SetSkyMode(bool present); bool GetSkyMode(); + //@} + //@{ + //! Management the mode of background void SetBackForce(bool present); bool GetBackForce(); + //@} + //@{ + //! Management the mode of planets void SetPlanetMode(bool present); bool GetPlanetMode(); + //@} + //@{ + //! Managing the mode of dynamic lights. void SetLightMode(bool present); bool GetLightMode(); + //@} + //@{ + // TODO: move to more appropriate class ? + //! Management of the indentation mode while editing (CEdit) void SetEditIndentMode(bool autoIndent); bool GetEditIndentMode(); + //@} + //@{ + // TODO: move to more appropriate class ? + //! Management of tab indent when editing (CEdit) void SetEditIndentValue(int value); int GetEditIndentValue(); + //@} + //@{ + //! Management of game speed void SetSpeed(float speed); float GetSpeed(); + //@{ + //! Management of precision of robot tracks void SetTracePrecision(float factor); float GetTracePrecision(); + //@} - void SetFocus(float focus); - float GetFocus(); - Math::Vector GetEyePt(); - Math::Vector GetLookatPt(); - float GetEyeDirH(); - float GetEyeDirV(); - Math::IntSize GetWindowSize(); - Math::IntSize GetLastWindowSize(); - void UpdateMatProj(); - - void ApplyChange(); - - void FlushPressKey(); - void ResetKey(); - void SetKey(int keyRank, int option, int key); - int GetKey(int keyRank, int option); - - void SetJoystick(bool enable); - bool GetJoystick(); - - void SetDebugMode(bool mode); - bool GetDebugMode(); - bool GetSetupMode(); - - bool IsVisiblePoint(const Math::Vector &pos); - - int DetectObject(Math::Point mouse); - void SetState(int state, Gfx::Color color = Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f)); - void SetTexture(const std::string &name, int stage = 0); - void SetMaterial(const Gfx::Material &mat); - + //@{ + //! Management of mouse cursor visibility void SetMouseVisible(bool show); bool GetMouseVisible(); + //@} + + //@{ + //! Management of mouse cursor position void SetMousePos(Math::Point pos); Math::Point GetMousePos(); + //@} + + //@{ + //! Management of mouse cursor type void SetMouseType(Gfx::EngineMouseType type); Gfx::EngineMouseType GetMouseType(); + //@} - CText* GetText(); + //! Returns the view matrix + const Math::Matrix& GetMatView(); + //! Returns the camera center point + Math::Vector GetEyePt(); + //! Returns the camera target point + Math::Vector GetLookatPt(); + //! Returns the horizontal direction angle of view + float GetEyeDirH(); + //! Returns the vertical direction angle of view + float GetEyeDirV(); + //! Indicates whether a point is visible + bool IsVisiblePoint(const Math::Vector& pos); - bool ChangeColor(char *name, Gfx::Color colorRef1, Gfx::Color colorNew1, - Gfx::Color colorRef2, Gfx::Color colorNew2, - float tolerance1, float tolerance2, - Math::Point ts, Math::Point ti, - Math::Point *pExclu=0, float shift=0.0f, bool hSV=false); - bool OpenImage(char *name); - bool CopyImage(); - bool LoadImage(); - bool ScrollImage(int dx, int dy); - bool SetDot(int x, int y, Gfx::Color color); - bool CloseImage(); - bool WriteScreenShot(char *filename, int width, int height); - //bool GetRenderDC(HDC &hDC); - //bool ReleaseRenderDC(HDC &hDC); - //PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp); - //bool CreateBMPFile(LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC); + //! Resets the projection matrix after changes + void UpdateMatProj(); + + //! Updates the scene after a change of parameters + void ApplyChange(); protected: + //! Prepares the interface for 3D scene + void Draw3DScene(); + //! Draws the user interface over the scene + void DrawInterface(); - void SetUp3DView(); - bool Draw3DScene(); + //! Updates the textures used for drawing ground spot + void UpdateGroundSpotTextures(); - void SetUpInterfaceView(); - bool DrawInterface(); - - void DrawGroundSpot(); + //! Draws shadows void DrawShadow(); + //! Draws the gradient background void DrawBackground(); - void DrawBackgroundGradient(Gfx::Color up, Gfx::Color down); - void DrawBackgroundImageQuarter(Math::Point p1, Math::Point p2, char *name); + //! Draws the gradient background + void DrawBackgroundGradient(const Gfx::Color& up, const Gfx::Color& down); + //! Draws a portion of the image background + void DrawBackgroundImageQuarter(Math::Point p1, Math::Point p2, const std::string& name); + //! Draws the image background void DrawBackgroundImage(); + //! Draws all the planets void DrawPlanet(); - void DrawFrontsize(); + //! Draws the image foreground + void DrawForegroundImage(); + //! Draws the foreground color void DrawOverColor(); - void DrawHilite(); + //! Draws the rectangle of the object highlighted + void DrawHighlight(); + //! Draws the mouse cursor void DrawMouse(); + //! Draw part of mouse cursor sprite void DrawMouseSprite(Math::Point pos, Math::Point dim, int icon); - /* - Gfx::ObjLevel2* AddLevel1(Gfx::ObjLevel1 *&p1, char* texName1, char* texName2); - Gfx::ObjLevel3* AddLevel2(Gfx::ObjLevel2 *&p2, int objRank); - Gfx::ObjLevel4* AddLevel3(Gfx::ObjLevel3 *&p3, float min, float max); - Gfx::ObjLevel5* AddLevel4(Gfx::ObjLevel4 *&p4, int reserve); - Gfx::ObjLevel6* AddLevel5(Gfx::ObjLevel5 *&p5, Gfx::TriangleType type, const Gfx::Material &mat, int state, int nb);*/ - + //! Tests whether the given object is visible bool IsVisible(int objRank); + + //! Detects whether an object is affected by the mouse bool DetectBBox(int objRank, Math::Point mouse); - bool GetBBox2D(int objRank, Math::Point &min, Math::Point &max); - bool DetectTriangle(Math::Point mouse, Gfx::VertexTex2 *triangle, int objRank, float &dist); - bool TransformPoint(Math::Vector &p2D, int objRank, Math::Vector p3D); + + //! Compute and return the 2D box on screen of any object + bool GetBBox2D(int objRank, Math::Point& min, Math::Point& max); + + //! Detects the target object that is selected with the mouse + /** Returns the rank of the object or -1. */ + int DetectObject(Math::Point mouse); + + //! Detects whether the mouse is in a triangle. + bool DetectTriangle(Math::Point mouse, Gfx::VertexTex2* triangle, int objRank, float& dist); + + //! Transforms a 3D point (x, y, z) in 2D space (x, y, -) of the window + /** The coordinated p2D.z gives the distance. */ + bool TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p3D); + + //! Calculates the distances between the viewpoint and the origin of different objects void ComputeDistance(); + + //! Updates all the geometric parameters of objects void UpdateGeometry(); protected: CInstanceManager* m_iMan; CApplication* m_app; - CSound* m_sound; + CSoundInterface* m_sound; Gfx::CDevice* m_device; Gfx::CText* m_text; Gfx::CLightManager* m_lightMan; @@ -892,7 +1056,7 @@ protected: Gfx::CPlanet* m_planet; Gfx::CTerrain* m_terrain; - bool m_wasInit; + //! Last encountered error std::string m_error; //! Whether to show stats (FPS, etc) @@ -926,9 +1090,9 @@ protected: bool m_render; bool m_movieLock; - //! Current size of viewport + //! Current size of viewport window Math::IntSize m_size; - //! Previous size of viewport + //! Previous size of viewport window Math::IntSize m_lastSize; std::vector m_objectTree; @@ -950,7 +1114,6 @@ protected: Gfx::Color m_waterAddColor; int m_statisticTriangle; bool m_updateGeometry; - //char m_infoText[10][200]; int m_alphaMode; bool m_stateColor; bool m_forceStateColor; @@ -970,11 +1133,11 @@ protected: bool m_overFront; Gfx::Color m_overColor; int m_overMode; - std::string m_frontsizeName; + std::string m_foregroundImageName; bool m_drawWorld; bool m_drawFront; float m_limitLOD[2]; - float m_particuleDensity; + float m_particleDensity; float m_clippingDistance; float m_lastClippingDistance; float m_objectDetail; @@ -993,10 +1156,10 @@ protected: int m_editIndentValue; float m_tracePrecision; - int m_hiliteRank[100]; - bool m_hilite; - Math::Point m_hiliteP1; - Math::Point m_hiliteP2; + int m_highlightRank[100]; + bool m_highlight; + Math::Point m_highlightP1; + Math::Point m_highlightP2; int m_lastState; Gfx::Color m_lastColor; @@ -1015,12 +1178,6 @@ protected: Gfx::EngineMouseType m_mouseType; Math::Point m_mousePos; bool m_mouseVisible; - - //LPDIRECTDRAWSURFACE7 m_imageSurface; - //DDSURFACEDESC2 m_imageDDSD; - //WORD* m_imageCopy; - //int m_imageDX; - //int m_imageDY; }; }; // namespace Gfx diff --git a/src/object/object.h b/src/object/object.h index 38254120..4a4dcb0a 100644 --- a/src/object/object.h +++ b/src/object/object.h @@ -25,10 +25,6 @@ class CInstanceManager; -class CLight; -class CTerrain; -class CWater; -class CParticule; class CPhysics; class CBrain; class CMotion; @@ -40,6 +36,7 @@ class CScript; + // The father of all parts must always be the part number zero! const int OBJECTMAXPART = 40; @@ -306,7 +303,7 @@ enum ObjectMaterial struct ObjectPart { char bUsed; - int object; // number of the object in CD3DEngine + int object; // number of the object in CEngine int parentPart; // number of father part int masterParti; // master canal of the particle Math::Vector position; @@ -677,7 +674,7 @@ protected: CAuto* m_auto; CDisplayText* m_displayText; CRobotMain* m_main; - CSound* m_sound; + CSoundInterface* m_sound; CBotVar* m_botVar; CScript* m_runScript; From 7f80ca297154809523cd533edf1842ab1ae391aa Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sat, 11 Aug 2012 17:17:04 +0200 Subject: [PATCH 08/10] Render mode setting, refactoring - finished SetState in CEngine - refactored Size and IntSize back to Point and IntPoint - other minor changes in CEngine --- src/app/app.cpp | 6 +- src/app/app.h | 2 +- src/graphics/core/device.h | 6 +- src/graphics/core/texture.h | 4 +- src/graphics/engine/engine.cpp | 369 +++++++++++++++---------------- src/graphics/engine/engine.h | 126 ++++++----- src/graphics/engine/text.cpp | 64 +++--- src/graphics/engine/text.h | 7 +- src/graphics/opengl/gldevice.cpp | 6 +- src/math/intsize.h | 70 ------ src/math/size.h | 75 ------- 11 files changed, 298 insertions(+), 437 deletions(-) delete mode 100644 src/math/intsize.h delete mode 100644 src/math/size.h diff --git a/src/app/app.cpp b/src/app/app.cpp index e1169145..4f7120d1 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -285,7 +285,7 @@ bool CApplication::CreateVideoSurface() if (m_deviceConfig.hardwareAccel) SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1); - m_private->surface = SDL_SetVideoMode(m_deviceConfig.size.w, m_deviceConfig.size.h, + m_private->surface = SDL_SetVideoMode(m_deviceConfig.size.x, m_deviceConfig.size.y, m_deviceConfig.bpp, videoFlags); return true; @@ -761,7 +761,7 @@ Gfx::GLDeviceConfig CApplication::GetVideoConfig() return m_deviceConfig; } -VideoQueryResult CApplication::GetVideoResolutionList(std::vector &resolutions, +VideoQueryResult CApplication::GetVideoResolutionList(std::vector &resolutions, bool fullScreen, bool resizeable) { resolutions.clear(); @@ -799,7 +799,7 @@ VideoQueryResult CApplication::GetVideoResolutionList(std::vector for (int i = 0; modes[i] != NULL; ++i) - resolutions.push_back(Math::IntSize(modes[i]->w, modes[i]->h)); + resolutions.push_back(Math::IntPoint(modes[i]->w, modes[i]->h)); return VIDEO_QUERY_OK; } diff --git a/src/app/app.h b/src/app/app.h index e7ffd541..d3b13688 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -132,7 +132,7 @@ public: void Destroy(); //! Returns a list of possible video modes - VideoQueryResult GetVideoResolutionList(std::vector &resolutions, + VideoQueryResult GetVideoResolutionList(std::vector &resolutions, bool fullScreen, bool resizeable); //! Returns the current video mode diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h index 3ab86ddb..d4fcd261 100644 --- a/src/graphics/core/device.h +++ b/src/graphics/core/device.h @@ -25,7 +25,7 @@ #include "graphics/core/material.h" #include "graphics/core/texture.h" #include "graphics/core/vertex.h" -#include "math/intsize.h" +#include "math/intpoint.h" #include "math/matrix.h" #include @@ -46,7 +46,7 @@ namespace Gfx { struct DeviceConfig { //! Screen size - Math::IntSize size; + Math::IntPoint size; //! Bits per pixel int bpp; //! Full screen @@ -64,7 +64,7 @@ struct DeviceConfig //! Loads the default values inline void LoadDefault() { - size = Math::IntSize(800, 600); + size = Math::IntPoint(800, 600); bpp = 32; fullScreen = false; resizeable = false; diff --git a/src/graphics/core/texture.h b/src/graphics/core/texture.h index 8d6b0821..bb5b52f5 100644 --- a/src/graphics/core/texture.h +++ b/src/graphics/core/texture.h @@ -18,7 +18,7 @@ #pragma once -#include "math/intsize.h" +#include "math/intpoint.h" namespace Gfx { @@ -194,7 +194,7 @@ struct Texture //! ID of the texture in graphics engine unsigned int id; //! Size of texture - Math::IntSize size; + Math::IntPoint size; //! Whether the texture has alpha channel bool alpha; diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 4244fb29..04616365 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -80,9 +80,7 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_terrain = nullptr; m_focus = 0.75f; - m_baseTime = 0; - m_lastTime = 0; - m_absTime = 0.0f; + m_rankView = 0; m_ambientColor[0] = Gfx::Color(0.5f, 0.5f, 0.5f, 0.5f); @@ -147,15 +145,6 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_forceStateColor = true; m_stateColor = false; - m_blackSrcBlend[0] = 0; - m_blackDestBlend[0] = 0; - m_whiteSrcBlend[0] = 0; - m_whiteDestBlend[0] = 0; - m_diffuseSrcBlend[0] = 0; - m_diffuseDestBlend[0] = 0; - m_alphaSrcBlend[0] = 0; - m_alphaDestBlend[0] = 0; - m_updateGeometry = false; m_mice[Gfx::ENG_MOUSE_NORM] = Gfx::EngineMouse( 0, 1, 32, Gfx::ENG_RSTATE_TCOLOR_WHITE, Gfx::ENG_RSTATE_TCOLOR_BLACK, Math::Point( 1.0f, 1.0f)); @@ -188,8 +177,8 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_objectTree.reserve(LEVEL1_PREALLOCATE_COUNT); m_objects.reserve(OBJECT_PREALLOCATE_COUNT); - m_shadow.reserve(SHADOW_PREALLOCATE_COUNT); - m_groundSpot.reserve(GROUNDSPOT_PREALLOCATE_COUNT); + m_shadows.reserve(SHADOW_PREALLOCATE_COUNT); + m_groundSpots.reserve(GROUNDSPOT_PREALLOCATE_COUNT); } Gfx::CEngine::~CEngine() @@ -372,38 +361,6 @@ void Gfx::CEngine::StepSimulation(float rTime) m_app->StepSimulation(rTime); } -void Gfx::CEngine::TimeInit() -{ - /* TODO! - m_baseTime = timeGetTime(); - m_lastTime = 0; - m_absTime = 0.0f;*/ -} - -void Gfx::CEngine::TimeEnterGel() -{ - /* TODO! - m_stopTime = timeGetTime();*/ -} - -void Gfx::CEngine::TimeExitGel() -{ - /* TODO! - m_baseTime += timeGetTime() - m_stopTime;*/ -} - -float Gfx::CEngine::TimeGet() -{ - /* TODO! - float aTime = (timeGetTime()-m_baseTime)*0.001f; // in ms - float rTime = (aTime - m_lastTime)*m_speed; - m_absTime += rTime; - m_lastTime = aTime; - - return rTime;*/ - return 0.0f; -} - bool Gfx::CEngine::WriteScreenShot(const std::string& fileName, int width, int height) { // TODO! @@ -457,38 +414,38 @@ void Gfx::CEngine::SetRenderEnable(bool enable) m_render = enable; } -Math::IntSize Gfx::CEngine::GetWindowSize() +Math::IntPoint Gfx::CEngine::GetWindowSize() { return m_size; } -Math::IntSize Gfx::CEngine::GetLastWindowSize() +Math::IntPoint Gfx::CEngine::GetLastWindowSize() { return m_lastSize; } Math::Point Gfx::CEngine::WindowToInterfaceCoords(Math::IntPoint pos) { - return Math::Point( static_cast(pos.x) / static_cast(m_size.w), - 1.0f - static_cast(pos.y) / static_cast(m_size.h) ); + return Math::Point( static_cast(pos.x) / static_cast(m_size.x), + 1.0f - static_cast(pos.y) / static_cast(m_size.y) ); } Math::IntPoint Gfx::CEngine::InterfaceToWindowCoords(Math::Point pos) { - return Math::IntPoint(static_cast(pos.x * m_size.w), - static_cast((1.0f - pos.y) * m_size.h)); + return Math::IntPoint(static_cast(pos.x * m_size.x), + static_cast((1.0f - pos.y) * m_size.y)); } -Math::Size Gfx::CEngine::WindowToInterfaceSize(Math::IntSize size) +Math::Point Gfx::CEngine::WindowToInterfaceSize(Math::IntPoint size) { - return Math::Size( static_cast(size.w) / static_cast(m_size.w), - static_cast(size.h) / static_cast(m_size.h) ); + return Math::Point(static_cast(size.x) / static_cast(m_size.x), + static_cast(size.y) / static_cast(m_size.y)); } -Math::IntSize Gfx::CEngine::InterfaceToWindowSize(Math::Size size) +Math::IntPoint Gfx::CEngine::InterfaceToWindowSize(Math::Point size) { - return Math::IntSize(static_cast(size.w * m_size.w), - static_cast(size.h * m_size.h)); + return Math::IntPoint(static_cast(size.x * m_size.x), + static_cast(size.y * m_size.y)); } std::string Gfx::CEngine::GetTextureDir() @@ -874,7 +831,18 @@ bool Gfx::CEngine::IsVisible(int objRank) bool Gfx::CEngine::TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p3D) { - // TODO! + p3D = Math::Transform(m_objects[objRank].transform, p3D); + p3D = Math::Transform(m_matView, p3D); + + if (p3D.z < 2.0f) return false; // behind? + + p2D.x = (p3D.x/p3D.z)*m_matProj.Get(1,1); + p2D.y = (p3D.y/p3D.z)*m_matProj.Get(2,2); + p2D.z = p3D.z; + + p2D.x = (p2D.x+1.0f)/2.0f; // [-1..1] -> [0..1] + p2D.y = (p2D.y+1.0f)/2.0f; + return true; } @@ -888,13 +856,13 @@ bool Gfx::CEngine::TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p void Gfx::CEngine::SetState(int state, const Gfx::Color& color) { - if ( state == m_lastState && color == m_lastColor ) + if (state == m_lastState && color == m_lastColor) return; m_lastState = state; m_lastColor = color; - if ( m_alphaMode != 1 && (state & Gfx::ENG_RSTATE_ALPHA) ) + if (m_alphaMode != 1 && (state & Gfx::ENG_RSTATE_ALPHA)) { state &= ~Gfx::ENG_RSTATE_ALPHA; @@ -902,133 +870,150 @@ void Gfx::CEngine::SetState(int state, const Gfx::Color& color) state |= Gfx::ENG_RSTATE_TTEXTURE_BLACK; } - // TODO other modes & thorough testing - if (state & Gfx::ENG_RSTATE_TTEXTURE_BLACK) // The transparent black texture? + if (state & Gfx::ENG_RSTATE_TTEXTURE_BLACK) // transparent black texture? { m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); - m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); + + m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); + m_device->SetBlendFunc(Gfx::BLEND_ONE, Gfx::BLEND_INV_SRC_COLOR); + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); - m_device->SetBlendFunc(Gfx::BLEND_ONE, Gfx::BLEND_INV_SRC_COLOR); - m_device->SetTextureEnabled(0, true); m_device->SetTextureFactor(color); Gfx::TextureStageParams params; params.colorOperation = Gfx::TEX_MIX_OPER_MODULATE; params.colorArg1 = Gfx::TEX_MIX_ARG_TEXTURE; params.colorArg2 = Gfx::TEX_MIX_ARG_FACTOR; - params.alphaOperation = Gfx::TEX_MIX_OPER_MODULATE; + params.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT; // TODO: replace with src color ? + + m_device->SetTextureEnabled(0, true); m_device->SetTextureStageParams(0, params); } - else if (state & Gfx::ENG_RSTATE_TTEXTURE_WHITE) // The transparent white texture? + else if (state & Gfx::ENG_RSTATE_TTEXTURE_WHITE) // transparent white texture? { m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); - m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); + + m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); + m_device->SetBlendFunc(Gfx::BLEND_DST_COLOR, Gfx::BLEND_ZERO); + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); - m_device->SetBlendFunc(Gfx::BLEND_DST_COLOR, Gfx::BLEND_ZERO); - m_device->SetTextureEnabled(0, true); m_device->SetTextureFactor(color.Inverse()); Gfx::TextureStageParams params; params.colorOperation = Gfx::TEX_MIX_OPER_ADD; params.colorArg1 = Gfx::TEX_MIX_ARG_TEXTURE; params.colorArg2 = Gfx::TEX_MIX_ARG_FACTOR; - params.alphaOperation = Gfx::TEX_MIX_OPER_MODULATE; + params.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT; // TODO: replace with src color ? + + m_device->SetTextureEnabled(0, true); m_device->SetTextureStageParams(0, params); } - else if (state & Gfx::ENG_RSTATE_TCOLOR_BLACK) // The transparent black color? + else if (state & Gfx::ENG_RSTATE_TCOLOR_BLACK) // transparent black color? { - m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); - m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); - m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); - m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); + m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false); + m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); m_device->SetBlendFunc(Gfx::BLEND_ONE, Gfx::BLEND_INV_SRC_COLOR); - - m_device->SetTextureFactor(color); - m_device->SetTextureEnabled(0, true); - m_device->SetTextureStageParams(0, Gfx::TextureStageParams()); } - else if (state & Gfx::ENG_RSTATE_TCOLOR_WHITE) // The transparent white color? + else if (state & Gfx::ENG_RSTATE_TCOLOR_WHITE) // transparent white color? { - m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); - m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); - m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); - m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); + m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false); + m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); m_device->SetBlendFunc(Gfx::BLEND_DST_COLOR, Gfx::BLEND_ZERO); - - m_device->SetTextureFactor(color.Inverse()); - m_device->SetTextureEnabled(0, true); - m_device->SetTextureStageParams(0, Gfx::TextureStageParams()); } else if (state & Gfx::ENG_RSTATE_TDIFFUSE) // diffuse color as transparent? { - /*m_device->SetRenderState(D3DRENDERSTATE_FOGENABLE, false); - m_device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, false); - m_device->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, true); - m_device->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, false); - m_device->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_diffuseSrcBlend[1]); - m_device->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_diffuseDestBlend[1]); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); + m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); - m_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - m_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);*/ + m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); + m_device->SetBlendFunc(Gfx::BLEND_SRC_ALPHA, Gfx::BLEND_DST_ALPHA); + + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); + + Gfx::TextureStageParams params; + params.colorOperation = Gfx::TEX_MIX_OPER_REPLACE; + params.colorArg1 = Gfx::TEX_MIX_ARG_TEXTURE; + params.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT; // TODO: replace with src color ? + + m_device->SetTextureEnabled(0, true); + m_device->SetTextureStageParams(0, params); + } + else if (state & Gfx::ENG_RSTATE_TEXT) // font rendering? + { + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false); // TODO: depth test setting elsewhere! + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); + m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); + + m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); + m_device->SetBlendFunc(Gfx::BLEND_SRC_ALPHA, Gfx::BLEND_INV_SRC_ALPHA); + + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); + + Gfx::TextureStageParams params; + params.colorOperation = Gfx::TEX_MIX_OPER_DEFAULT; // default modulate operation + params.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT; // default modulate operation + + m_device->SetTextureEnabled(0, true); + m_device->SetTextureStageParams(0, params); } else if (state & Gfx::ENG_RSTATE_ALPHA) // image with alpha channel? { - /*m_device->SetRenderState(D3DRENDERSTATE_FOGENABLE, true); - m_device->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, true); - m_device->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE, false); - m_device->SetRenderState(D3DRENDERSTATE_ALPHATESTENABLE, true); - m_device->SetRenderState(D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATER); - m_device->SetRenderState(D3DRENDERSTATE_ALPHAREF, (DWORD)(128)); - m_device->SetRenderState(D3DRENDERSTATE_SRCBLEND, m_alphaSrcBlend[1]); - m_device->SetRenderState(D3DRENDERSTATE_DESTBLEND, m_alphaSrcBlend[1]); + m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, false); + + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, true); + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, true); + + m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, true); + + m_device->SetAlphaTestFunc(Gfx::COMP_FUNC_GREATER, 0.5f); - m_device->SetRenderState(D3DRENDERSTATE_TEXTUREFACTOR, color); - m_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - m_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - m_device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);*/ - } - else if (state & Gfx::ENG_RSTATE_TEXT) - { - m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); - m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false); - m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); - m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, true); + + m_device->SetTextureFactor(color); + + Gfx::TextureStageParams params; + params.colorOperation = Gfx::TEX_MIX_OPER_MODULATE; + params.colorArg1 = Gfx::TEX_MIX_ARG_TEXTURE; + params.colorArg2 = Gfx::TEX_MIX_ARG_SRC_COLOR; + params.alphaOperation = Gfx::TEX_MIX_OPER_REPLACE; + params.alphaArg1 = Gfx::TEX_MIX_ARG_TEXTURE; m_device->SetTextureEnabled(0, true); - m_device->SetTextureStageParams(0, Gfx::TextureStageParams()); - - m_device->SetBlendFunc(Gfx::BLEND_SRC_ALPHA, Gfx::BLEND_INV_SRC_ALPHA); + m_device->SetTextureStageParams(0, params); } else // normal ? { - m_device->SetRenderState(Gfx::RENDER_STATE_FOG, true); - m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, true); - m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, false); m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); - m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); + m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, false); + + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, true); + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, true); + + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); + + Gfx::TextureStageParams params; + params.colorOperation = Gfx::TEX_MIX_OPER_DEFAULT; // default modulate + params.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT; // TODO: replace with src color ? m_device->SetTextureEnabled(0, true); - m_device->SetTextureStageParams(0, Gfx::TextureStageParams()); - - /*m_device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - m_device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);*/ + m_device->SetTextureStageParams(0, params); } if (state & Gfx::ENG_RSTATE_FOG) @@ -1040,21 +1025,25 @@ void Gfx::CEngine::SetState(int state, const Gfx::Color& color) if ( !m_groundSpotVisible && (state & Gfx::ENG_RSTATE_SECOND) != 0 ) second = false; if ( !m_dirty && (state & Gfx::ENG_RSTATE_SECOND) == 0 ) second = false; - if ( (state & ENG_RSTATE_DUAL_BLACK) && second ) + if ((state & ENG_RSTATE_DUAL_BLACK) && second) { - /*m_device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE); - m_device->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); - m_device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - m_device->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);*/ + Gfx::TextureStageParams params; + params.colorOperation = Gfx::TEX_MIX_OPER_MODULATE; + params.colorArg1 = Gfx::TEX_MIX_ARG_TEXTURE; + params.colorArg2 = Gfx::TEX_MIX_ARG_COMPUTED_COLOR; + params.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT; // TODO: ??? + m_device->SetTextureEnabled(0, true); + m_device->SetTextureStageParams(1, params); } - else if ( (state & ENG_RSTATE_DUAL_WHITE) && second ) + else if ((state & ENG_RSTATE_DUAL_WHITE) && second) { - /*m_device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_ADD); - m_device->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE); - m_device->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT); - m_device->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - m_device->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1);*/ + Gfx::TextureStageParams params; + params.colorOperation = Gfx::TEX_MIX_OPER_ADD; + params.colorArg1 = Gfx::TEX_MIX_ARG_TEXTURE; + params.colorArg2 = Gfx::TEX_MIX_ARG_COMPUTED_COLOR; + params.alphaOperation = Gfx::TEX_MIX_OPER_DEFAULT; // TODO: ??? + m_device->SetTextureEnabled(0, true); + m_device->SetTextureStageParams(1, params); } else { @@ -1063,18 +1052,25 @@ void Gfx::CEngine::SetState(int state, const Gfx::Color& color) if (state & Gfx::ENG_RSTATE_WRAP) { - /*m_device->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_WRAP); - m_device->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_WRAP);*/ + // TODO: separate function for setting wrap mode? + + Gfx::TextureStageParams p1 = m_device->GetTextureStageParams(0); + p1.wrapS = p1.wrapT = Gfx::TEX_WRAP_REPEAT; + m_device->SetTextureStageParams(0, p1); + + Gfx::TextureStageParams p2 = m_device->GetTextureStageParams(1); + p2.wrapS = p2.wrapT = Gfx::TEX_WRAP_REPEAT; + m_device->SetTextureStageParams(1, p2); } - else if (state & Gfx::ENG_RSTATE_CLAMP) + else // if (state & Gfx::ENG_RSTATE_CLAMP) or otherwise { - /*m_device->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); - m_device->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);*/ - } - else - { - /*m_device->SetTextureStageState(0, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP); - m_device->SetTextureStageState(1, D3DTSS_ADDRESS, D3DTADDRESS_CLAMP);*/ + Gfx::TextureStageParams p1 = m_device->GetTextureStageParams(0); + p1.wrapS = p1.wrapT = Gfx::TEX_WRAP_CLAMP; + m_device->SetTextureStageParams(0, p1); + + Gfx::TextureStageParams p2 = m_device->GetTextureStageParams(1); + p2.wrapS = p2.wrapT = Gfx::TEX_WRAP_CLAMP; + m_device->SetTextureStageParams(1, p2); } if (state & Gfx::ENG_RSTATE_2FACE) @@ -1197,13 +1193,13 @@ float Gfx::CEngine::GetLimitLOD(int rank, bool last) if (last) { limit = m_limitLOD[rank]; - limit *= m_lastSize.w/640.0f; // limit further if large window! + limit *= m_lastSize.x/640.0f; // limit further if large window! limit += m_limitLOD[0]*(m_lastObjectDetail*2.0f); } else { limit = m_limitLOD[rank]; - limit *= m_size.w/640.0f; // limit further if large window! + limit *= m_size.x/640.0f; // limit further if large window! limit += m_limitLOD[0]*(m_objectDetail*2.0f); } @@ -1222,7 +1218,7 @@ void Gfx::CEngine::SetFocus(float focus) m_focus = focus; m_size = m_app->GetVideoConfig().size; - float aspect = (static_cast(m_size.h)) / m_size.w; + float aspect = (static_cast(m_size.y)) / m_size.x; Math::LoadProjectionMatrix(m_matProj, m_focus, aspect, 0.5f, m_deepView[0]); } @@ -1698,15 +1694,6 @@ void Gfx::CEngine::ApplyChange() viewport, and renders the scene. */ void Gfx::CEngine::Render() { - /* TODO! - D3DObjLevel1* p1; - D3DObjLevel2* p2; - D3DObjLevel3* p3; - D3DObjLevel4* p4; - D3DObjLevel5* p5; - D3DVERTEX2* pv; - int l1, l2, l3, l4, l5, objRank;*/ - if (! m_render) return; m_statisticTriangle = 0; @@ -1729,19 +1716,27 @@ void Gfx::CEngine::Render() if (m_drawWorld) - { Draw3DScene(); - } DrawInterface(); + // End the scene m_device->EndScene(); } void Gfx::CEngine::Draw3DScene() { + /* TODO! + D3DObjLevel1* p1; + D3DObjLevel2* p2; + D3DObjLevel3* p3; + D3DObjLevel4* p4; + D3DObjLevel5* p5; + D3DVERTEX2* pv; + int l1, l2, l3, l4, l5, objRank;*/ + if (m_groundSpotVisible) UpdateGroundSpotTextures(); @@ -2153,11 +2148,11 @@ void Gfx::CEngine::DrawShadow() float endDeepView = m_deepView[m_rankView]; float lastIntensity = -1.0f; - for (int i = 0; i < static_cast( m_shadow.size() ); i++) + for (int i = 0; i < static_cast( m_shadows.size() ); i++) { - if (m_shadow[i].hide) continue; + if (m_shadows[i].hide) continue; - Math::Vector pos = m_shadow[i].pos; // pos = center of the shadow on the ground + Math::Vector pos = m_shadows[i].pos; // pos = center of the shadow on the ground if (m_eyePt.y == pos.y) continue; // camera at the same level? @@ -2169,7 +2164,7 @@ void Gfx::CEngine::DrawShadow() if (m_eyePt.y > pos.y) // camera on? { float height = m_eyePt.y-pos.y; - float h = m_shadow[i].radius; + float h = m_shadows[i].radius; float max = height*0.5f; if ( h > max ) h = max; if ( h > 4.0f ) h = 4.0f; @@ -2185,7 +2180,7 @@ void Gfx::CEngine::DrawShadow() else // camera underneath? { float height = pos.y-m_eyePt.y; - float h = m_shadow[i].radius; + float h = m_shadows[i].radius; float max = height*0.1f; if ( h > max ) h = max; if ( h > 4.0f ) h = 4.0f; @@ -2201,20 +2196,20 @@ void Gfx::CEngine::DrawShadow() // The hFactor decreases the intensity and size increases more // the object is high relative to the ground. - float hFactor = m_shadow[i].height/20.0f; + float hFactor = m_shadows[i].height/20.0f; if ( hFactor < 0.0f ) hFactor = 0.0f; if ( hFactor > 1.0f ) hFactor = 1.0f; hFactor = powf(1.0f-hFactor, 2.0f); if ( hFactor < 0.2f ) hFactor = 0.2f; - float radius = m_shadow[i].radius*1.5f; + float radius = m_shadows[i].radius*1.5f; radius *= 2.0f-hFactor; // greater if high radius *= 1.0f-d/D; // smaller if close Math::Vector corner[4]; - if (m_shadow[i].type == Gfx::ENG_SHADOW_NORM) + if (m_shadows[i].type == Gfx::ENG_SHADOW_NORM) { corner[0].x = +radius; corner[0].z = +radius; @@ -2239,27 +2234,27 @@ void Gfx::CEngine::DrawShadow() { Math::Point rot; - rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(radius, radius)); + rot = Math::RotatePoint(-m_shadows[i].angle, Math::Point(radius, radius)); corner[0].x = rot.x; corner[0].z = rot.y; corner[0].y = 0.0f; - rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(-radius, radius)); + rot = Math::RotatePoint(-m_shadows[i].angle, Math::Point(-radius, radius)); corner[1].x = rot.x; corner[1].z = rot.y; corner[1].y = 0.0f; - rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(radius, -radius)); + rot = Math::RotatePoint(-m_shadows[i].angle, Math::Point(radius, -radius)); corner[2].x = rot.x; corner[2].z = rot.y; corner[2].y = 0.0f; - rot = Math::RotatePoint(-m_shadow[i].angle, Math::Point(-radius, -radius)); + rot = Math::RotatePoint(-m_shadows[i].angle, Math::Point(-radius, -radius)); corner[3].x = rot.x; corner[3].z = rot.y; corner[3].y = 0.0f; - if (m_shadow[i].type == Gfx::ENG_SHADOW_WORM) + if (m_shadows[i].type == Gfx::ENG_SHADOW_WORM) { ts.x = 96.0f/256.0f; ti.x = 128.0f/256.0f; @@ -2271,10 +2266,10 @@ void Gfx::CEngine::DrawShadow() } } - corner[0] = Math::CrossProduct(corner[0], m_shadow[i].normal); - corner[1] = Math::CrossProduct(corner[1], m_shadow[i].normal); - corner[2] = Math::CrossProduct(corner[2], m_shadow[i].normal); - corner[3] = Math::CrossProduct(corner[3], m_shadow[i].normal); + corner[0] = Math::CrossProduct(corner[0], m_shadows[i].normal); + corner[1] = Math::CrossProduct(corner[1], m_shadows[i].normal); + corner[2] = Math::CrossProduct(corner[2], m_shadows[i].normal); + corner[3] = Math::CrossProduct(corner[3], m_shadows[i].normal); corner[0] += pos; corner[1] += pos; @@ -2292,7 +2287,7 @@ void Gfx::CEngine::DrawShadow() Gfx::Vertex(corner[2], n, Math::Point(ti.x, ti.y)) }; - float intensity = (0.5f+m_shadow[i].intensity*0.5f)*hFactor; + float intensity = (0.5f+m_shadows[i].intensity*0.5f)*hFactor; // Decreases the intensity of the shade if you're in the area // between the beginning and the end of the fog. diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index d01a679e..8f9338a4 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -19,17 +19,15 @@ #pragma once - +#include "app/system.h" #include "common/event.h" #include "graphics/core/color.h" #include "graphics/core/material.h" #include "graphics/core/texture.h" #include "graphics/core/vertex.h" #include "math/intpoint.h" -#include "math/intsize.h" #include "math/matrix.h" #include "math/point.h" -#include "math/size.h" #include "math/vector.h" @@ -567,15 +565,6 @@ public: //! Evolved throughout the game void StepSimulation(float rTime); - //! Initialize timestamps at the beginning of animation - void TimeInit(); - //! Suspend animation - void TimeEnterGel(); - //! Resume animation - void TimeExitGel(); - //! Returns the relative time since last animation update - float TimeGet(); - //! Writes a screenshot containing the current frame bool WriteScreenShot(const std::string& fileName, int width, int height); @@ -608,22 +597,24 @@ public: void SetRenderEnable(bool enable); //! Returns current size of viewport window - Math::IntSize GetWindowSize(); + Math::IntPoint GetWindowSize(); //! Returns the last size of viewport window - Math::IntSize GetLastWindowSize(); + Math::IntPoint GetLastWindowSize(); - //! Converts window coords to interface coords - /** Conversion of the position of the mouse from window coords to interface coords: - - x: 0=left, 1=right - - y: 0=down, 1=up */ + //@{ + //! Conversion functions between window and interface coordinates + /** Window coordinates are from top-left (0,0) to bottom-right (w,h) - size of window + Interface cords are from bottom-left (0,0) to top-right (1,1) - and do not depend on window size */ 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); + //@{ + //! Conversion functions between window and interface sizes + /** Unlike coordinate conversions, this is only scale conversion, not translation and scale. */ + Math::Point WindowToInterfaceSize(Math::IntPoint size); + Math::IntPoint InterfaceToWindowSize(Math::Point size); + //@} //! Returns the name of directory with textures std::string GetTextureDir(); @@ -1062,46 +1053,48 @@ protected: //! Whether to show stats (FPS, etc) bool m_showStats; - int m_blackSrcBlend[2]; - int m_blackDestBlend[2]; - int m_whiteSrcBlend[2]; - int m_whiteDestBlend[2]; - int m_diffuseSrcBlend[2]; - int m_diffuseDestBlend[2]; - int m_alphaSrcBlend[2]; - int m_alphaDestBlend[2]; - - Math::Matrix m_matProj; - Math::Matrix m_matLeftView; - Math::Matrix m_matRightView; - Math::Matrix m_matView; - float m_focus; - - Math::Matrix m_matWorldInterface; - Math::Matrix m_matProjInterface; - Math::Matrix m_matViewInterface; - - long m_baseTime; - long m_stopTime; - float m_absTime; - float m_lastTime; + //! Speed of animation float m_speed; + //! Pause mode bool m_pause; + //! Rendering enabled? bool m_render; + //! Lock for duration of movie? bool m_movieLock; - //! Current size of viewport window - Math::IntSize m_size; - //! Previous size of viewport window - Math::IntSize m_lastSize; + //! Projection matrix for 3D scene + Math::Matrix m_matProj; + //! View matrix for 3D scene + Math::Matrix m_matView; + //! Camera angle for 3D scene + float m_focus; + //! World matrix for 2D interface + Math::Matrix m_matWorldInterface; + //! Projection matrix for 2D interface + Math::Matrix m_matProjInterface; + //! View matrix for 2D interface + Math::Matrix m_matViewInterface; + + //! Current size of viewport window + Math::IntPoint m_size; + //! Previous size of viewport window + Math::IntPoint m_lastSize; + + //! Root of tree object structure (level 1 list) std::vector m_objectTree; + //! Object parameters std::vector m_objects; - std::vector m_shadow; - std::vector m_groundSpot; + //! Shadow list + std::vector m_shadows; + //! Ground spot list + std::vector m_groundSpots; + //! Ground mark Gfx::EngineGroundMark m_groundMark; + //! Location of camera Math::Vector m_eyePt; + //! Camera target Math::Vector m_lookatPt; float m_eyeDirH; float m_eyeDirV; @@ -1156,28 +1149,47 @@ protected: int m_editIndentValue; float m_tracePrecision; + //! Ranks of highlighted objects int m_highlightRank[100]; + //! Highlight visible? bool m_highlight; + //@{ + //! Highlight rectangle points Math::Point m_highlightP1; Math::Point m_highlightP2; + //@} - int m_lastState; - Gfx::Color m_lastColor; - char m_lastTexture[2][50]; - Gfx::Material m_lastMaterial; - + //! Texture directory name std::string m_texPath; + //! Default texture create params Gfx::TextureCreateParams m_defaultTexParams; + //! Map of loaded textures (by name) std::map m_texNameMap; + //! Reverse map of loaded textures (by texture) std::map m_revTexNameMap; + //! Mouse cursor definitions Gfx::EngineMouse m_mice[Gfx::ENG_MOUSE_COUNT]; + //! Texture with mouse cursors Gfx::Texture m_miceTexture; + //! Size of mouse cursor Math::Point m_mouseSize; + //! Type of mouse cursor Gfx::EngineMouseType m_mouseType; + //! Position of mouse in interface coords Math::Point m_mousePos; + //! Is mouse visible? bool m_mouseVisible; + + //! Last engine render state (-1 at the beginning of frame) + int m_lastState; + //! Last color set with render state + Gfx::Color m_lastColor; + //! Last texture names for 2 used texture stages + std::string m_lastTexture[2]; + //! Last material + Gfx::Material m_lastMaterial; }; }; // namespace Gfx diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 77515ad1..0a57026c 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -245,10 +245,10 @@ float Gfx::CText::GetAscent(Gfx::FontType font, float size) Gfx::CachedFont* cf = GetOrOpenFont(font, size); assert(cf != nullptr); - Math::IntSize wndSize; - wndSize.h = TTF_FontAscent(cf->font); - Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize); - return ifSize.h; + Math::IntPoint wndSize; + wndSize.y = TTF_FontAscent(cf->font); + Math::Point ifSize = m_engine->WindowToInterfaceSize(wndSize); + return ifSize.y; } float Gfx::CText::GetDescent(Gfx::FontType font, float size) @@ -257,10 +257,10 @@ float Gfx::CText::GetDescent(Gfx::FontType font, float size) Gfx::CachedFont* cf = GetOrOpenFont(font, size); assert(cf != nullptr); - Math::IntSize wndSize; - wndSize.h = TTF_FontDescent(cf->font); - Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize); - return ifSize.h; + Math::IntPoint wndSize; + wndSize.y = TTF_FontDescent(cf->font); + Math::Point ifSize = m_engine->WindowToInterfaceSize(wndSize); + return ifSize.y; } float Gfx::CText::GetHeight(Gfx::FontType font, float size) @@ -269,10 +269,10 @@ float Gfx::CText::GetHeight(Gfx::FontType font, float size) Gfx::CachedFont* cf = GetOrOpenFont(font, size); assert(cf != nullptr); - Math::IntSize wndSize; - wndSize.h = TTF_FontHeight(cf->font); - Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize); - return ifSize.h; + Math::IntPoint wndSize; + wndSize.y = TTF_FontHeight(cf->font); + Math::Point ifSize = m_engine->WindowToInterfaceSize(wndSize); + return ifSize.y; } @@ -315,10 +315,10 @@ float Gfx::CText::GetStringWidth(const std::string &text, Gfx::FontType font, fl Gfx::CachedFont* cf = GetOrOpenFont(font, size); assert(cf != nullptr); - Math::IntSize wndSize; - TTF_SizeUTF8(cf->font, text.c_str(), &wndSize.w, &wndSize.h); - Math::Size ifSize = m_engine->WindowToInterfaceSize(wndSize); - return ifSize.w; + Math::IntPoint wndSize; + TTF_SizeUTF8(cf->font, text.c_str(), &wndSize.x, &wndSize.y); + Math::Point ifSize = m_engine->WindowToInterfaceSize(wndSize); + return ifSize.x; } float Gfx::CText::GetCharWidth(Gfx::UTF8Char ch, Gfx::FontType font, float size, float offset) @@ -339,7 +339,7 @@ float Gfx::CText::GetCharWidth(Gfx::UTF8Char ch, Gfx::FontType font, float size, else tex = CreateCharTexture(ch, cf); - return tex.charSize.w; + return tex.charSize.x; } @@ -539,9 +539,9 @@ void Gfx::CText::DrawString(const std::string &text, const std::vector(format[fmtIndex] & Gfx::FONT_MASK_HIGHLIGHT); if (hl != Gfx::FONT_HIGHLIGHT_NONE) { - Math::Size charSize; - charSize.w = GetCharWidth(ch, font, size, offset); - charSize.h = GetHeight(font, size); + Math::Point charSize; + charSize.x = GetCharWidth(ch, font, size, offset); + charSize.y = GetHeight(font, size); DrawHighlight(hl, pos, charSize); } @@ -580,7 +580,7 @@ void Gfx::CText::DrawString(const std::string &text, Gfx::FontType font, } } -void Gfx::CText::DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Size size) +void Gfx::CText::DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Point size) { // Gradient colors Gfx::Color grad[4]; @@ -622,16 +622,16 @@ void Gfx::CText::DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Siz return; } - Math::IntSize vsize = m_engine->GetWindowSize(); + Math::IntPoint vsize = m_engine->GetWindowSize(); float h = 0.0f; - if (vsize.h <= 768.0f) // 1024x768 or less? - h = 1.01f / vsize.h; // 1 pixel + if (vsize.y <= 768.0f) // 1024x768 or less? + h = 1.01f / vsize.y; // 1 pixel else // more than 1024x768? - h = 2.0f / vsize.h; // 2 pixels + h = 2.0f / vsize.y; // 2 pixels Math::Point p1, p2; p1.x = pos.x; - p2.x = pos.x + size.w; + p2.x = pos.x + size.x; if (hl == Gfx::FONT_HIGHLIGHT_LINK) { @@ -641,7 +641,7 @@ void Gfx::CText::DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Siz else { p1.y = pos.y; - p2.y = pos.y + size.h; + p2.y = pos.y + size.y; } m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false); @@ -690,8 +690,8 @@ void Gfx::CText::DrawChar(Gfx::UTF8Char ch, Gfx::FontType font, float size, Math m_device->SetRenderState(Gfx::RENDER_STATE_CULLING, false); - Math::Point p1(pos.x, pos.y + tex.charSize.h - tex.texSize.h); - Math::Point p2(pos.x + tex.texSize.w, pos.y + tex.charSize.h); + Math::Point p1(pos.x, pos.y + tex.charSize.y - tex.texSize.y); + Math::Point p2(pos.x + tex.texSize.x, pos.y + tex.charSize.y); Math::Vector n(0.0f, 0.0f, -1.0f); // normal @@ -707,7 +707,7 @@ void Gfx::CText::DrawChar(Gfx::UTF8Char ch, Gfx::FontType font, float size, Math m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, quad, 4); m_engine->AddStatisticTriangle(2); - pos.x += tex.charSize.w; + pos.x += tex.charSize.x; } Gfx::CachedFont* Gfx::CText::GetOrOpenFont(Gfx::FontType font, float size) @@ -797,8 +797,8 @@ Gfx::CharTexture Gfx::CText::CreateCharTexture(Gfx::UTF8Char ch, Gfx::CachedFont } 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)); + texture.texSize = m_engine->WindowToInterfaceSize(Math::IntPoint(textureSurface->w, textureSurface->h)); + texture.charSize = m_engine->WindowToInterfaceSize(Math::IntPoint(textSurface->w, textSurface->h)); return texture; } diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h index 6209c39b..7e2f84b0 100644 --- a/src/graphics/engine/text.h +++ b/src/graphics/engine/text.h @@ -20,7 +20,6 @@ #pragma once #include "math/point.h" -#include "math/size.h" #include #include @@ -168,8 +167,8 @@ struct UTF8Char struct CharTexture { unsigned int id; - Math::Size texSize; - Math::Size charSize; + Math::Point texSize; + Math::Point charSize; CharTexture() : id(0) {} }; @@ -277,7 +276,7 @@ protected: 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 DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Size size); + void DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Point size); void DrawChar(Gfx::UTF8Char ch, Gfx::FontType font, float size, Math::Point &pos); protected: diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index cef372f9..4c36053b 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -122,7 +122,7 @@ bool Gfx::CGLDevice::Create() glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glViewport(0, 0, m_config.size.w, m_config.size.h); + glViewport(0, 0, m_config.size.x, m_config.size.y); m_lights = std::vector(GL_MAX_LIGHTS, Gfx::Light()); @@ -390,8 +390,8 @@ Gfx::Texture Gfx::CGLDevice::CreateTexture(ImageData *data, const Gfx::TextureCr Gfx::Texture result; result.valid = true; - result.size.w = data->surface->w; - result.size.h = data->surface->h; + result.size.x = data->surface->w; + result.size.y = data->surface->h; // Use & enable 1st texture stage glActiveTexture(GL_TEXTURE0); diff --git a/src/math/intsize.h b/src/math/intsize.h deleted file mode 100644 index c88f09ba..00000000 --- a/src/math/intsize.h +++ /dev/null @@ -1,70 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2012, Polish Portal of Colobot (PPC) -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -/** @defgroup MathIntSizeModule math/intsize.h - Contains the IntSize struct. - */ - -#pragma once - -#include "math/intpoint.h" - - -// Math module namespace -namespace Math -{ - -/* @{ */ // start of group - -/** \struct IntSize math/size.h - \brief 2D size with integer dimensions */ -struct IntSize -{ - //! Width - int w; - //! Height - int h; - - //! Constructs a zero size: (0,0) - inline IntSize() - { - LoadZero(); - } - - //! Constructs a size from given dimensions: (w,h) - inline explicit IntSize(int w, int h) - { - this->w = w; - this->h = h; - } - - //! Sets the zero size: (0,0) - inline void LoadZero() - { - w = h = 0; - } - - //! Converts Point to Size - inline static Math::IntSize FromIntPoint(Math::IntPoint p) - { - return Math::IntSize(p.x, p.y); - } -}; // struct Size - - -/* @} */ // end of group - -}; // namespace Math diff --git a/src/math/size.h b/src/math/size.h deleted file mode 100644 index 03cffaa5..00000000 --- a/src/math/size.h +++ /dev/null @@ -1,75 +0,0 @@ -// * This file is part of the COLOBOT source code -// * Copyright (C) 2012, Polish Portal of Colobot (PPC) -// * -// * This program is free software: you can redistribute it and/or modify -// * it under the terms of the GNU General Public License as published by -// * the Free Software Foundation, either version 3 of the License, or -// * (at your option) any later version. -// * -// * This program is distributed in the hope that it will be useful, -// * but WITHOUT ANY WARRANTY; without even the implied warranty of -// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// * GNU General Public License for more details. -// * -// * You should have received a copy of the GNU General Public License -// * along with this program. If not, see http://www.gnu.org/licenses/. - -/** @defgroup MathSizeModule math/size.h - Contains the Size struct. - */ - -#pragma once - -#include "math/point.h" - - -// Math module namespace -namespace Math -{ - -/* @{ */ // start of group - -/** \struct Size math/size.h - \brief 2D size - - Represents a 2D size (w, h). - Is separate from Math::Point to avoid confusion. - - */ -struct Size -{ - //! Width - float w; - //! Height - float h; - - //! Constructs a zero size: (0,0) - inline Size() - { - LoadZero(); - } - - //! Constructs a size from given dimensions: (w,h) - inline explicit Size(float w, float h) - { - this->w = w; - this->h = h; - } - - //! Sets the zero size: (0,0) - inline void LoadZero() - { - 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 - - -/* @} */ // end of group - -}; // namespace Math From 1996507fd3d4d9de90de99845b71a6bf3fbe62da Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sat, 11 Aug 2012 18:39:16 +0200 Subject: [PATCH 09/10] Documentation update - updated Doxyfile - added/changed file, dir and namespace descriptions - fixed some errors in doxygen tags --- Doxyfile | 1670 ++++++++++++++++--------------- src/app/README.txt | 7 +- src/app/app.h | 5 +- src/app/main.cpp | 5 +- src/app/system.h | 9 +- src/app/system_linux.h | 9 +- src/app/system_other.h | 9 +- src/app/system_windows.h | 9 +- src/common/README.txt | 7 +- src/common/logger.h | 12 +- src/graphics/README.txt | 13 +- src/graphics/core/README.txt | 13 +- src/graphics/core/color.h | 5 +- src/graphics/core/device.h | 5 +- src/graphics/core/light.h | 5 +- src/graphics/core/material.h | 5 +- src/graphics/core/texture.h | 5 +- src/graphics/core/vertex.h | 5 +- src/graphics/d3d/README.txt | 7 +- src/graphics/engine/README.txt | 17 +- src/graphics/engine/camera.h | 5 +- src/graphics/engine/cloud.h | 5 +- src/graphics/engine/engine.h | 5 +- src/graphics/engine/lightman.h | 5 +- src/graphics/engine/lightning.h | 5 +- src/graphics/engine/modelfile.h | 5 +- src/graphics/engine/particle.h | 5 +- src/graphics/engine/planet.h | 5 +- src/graphics/engine/pyro.h | 5 +- src/graphics/engine/terrain.h | 5 +- src/graphics/engine/text.h | 5 +- src/graphics/engine/water.h | 5 +- src/graphics/opengl/README.txt | 13 +- src/graphics/opengl/gldevice.h | 5 +- src/math/README.txt | 13 +- src/math/all.h | 9 +- src/math/const.h | 7 +- src/math/func.h | 21 +- src/math/geometry.h | 11 +- src/math/intpoint.h | 12 +- src/math/matrix.h | 24 +- src/math/point.h | 9 +- src/math/vector.h | 9 +- src/object/README.txt | 10 +- src/physics/README.txt | 7 +- src/sound/README.txt | 7 +- src/ui/README.txt | 7 +- 47 files changed, 1071 insertions(+), 975 deletions(-) diff --git a/Doxyfile b/Doxyfile index 9e4fe82d..cdbf278d 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,103 +1,103 @@ -# Doxyfile 1.8.0 +# Doxyfile 1.8.1.2 # This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project +# doxygen (www.doxygen.org) for a project. # -# All text after a hash (#) is considered a comment and will be ignored +# All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") +# Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 -# The PROJECT_NAME tag is a single word (or sequence of words) that should -# identify the project. Note that if you do not use Doxywizard you need +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = Colobot -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. -PROJECT_BRIEF = +PROJECT_BRIEF = -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. -PROJECT_LOGO = +PROJECT_LOGO = -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = "./doc" -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = "The $name class" \ @@ -112,246 +112,246 @@ ABBREVIATE_BRIEF = "The $name class" \ an \ the -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the # path to strip. -STRIP_FROM_PATH = +STRIP_FROM_PATH = -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. -STRIP_FROM_INC_PATH = +STRIP_FROM_INC_PATH = -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO -# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = +ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding -# "class=itcl::class" will allow you to use the command class in the +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. -TCL_SUBST = +TCL_SUBST = -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. -EXTENSION_MAPPING = +EXTENSION_MAPPING = -# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all -# comments according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you -# can mix doxygen, HTML, and XML commands with Markdown formatting. +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO -# If you use Microsoft's C++/CLI language, you should set this option to YES to +# If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and -# unions with only public data fields will be shown inline in the documentation -# of the scope in which they are defined (i.e. file, namespace, or group -# documentation), provided this scope is documented. If set to NO (the default), -# structs, classes, and unions are shown on a separate page (for HTML and Man +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 -# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be -# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given -# their name and scope. Since this can be an expensive process and often the -# same symbol appear multiple times in the code, doxygen keeps a cache of -# pre-resolved symbols. If the cache is too small doxygen will become slower. -# If the cache is too large, memory is wasted. The cache size is given by this -# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 @@ -360,484 +360,485 @@ LOOKUP_CACHE_SIZE = 0 # Build related configuration options #--------------------------------------------------------------------------- -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO -# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal -# scope will be included in the documentation. +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. EXTRACT_PACKAGE = NO -# If the EXTRACT_STATIC tag is set to YES all static members of a file +# If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES -# The ENABLED_SECTIONS tag can be used to enable conditional +# The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. -ENABLED_SECTIONS = +ENABLED_SECTIONS = -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. This will remove the Namespaces entry from the Quick Index +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. -FILE_VERSION_FILTER = +FILE_VERSION_FILTER = -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. -LAYOUT_FILE = +LAYOUT_FILE = -# The CITE_BIB_FILES tag can be used to specify one or more bib files -# containing the references data. This must be a list of .bib files. The -# .bib extension is automatically appended if omitted. Using this command -# requires the bibtex tool to be installed. See also -# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style -# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. -CITE_BIB_FILES = +CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- -# The QUIET tag can be used to turn on/off the messages that are generated +# The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. -WARN_IF_UNDOCUMENTED = YES +WARN_IF_UNDOCUMENTED = NO -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written # to stderr. -WARN_LOGFILE = +WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = "src" "src/CBot" "src/doc" +INPUT = "src" \ + "src/CBot" -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.h \ - *.cpp + *.cpp \ + README.txt -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# Note that relative paths are relative to the directory from which doxygen is +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = "src/old" "src/metafile" +EXCLUDE = "src/old" \ + "src/metafile" -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test -EXCLUDE_SYMBOLS = +EXCLUDE_SYMBOLS = -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see # the \include command). -EXAMPLE_PATH = +EXAMPLE_PATH = -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = * -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see # the \image command). -IMAGE_PATH = +IMAGE_PATH = -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be # ignored. -INPUT_FILTER = +INPUT_FILTER = -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. -FILTER_PATTERNS = +FILTER_PATTERNS = -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. -FILTER_SOURCE_PATTERNS = +FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO -# Setting the INLINE_SOURCES tag to YES will include the body +# Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentation. +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES @@ -846,157 +847,160 @@ VERBATIM_HEADERS = YES # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. -IGNORE_PREFIX = +IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is advised to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! -HTML_HEADER = +HTML_HEADER = -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a # standard footer. -HTML_FOOTER = +HTML_FOOTER = -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own # style sheet in the HTML output directory as well, or it will be erased! -HTML_STYLESHEET = +HTML_STYLESHEET = -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. -HTML_EXTRA_FILES = +HTML_EXTRA_FILES = -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the style sheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. HTML_DYNAMIC_SECTIONS = NO -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher @@ -1005,220 +1009,216 @@ DOCSET_PUBLISHER_ID = org.doxygen.Publisher DOCSET_PUBLISHER_NAME = Publisher -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be # written to the html output directory. -CHM_FILE = +CHM_FILE = -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. -HHC_LOCATION = +HHC_LOCATION = -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. -CHM_INDEX_ENCODING = +CHM_INDEX_ENCODING = -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO -# The TOC_EXPAND flag can be set to YES to add extra items for group members +# The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. -QCH_FILE = +QCH_FILE = -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters -QHP_CUST_FILTER_NAME = +QHP_CUST_FILTER_NAME = -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# # Qt Help Project / Custom Filters. -QHP_CUST_FILTER_ATTRS = +QHP_CUST_FILTER_ATTRS = -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# # Qt Help Project / Filter Attributes. -QHP_SECT_FILTER_ATTRS = +QHP_SECT_FILTER_ATTRS = -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. -QHG_LOCATION = +QHG_LOCATION = -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project -# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) -# at top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. Since the tabs have the same information as the -# navigation tree you can set this option to NO if you already set +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. -# Since the tree basically has the same information as the tab index you +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you may also need to install MathJax separately and +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to -# the MathJax Content Delivery Network so you can quickly see the result without -# installing MathJax. However, it is strongly recommended to install a local +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest -# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. -MATHJAX_EXTENSIONS = +MATHJAX_EXTENSIONS = -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO @@ -1227,97 +1227,97 @@ SERVER_BASED_SEARCH = NO # configuration options related to the LaTeX output #--------------------------------------------------------------------------- -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4 -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. -EXTRA_PACKAGES = +EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! -LATEX_HEADER = +LATEX_HEADER = -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! -LATEX_FOOTER = +LATEX_FOOTER = -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO -# The LATEX_BIB_STYLE tag can be used to specify the style to use for the -# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain @@ -1326,68 +1326,68 @@ LATEX_BIB_STYLE = plain # configuration options related to the RTF output #--------------------------------------------------------------------------- -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO -# Load style sheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. -RTF_STYLESHEET_FILE = +RTF_STYLESHEET_FILE = -# Set optional variables used in the generation of an rtf document. +# Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. -RTF_EXTENSIONS_FILE = +RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man -# The MAN_EXTENSION tag determines the extension that is added to +# The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO @@ -1396,33 +1396,33 @@ MAN_LINKS = NO # configuration options related to the XML output #--------------------------------------------------------------------------- -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_SCHEMA = +XML_SCHEMA = -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the # syntax of the XML files. -XML_DTD = +XML_DTD = -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES @@ -1431,10 +1431,10 @@ XML_PROGRAMLISTING = YES # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO @@ -1443,97 +1443,99 @@ GENERATE_AUTOGEN_DEF = NO # configuration options related to the Perl module output #--------------------------------------------------------------------------- -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. -PERLMOD_MAKEVAR_PREFIX = +PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by # the preprocessor. -INCLUDE_PATH = +INCLUDE_PATH = -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. -INCLUDE_FILE_PATTERNS = +INCLUDE_FILE_PATTERNS = -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator # instead of the = operator. -PREDEFINED = +PREDEFINED = -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. -EXPAND_AS_DEFINED = +EXPAND_AS_DEFINED = -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES @@ -1542,37 +1544,39 @@ SKIP_FUNCTION_MACROS = YES # Configuration::additions related to external references #--------------------------------------------------------------------------- -# The TAGFILES option can be used to specify one or more tagfiles. For each -# tag file the location of the external documentation should be added. The -# format of a tag file without this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths -# or URLs. Note that each tag file must have a unique name (where the name does -# NOT include the path). If a tag file is not located in the directory in which +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. -TAGFILES = +TAGFILES = -# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. -GENERATE_TAGFILE = +GENERATE_TAGFILE = -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES -# The PERL_PATH should be the absolute path and name of the perl script +# The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl @@ -1581,222 +1585,222 @@ PERL_PATH = /usr/bin/perl # Configuration options related to the dot tool #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = NO -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. -MSCGEN_PATH = +MSCGEN_PATH = -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 -# By default doxygen will use the Helvetica font for all dot files that -# doxygen generates. When you want a differently looking font you can specify -# the font name using DOT_FONTNAME. You need to make sure dot is able to find -# the font, which can be done by putting it in a standard location or by setting -# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = Helvetica -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 -# By default doxygen will tell dot to use the Helvetica font. -# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. -DOT_FONTPATH = +DOT_FONTPATH = -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = NO -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO -# If the UML_LOOK tag is enabled, the fields and methods are shown inside -# the class node. If there are many fields or methods and many nodes the -# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS -# threshold limits the number of items for each type to make the size more -# managable. Set this to 0 for no limit. Note that the threshold may be +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 -# If set to YES, the inheritance and collaboration graphs will show the +# If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = NO -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. If you choose svg you need to set -# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png -# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to -# enable generation of interactive SVG images that allow zooming and panning. -# Note that this requires a modern browser other than Internet Explorer. -# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you -# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO -# The tag DOT_PATH can be used to specify the path where the dot tool can be +# The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. -DOT_PATH = +DOT_PATH = -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the # \dotfile command). -DOTFILE_DIRS = +DOTFILE_DIRS = -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the # \mscfile command). -MSCFILE_DIRS = +MSCFILE_DIRS = -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES diff --git a/src/app/README.txt b/src/app/README.txt index 1df1fcce..e4f69ec8 100644 --- a/src/app/README.txt +++ b/src/app/README.txt @@ -1,3 +1,4 @@ -src/app - -Contains the main class of the application. +/** + * \dir app + * Main class of the application and system functions + */ diff --git a/src/app/app.h b/src/app/app.h index d3b13688..bfa8c254 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// app.h +/** + * \file app/app.h + * \brief CApplication class + */ #pragma once diff --git a/src/app/main.cpp b/src/app/main.cpp index dce13da2..619043e1 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// main.cpp +/** + * \file app/main.cpp + * \brief Entry point of application - main() function + */ #include "app/app.h" #include "app/system.h" diff --git a/src/app/system.h b/src/app/system.h index 3c04760a..e216842c 100644 --- a/src/app/system.h +++ b/src/app/system.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// system.h +/** + * \file app/system.h + * \brief System functions: time stamps, info dialogs, etc. + */ #pragma once @@ -26,7 +29,7 @@ /* Dialog utils */ /** - * \enum SysDialogType + * \enum SystemDialogType * \brief Type of system dialog */ enum SystemDialogType @@ -44,7 +47,7 @@ enum SystemDialogType }; /** - * \enum SysDialogResult + * \enum SystemDialogResult * \brief Result of system dialog * * Means which button was pressed. diff --git a/src/app/system_linux.h b/src/app/system_linux.h index f58c9a1a..69893de3 100644 --- a/src/app/system_linux.h +++ b/src/app/system_linux.h @@ -15,10 +15,13 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// system_linux.h +/** + * \file app/system_linux.h + * \brief Linux-specific implementation of system functions + */ -/* This header contains Linux-specific code for system utils - from system.h. There is no separate .cpp module for simplicity.*/ +/* NOTE: code is contained in this header; + * there is no separate .cpp module for simplicity */ #include #include diff --git a/src/app/system_other.h b/src/app/system_other.h index 9f13ffa0..eff0c8a0 100644 --- a/src/app/system_other.h +++ b/src/app/system_other.h @@ -15,10 +15,13 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// system_other.h +/** + * \file app/system_other.h + * \brief Fallback code for other systems + */ -/* This header contains fallback code for other platforms for system utils - from system.h. There is no separate .cpp module for simplicity.*/ +/* NOTE: code is contained in this header; + * there is no separate .cpp module for simplicity */ #include diff --git a/src/app/system_windows.h b/src/app/system_windows.h index eb6beec7..72d9f88d 100644 --- a/src/app/system_windows.h +++ b/src/app/system_windows.h @@ -15,10 +15,13 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// system_windows.h +/** + * \file app/system_windows.h + * \brief Windows-specific implementation of system functions + */ -/* This header contains Windows-specific code for system utils - from system.h. There is no separate .cpp module for simplicity.*/ +/* NOTE: code is contained in this header; + * there is no separate .cpp module for simplicity */ #include diff --git a/src/common/README.txt b/src/common/README.txt index 36653ccb..73d65b73 100644 --- a/src/common/README.txt +++ b/src/common/README.txt @@ -1,3 +1,4 @@ -src/common - -Contains headers and modules with common structs and enums. +/** + * \dir common + * \brief Structs and utils shared throughout the application + */ diff --git a/src/common/logger.h b/src/common/logger.h index a67aefec..5de3d638 100644 --- a/src/common/logger.h +++ b/src/common/logger.h @@ -57,36 +57,36 @@ class CLogger : public CSingleton ~CLogger(); /** Write message to console or file - * @param const char str - message to write + * @param str - message to write * @param ... - additional arguments */ void Message(const char *str, ...); /** Write message to console or file with LOG_INFO level - * @param const char str - message to write + * @param str - message to write * @param ... - additional arguments */ void Info(const char *str, ...); /** Write message to console or file with LOG_WARN level - * @param const char str - message to write + * @param str - message to write * @param ... - additional arguments */ void Warn(const char *str, ...); /** Write message to console or file with LOG_ERROR level - * @param const char str - message to write + * @param str - message to write * @param ... - additional arguments */ void Error(const char *str, ...); /** Set output file to write logs to - * @param std::string filename - output file to write to + * @param filename - output file to write to */ void SetOutputFile(std::string filename); /** Set log level. Logs with level below will not be shown - * @param LogType level - minimum log level to write + * @param level - minimum log level to write */ void SetLogLevel(LogType level); diff --git a/src/graphics/README.txt b/src/graphics/README.txt index 3ec3871c..479747b9 100644 --- a/src/graphics/README.txt +++ b/src/graphics/README.txt @@ -1,3 +1,12 @@ -src/graphics +/** + * \dir graphics + * \brief Graphics engine + */ -Graphics engine +/** + * \namespace Gfx + * \brief Namespace for (new) graphics code + * + * This namespace was created to avoid clashing with old code, but now it still serves, + * defining a border between pure graphics engine and other parts of application. + */ \ No newline at end of file diff --git a/src/graphics/core/README.txt b/src/graphics/core/README.txt index 12beef92..ca3768ce 100644 --- a/src/graphics/core/README.txt +++ b/src/graphics/core/README.txt @@ -1,6 +1,7 @@ -src/graphics/core - -Abstract core of graphics engine - -Core types, enums, structs and CDevice abstract class that define -the abstract graphics device used in graphics engine +/** + * \dir graphics/core + * \brief Abstract core of graphics engine + * + * Core types, enums, structs and CDevice abstract class that define + * the abstract graphics device used in graphics engine + */ \ No newline at end of file diff --git a/src/graphics/core/color.h b/src/graphics/core/color.h index 0e08de35..ff8a2eb1 100644 --- a/src/graphics/core/color.h +++ b/src/graphics/core/color.h @@ -14,7 +14,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// color.h +/** + * \file graphics/core/color.h + * \brief Color structs and related functions + */ #pragma once diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h index d4fcd261..a829c81d 100644 --- a/src/graphics/core/device.h +++ b/src/graphics/core/device.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// device.h +/** + * \file graphics/core/device.h + * \brief Abstract graphics device - Gfx::CDevice class and related structs/enums + */ #pragma once diff --git a/src/graphics/core/light.h b/src/graphics/core/light.h index b787cb2c..a39d1f58 100644 --- a/src/graphics/core/light.h +++ b/src/graphics/core/light.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// light.h +/** + * \file graphics/core/light.h + * \brief Light struct and related enums + */ #pragma once diff --git a/src/graphics/core/material.h b/src/graphics/core/material.h index 31b42f36..eb73c503 100644 --- a/src/graphics/core/material.h +++ b/src/graphics/core/material.h @@ -14,7 +14,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// material.h +/** + * \file graphics/core/material.h + * \brief Material struct + */ #pragma once diff --git a/src/graphics/core/texture.h b/src/graphics/core/texture.h index bb5b52f5..c36b6c6f 100644 --- a/src/graphics/core/texture.h +++ b/src/graphics/core/texture.h @@ -14,7 +14,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// texture.h +/** + * \file graphics/core/texture.h + * \brief Texture struct and related enums + */ #pragma once diff --git a/src/graphics/core/vertex.h b/src/graphics/core/vertex.h index b7fab1ca..53dd642f 100644 --- a/src/graphics/core/vertex.h +++ b/src/graphics/core/vertex.h @@ -14,7 +14,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// vertex.h +/** + * \file graphics/core/vertex.h + * \brief Vertex structs + */ #pragma once diff --git a/src/graphics/d3d/README.txt b/src/graphics/d3d/README.txt index 8388120f..524ae7bb 100644 --- a/src/graphics/d3d/README.txt +++ b/src/graphics/d3d/README.txt @@ -1,3 +1,4 @@ -src/graphics/d3d - -Possible future DirectX implementation of graphics engine +/** + * \dir graphics/d3d + * \brief Possible future DirectX implementation of graphics engine + */ \ No newline at end of file diff --git a/src/graphics/engine/README.txt b/src/graphics/engine/README.txt index 308b601b..f64d3dda 100644 --- a/src/graphics/engine/README.txt +++ b/src/graphics/engine/README.txt @@ -1,8 +1,9 @@ -src/graphics/engine - -Graphics engine - -CEngine class and various other classes implementing the main features -of graphics engine from model loading to decorative particles - -Graphics operations are done on abstract interface from src/graphics/core +/** + * \dir graphics/engine + * \brief Graphics engine + * + * CEngine class and various other classes implementing the main features + * of graphics engine from model loading to decorative particles + * + * Graphics operations are done on abstract interface from src/graphics/core + */ \ No newline at end of file diff --git a/src/graphics/engine/camera.h b/src/graphics/engine/camera.h index ec6afcb2..1a82f9f7 100644 --- a/src/graphics/engine/camera.h +++ b/src/graphics/engine/camera.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// camera.h +/** + * \file graphics/engine/camera.h + * \brief Camera handling - Gfx::CCamera class + */ #pragma once diff --git a/src/graphics/engine/cloud.h b/src/graphics/engine/cloud.h index 676dfe82..881a5980 100644 --- a/src/graphics/engine/cloud.h +++ b/src/graphics/engine/cloud.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// cloud.h +/** + * \file graphics/engine/cloud.h + * \brief Cloud rendering - Gfx::CCloud class + */ #pragma once diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index 8f9338a4..c7ff084e 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// engine.h +/** + * \file graphics/engine/engine.h + * \brief Main graphics engine - Gfx::CEngine class + */ #pragma once diff --git a/src/graphics/engine/lightman.h b/src/graphics/engine/lightman.h index 82721250..52058c8a 100644 --- a/src/graphics/engine/lightman.h +++ b/src/graphics/engine/lightman.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// lightman.h +/** + * \file graphics/engine/lightman.h + * \brief Dynamic light manager - Gfx::CLightManager class + */ #pragma once diff --git a/src/graphics/engine/lightning.h b/src/graphics/engine/lightning.h index 9e854be8..3b4e2cfb 100644 --- a/src/graphics/engine/lightning.h +++ b/src/graphics/engine/lightning.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// lightning.h (aka blitz.h) +/** + * \file graphics/engine/lightning.h + * \brief Lightning rendering - Gfx::CLightning class (aka blitz) + */ #pragma once diff --git a/src/graphics/engine/modelfile.h b/src/graphics/engine/modelfile.h index 6a30487b..fab190f6 100644 --- a/src/graphics/engine/modelfile.h +++ b/src/graphics/engine/modelfile.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// modelfile.h (aka modfile.h) +/** + * \file graphics/engine/modelfile.h + * \brief Model loading - Gfx::CModelFile class (aka modfile) + */ #include "graphics/engine/engine.h" #include "graphics/core/vertex.h" diff --git a/src/graphics/engine/particle.h b/src/graphics/engine/particle.h index 89e2c5be..45396d23 100644 --- a/src/graphics/engine/particle.h +++ b/src/graphics/engine/particle.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// particle.h (aka particule.h) +/** + * \file graphics/engine/particle.h + * \brief Particle rendering - Gfx::CParticle class (aka particule) + */ #pragma once diff --git a/src/graphics/engine/planet.h b/src/graphics/engine/planet.h index 5ba318b2..54d8b556 100644 --- a/src/graphics/engine/planet.h +++ b/src/graphics/engine/planet.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// planet.h +/** + * \file graphics/engine/planet.h + * \brief Planet rendering - Gfx::CPlanet class + */ #pragma once diff --git a/src/graphics/engine/pyro.h b/src/graphics/engine/pyro.h index 35b5c5ff..768abf89 100644 --- a/src/graphics/engine/pyro.h +++ b/src/graphics/engine/pyro.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// pyro.h +/** + * \file graphics/engine/pyro.h + * \brief Fire effect rendering - Gfx::CPyro class + */ #pragma once diff --git a/src/graphics/engine/terrain.h b/src/graphics/engine/terrain.h index a1985901..41d4bbb6 100644 --- a/src/graphics/engine/terrain.h +++ b/src/graphics/engine/terrain.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// terrain.h +/** + * \file graphics/engine/terrain.h + * \brief Terrain rendering - Gfx::CTerrain class + */ #pragma once diff --git a/src/graphics/engine/text.h b/src/graphics/engine/text.h index 7e2f84b0..24251ab6 100644 --- a/src/graphics/engine/text.h +++ b/src/graphics/engine/text.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// text.h +/** + * \file graphics/engine/text.h + * \brief Text rendering - Gfx::CText class + */ #pragma once diff --git a/src/graphics/engine/water.h b/src/graphics/engine/water.h index 245baf71..b0518891 100644 --- a/src/graphics/engine/water.h +++ b/src/graphics/engine/water.h @@ -15,7 +15,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// water.h +/** + * \file graphics/engine/water.h + * \brief Water rendering - Gfx::CWater class + */ #pragma once diff --git a/src/graphics/opengl/README.txt b/src/graphics/opengl/README.txt index 0aba0ed8..596871d4 100644 --- a/src/graphics/opengl/README.txt +++ b/src/graphics/opengl/README.txt @@ -1,6 +1,7 @@ -src/graphics/opengl - -OpenGL engine implementation - -Contains the concrete implementation using OpenGL of abstract CDevice class -from src/graphics/core +/** + * \dir graphics/opengl + * \brief OpenGL engine implementation + * + * Contains the concrete implementation using OpenGL of abstract CDevice class + * from src/graphics/core + */ \ No newline at end of file diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h index a41c41ca..dbe9a526 100644 --- a/src/graphics/opengl/gldevice.h +++ b/src/graphics/opengl/gldevice.h @@ -14,7 +14,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// gldevice.h +/** + * \file graphics/opengl/gldevice.h + * \brief OpenGL implementation - Gfx::CGLDevice class + */ #pragma once diff --git a/src/math/README.txt b/src/math/README.txt index 1a5ce93b..fd34dcbe 100644 --- a/src/math/README.txt +++ b/src/math/README.txt @@ -1,3 +1,12 @@ -src/math +/** + * \dir math + * \brief Common mathematical structures and functions + */ -Contains common mathematical structures and functions. +/** + * \namespace Math + * \brief Namespace for (new) math code + * + * This namespace was created to avoid clashing with old code, but now it still serves, + * defining a border between math and non-math-related code. + */ \ No newline at end of file diff --git a/src/math/all.h b/src/math/all.h index 13a9290a..4ac9d554 100644 --- a/src/math/all.h +++ b/src/math/all.h @@ -14,14 +14,13 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -/** @defgroup MathAllModule math/all.h - Includes all other math module headers. +/** + * \file math/all.h + * \brief Includes all other math module headers */ #pragma once -/* @{ */ // start of group - #include "const.h" #include "func.h" #include "point.h" @@ -30,5 +29,3 @@ #include "geometry.h" #include "conv.h" - -/* @} */ // end of group diff --git a/src/math/const.h b/src/math/const.h index b08a4001..0b6f971e 100644 --- a/src/math/const.h +++ b/src/math/const.h @@ -14,8 +14,9 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -/** @defgroup MathConstModule math/const.h - Contains the math constants used in math functions. +/** + * \file math/const.h + * \brief Constants used in math functions */ #pragma once @@ -26,7 +27,6 @@ // Math module namespace namespace Math { -/* @{ */ // start of group //! Tolerance level -- minimum accepted float value const float TOLERANCE = 1e-6f; @@ -50,6 +50,5 @@ const float RAD_TO_DEG = 57.29577951308232286465f; //! Natural logarithm of 2 const float LOG_2 = log(2.0f); -/* @} */ // end of group }; // namespace Math diff --git a/src/math/func.h b/src/math/func.h index e97d9903..541b0843 100644 --- a/src/math/func.h +++ b/src/math/func.h @@ -15,8 +15,9 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -/** @defgroup MathFuncModule math/func.h - Contains common math functions. +/** + * \file math/func.h + * \brief Common math functions */ #pragma once @@ -31,8 +32,6 @@ namespace Math { -/* @{ */ // start of group - //! Compares \a a and \a b within \a tolerance inline bool IsEqual(float a, float b, float tolerance = Math::TOLERANCE) { @@ -188,11 +187,13 @@ inline float Direction(float a, float g) //! Managing the dead zone of a joystick. /** -\verbatimin: -1 0 1 +\verbatim +in: -1 0 1 --|-------|----o----|-------|--> <----> dead -out: -1 0 0 1\endverbatim */ +out: -1 0 0 1 +\endverbatim */ inline float Neutral(float value, float dead) { if ( fabs(value) <= dead ) @@ -226,7 +227,8 @@ inline float Smooth(float actual, float hope, float time) //! Bounces any movement /** -\verbatimout +\verbatim +out | 1+------o-------o--- | o | o o | | bounce @@ -235,7 +237,8 @@ inline float Smooth(float actual, float hope, float time) | o | | -o------|-------+----> progress 0| | 1 - |<---->|middle\endverbatim */ + |<---->|middle +\endverbatim */ inline float Bounce(float progress, float middle = 0.3f, float bounce = 0.4f) { if ( progress < middle ) @@ -250,6 +253,4 @@ inline float Bounce(float progress, float middle = 0.3f, float bounce = 0.4f) } } -/* @} */ // end of group - }; // namespace Math diff --git a/src/math/geometry.h b/src/math/geometry.h index 3a31ad6a..1c5f60fc 100644 --- a/src/math/geometry.h +++ b/src/math/geometry.h @@ -15,9 +15,9 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -/** @defgroup MathGeometryModule math/geometry.h - Contains math functions related to 3D geometry calculations, - transformations, etc. +/** + * \file math/geometry.h + * \brief Math functions related to 3D geometry calculations, transformations, etc. */ #pragma once @@ -36,9 +36,6 @@ namespace Math { -/* @{ */ // start of group - - //! Returns py up on the line \a a - \a b inline float MidPoint(const Math::Point &a, const Math::Point &b, float px) { @@ -566,6 +563,4 @@ inline Math::Vector RotateView(Math::Vector center, float angleH, float angleV, return eye+center; } -/* @} */ // end of group - }; // namespace Math diff --git a/src/math/intpoint.h b/src/math/intpoint.h index 476e67bc..8e13b192 100644 --- a/src/math/intpoint.h +++ b/src/math/intpoint.h @@ -14,18 +14,18 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -/** @defgroup MathIntPointModule math/intpoint.h - Contains the IntPoint struct. +/** + * \file math/intpoint.h + * \brief IntPoint struct */ #pragma once namespace Math { -/* @{ */ // start of group - /** - * \struct IntPoint 2D Point with integer coords + * \struct IntPoint + * \brief 2D Point with integer coords * * Analog of WinAPI's POINT struct. */ @@ -39,6 +39,4 @@ struct IntPoint IntPoint(int aX = 0, int aY = 0) : x(aX), y(aY) {} }; -/* @} */ // end of group - }; // namespace Math diff --git a/src/math/matrix.h b/src/math/matrix.h index 45a7d75b..30e629a9 100644 --- a/src/math/matrix.h +++ b/src/math/matrix.h @@ -14,8 +14,9 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -/** @defgroup MathMatrixModule math/matrix.h - Contains the Matrix struct and related functions. +/** + * \file math/matrix.h + * \brief Matrix struct and related functions */ #pragma once @@ -32,8 +33,6 @@ namespace Math { -/* @{ */ // start of group - /** \struct Matrix math/matrix.h \brief 4x4 matrix @@ -42,11 +41,12 @@ namespace Math The internal representation is a 16-value table in column-major order, thus: - \verbatim +\verbatim m[0 ] m[4 ] m[8 ] m[12] m[1 ] m[5 ] m[9 ] m[13] m[2 ] m[6 ] m[10] m[14] -m[3 ] m[7 ] m[11] m[15] \endverbatim +m[3 ] m[7 ] m[11] m[15] +\endverbatim This representation is native to OpenGL; DirectX requires transposing the matrix. @@ -405,11 +405,15 @@ inline Math::Matrix MultiplyMatrices(const Math::Matrix &left, const Math::Matri } //! Calculates the result of multiplying m * v -/** The multiplication is performed thus: -\verbatim [ m.m[0 ] m.m[4 ] m.m[8 ] m.m[12] ] [ v.x ] +/** + The multiplication is performed thus: + +\verbatim +[ m.m[0 ] m.m[4 ] m.m[8 ] m.m[12] ] [ v.x ] [ m.m[1 ] m.m[5 ] m.m[9 ] m.m[13] ] [ v.y ] [ m.m[2 ] m.m[6 ] m.m[10] m.m[14] ] * [ v.z ] -[ m.m[3 ] m.m[7 ] m.m[11] m.m[15] ] [ 1 ] \endverbatim +[ m.m[3 ] m.m[7 ] m.m[11] m.m[15] ] [ 1 ] +\endverbatim The result, a 4x1 vector is then converted to 3x1 by dividing x,y,z coords by the fourth coord (w). */ @@ -434,6 +438,4 @@ inline Math::Vector MatrixVectorMultiply(const Math::Matrix &m, const Math::Vect return Math::Vector(x, y, z); } -/* @} */ // end of group - }; // namespace Math diff --git a/src/math/point.h b/src/math/point.h index ea20db96..ecf896fc 100644 --- a/src/math/point.h +++ b/src/math/point.h @@ -14,8 +14,9 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -/** @defgroup MathPointModule math/point.h - Contains the Point struct and related functions. +/** + * \file math/point.h + * \brief Point struct and related functions */ #pragma once @@ -31,8 +32,6 @@ namespace Math { -/* @{ */ // start of group - /** \struct Point math/point.h \brief 2D point @@ -188,6 +187,4 @@ inline float Distance(const Point &a, const Point &b) return sqrtf((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)); } -/* @} */ // end of group - }; // namespace Math diff --git a/src/math/vector.h b/src/math/vector.h index 147869f2..4378e751 100644 --- a/src/math/vector.h +++ b/src/math/vector.h @@ -14,8 +14,9 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -/** @defgroup MathVectorModule math/vector.h - Contains the Vector struct and related functions. +/** + * \file math/vector.h + * \brief Vector struct and related functions */ #pragma once @@ -31,8 +32,6 @@ namespace Math { -/* @{ */ // start of group - /** \struct Vector math/vector.h \brief 3D (3x1) vector @@ -263,6 +262,4 @@ inline float Distance(const Math::Vector &a, const Math::Vector &b) (a.z-b.z)*(a.z-b.z) ); } -/* @} */ // end of group - }; // namespace Math diff --git a/src/object/README.txt b/src/object/README.txt index f4c25d04..f3bad238 100644 --- a/src/object/README.txt +++ b/src/object/README.txt @@ -1,3 +1,7 @@ -src/object - -Contains modules of robots and buildings. +/** + * \dir object + * \brief Game engine + * + * Contains the main class of game engine - CRobotMain and the various in-game objects: + * CObject and related auto, motion and task subclasses. + */ \ No newline at end of file diff --git a/src/physics/README.txt b/src/physics/README.txt index 00039566..4ad59891 100644 --- a/src/physics/README.txt +++ b/src/physics/README.txt @@ -1,3 +1,4 @@ -src/physics - -Contains the physics module. +/** + * \dir physics + * \brief Physics engine + */ \ No newline at end of file diff --git a/src/sound/README.txt b/src/sound/README.txt index d6ac0bd8..fa7bbad9 100644 --- a/src/sound/README.txt +++ b/src/sound/README.txt @@ -1,3 +1,4 @@ -src/sound - -Contains the sound module - for playing sounds and music. +/** + * \dir sound + * \brief Sound module - playing sounds and music + */ \ No newline at end of file diff --git a/src/ui/README.txt b/src/ui/README.txt index 4ffd8ec0..9814ef0a 100644 --- a/src/ui/README.txt +++ b/src/ui/README.txt @@ -1,3 +1,4 @@ -src/ui - -Contains modules responsible for displaying the user interface controls (from game menus and HUD). +/** + * \dir ui + * \brief 2D user interface controls + */ \ No newline at end of file From b4b74c30e9aa93ae736db73df5cb0c5d508ec6ed Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sun, 12 Aug 2012 10:45:04 +0200 Subject: [PATCH 10/10] Fixes & testing in CEngine - fixed bugs in settings modes, etc. - some additions and minor refactoring --- src/app/app.cpp | 19 +- src/app/app.h | 3 + src/graphics/core/device.h | 7 +- src/graphics/engine/cloud.cpp | 5 +- src/graphics/engine/engine.cpp | 366 ++++++++++++++++++++++--------- src/graphics/engine/engine.h | 35 ++- src/graphics/engine/text.cpp | 6 +- src/graphics/engine/water.cpp | 5 +- src/graphics/opengl/gldevice.cpp | 19 +- src/graphics/opengl/gldevice.h | 2 + 10 files changed, 336 insertions(+), 131 deletions(-) diff --git a/src/app/app.cpp b/src/app/app.cpp index 4f7120d1..a0518dbc 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -215,8 +215,7 @@ bool CApplication::Create() if (! m_device->Create() ) { SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", - std::string("Error in CDevice::Create() :\n") + - std::string(m_device->GetError()) ); + std::string("Error in CDevice::Create()") ); m_exitCode = 1; return false; } @@ -229,8 +228,7 @@ bool CApplication::Create() if (! m_engine->Create() ) { SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", - std::string("Error in CEngine::Init() :\n") + - std::string(m_engine->GetError()) ); + std::string("Error in CEngine::Init()") ); m_exitCode = 1; return false; } @@ -498,6 +496,14 @@ void CApplication::UpdateJoystick() } } +void CApplication::UpdateMouse() +{ + Math::IntPoint pos; + SDL_GetMouseState(&pos.x, &pos.y); + m_systemMousePos = m_engine->WindowToInterfaceCoords(pos); + m_engine->SetMousePos(m_systemMousePos); +} + int CApplication::Run() { m_active = true; @@ -572,6 +578,10 @@ int CApplication::Run() m_robotMain->ProcessEvent(event); */ } + /* Update mouse position explicitly right before rendering + * because mouse events are usually way behind */ + UpdateMouse(); + // Update game and render a frame during idle time (no messages are waiting) Render(); } @@ -857,7 +867,6 @@ bool CApplication::GetSystemMouseVisibile() return result == SDL_ENABLE; } - void CApplication::SetSystemMousePos(Math::Point pos) { Math::IntPoint windowPos = m_engine->InterfaceToWindowCoords(pos); diff --git a/src/app/app.h b/src/app/app.h index bfa8c254..0cfaad2b 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -164,6 +164,9 @@ public: //! Polls the state of joystick axes and buttons void UpdateJoystick(); + //! Updates the mouse position explicitly + void UpdateMouse(); + void FlushPressKey(); void ResetKey(); void SetKey(int keyRank, int option, int key); diff --git a/src/graphics/core/device.h b/src/graphics/core/device.h index a829c81d..a3d0208a 100644 --- a/src/graphics/core/device.h +++ b/src/graphics/core/device.h @@ -153,9 +153,9 @@ enum FogMode \brief Culling mode for polygons */ enum CullMode { - //! Cull clockwise side + //! Cull clockwise faces CULL_CW, - //! Cull counter-clockwise side + //! Cull counter-clockwise faces CULL_CCW }; @@ -278,6 +278,9 @@ class CDevice public: virtual ~CDevice() {} + //! Provides a hook to debug graphics code (implementation-specific) + virtual void DebugHook() = 0; + //! Initializes the device, setting the initial state virtual bool Create() = 0; //! Destroys the device, releasing every acquired resource diff --git a/src/graphics/engine/cloud.cpp b/src/graphics/engine/cloud.cpp index 71dd9690..f3c00020 100644 --- a/src/graphics/engine/cloud.cpp +++ b/src/graphics/engine/cloud.cpp @@ -231,10 +231,7 @@ void Gfx::CCloud::Create(const std::string& fileName, m_fileName = fileName; if (! m_fileName.empty()) - { - m_engine->LoadTexture(m_fileName, 0); - m_engine->LoadTexture(m_fileName, 1); - } + m_engine->LoadTexture(m_fileName); if (m_terrain == nullptr) m_terrain = static_cast(m_iMan->SearchInstance(CLASS_TERRAIN)); diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 04616365..644ecaf1 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -115,6 +115,7 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_overColor = 0; m_overMode = ENG_RSTATE_TCOLOR_BLACK; m_highlightRank[0] = -1; // empty list + m_highlightTime = 0.0f; m_eyePt = Math::Vector(0.0f, 0.0f, 0.0f); m_lookatPt = Math::Vector(0.0f, 0.0f, 1.0f); m_drawWorld = true; @@ -133,7 +134,7 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_lensMode = true; m_waterMode = true; m_skyMode = true; - m_backForce = true; + m_backForce = false; // TODO: change to true? m_planetMode = true; m_lightMode = true; m_editIndentMode = true; @@ -147,22 +148,22 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_updateGeometry = false; - m_mice[Gfx::ENG_MOUSE_NORM] = Gfx::EngineMouse( 0, 1, 32, Gfx::ENG_RSTATE_TCOLOR_WHITE, Gfx::ENG_RSTATE_TCOLOR_BLACK, Math::Point( 1.0f, 1.0f)); - m_mice[Gfx::ENG_MOUSE_WAIT] = Gfx::EngineMouse( 2, 3, 33, Gfx::ENG_RSTATE_TCOLOR_WHITE, Gfx::ENG_RSTATE_TCOLOR_BLACK, Math::Point( 8.0f, 12.0f)); - m_mice[Gfx::ENG_MOUSE_HAND] = Gfx::EngineMouse( 4, 5, 34, Gfx::ENG_RSTATE_TCOLOR_WHITE, Gfx::ENG_RSTATE_TCOLOR_BLACK, Math::Point( 7.0f, 2.0f)); - m_mice[Gfx::ENG_MOUSE_NO] = Gfx::EngineMouse( 6, 7, 35, Gfx::ENG_RSTATE_TCOLOR_WHITE, Gfx::ENG_RSTATE_TCOLOR_BLACK, Math::Point(10.0f, 10.0f)); - m_mice[Gfx::ENG_MOUSE_EDIT] = Gfx::EngineMouse( 8, 9, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 6.0f, 10.0f)); - m_mice[Gfx::ENG_MOUSE_CROSS] = Gfx::EngineMouse(10, 11, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point(10.0f, 10.0f)); - m_mice[Gfx::ENG_MOUSE_MOVEV] = Gfx::EngineMouse(12, 13, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 5.0f, 11.0f)); - m_mice[Gfx::ENG_MOUSE_MOVEH] = Gfx::EngineMouse(14, 15, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point(11.0f, 5.0f)); - m_mice[Gfx::ENG_MOUSE_MOVED] = Gfx::EngineMouse(16, 17, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 9.0f, 9.0f)); - m_mice[Gfx::ENG_MOUSE_MOVEI] = Gfx::EngineMouse(18, 19, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 9.0f, 9.0f)); - m_mice[Gfx::ENG_MOUSE_MOVE] = Gfx::EngineMouse(20, 21, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point(11.0f, 11.0f)); - m_mice[Gfx::ENG_MOUSE_TARGET] = Gfx::EngineMouse(22, 23, -1, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point(15.0f, 15.0f)); - m_mice[Gfx::ENG_MOUSE_SCROLLL] = Gfx::EngineMouse(24, 25, 43, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 2.0f, 9.0f)); - m_mice[Gfx::ENG_MOUSE_SCROLLR] = Gfx::EngineMouse(26, 27, 44, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point(17.0f, 9.0f)); - m_mice[Gfx::ENG_MOUSE_SCROLLU] = Gfx::EngineMouse(28, 29, 45, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 9.0f, 2.0f)); - m_mice[Gfx::ENG_MOUSE_SCROLLD] = Gfx::EngineMouse(30, 31, 46, Gfx::ENG_RSTATE_TCOLOR_BLACK, Gfx::ENG_RSTATE_TCOLOR_WHITE, Math::Point( 9.0f, 17.0f)); + m_mice[Gfx::ENG_MOUSE_NORM] = Gfx::EngineMouse( 0, 1, 32, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 1.0f, 1.0f)); + m_mice[Gfx::ENG_MOUSE_WAIT] = Gfx::EngineMouse( 2, 3, 33, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 8.0f, 12.0f)); + m_mice[Gfx::ENG_MOUSE_HAND] = Gfx::EngineMouse( 4, 5, 34, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 7.0f, 2.0f)); + m_mice[Gfx::ENG_MOUSE_NO] = Gfx::EngineMouse( 6, 7, 35, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Math::Point(10.0f, 10.0f)); + m_mice[Gfx::ENG_MOUSE_EDIT] = Gfx::EngineMouse( 8, 9, -1, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 6.0f, 10.0f)); + m_mice[Gfx::ENG_MOUSE_CROSS] = Gfx::EngineMouse(10, 11, -1, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point(10.0f, 10.0f)); + m_mice[Gfx::ENG_MOUSE_MOVEV] = Gfx::EngineMouse(12, 13, -1, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 5.0f, 11.0f)); + m_mice[Gfx::ENG_MOUSE_MOVEH] = Gfx::EngineMouse(14, 15, -1, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point(11.0f, 5.0f)); + m_mice[Gfx::ENG_MOUSE_MOVED] = Gfx::EngineMouse(16, 17, -1, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 9.0f, 9.0f)); + m_mice[Gfx::ENG_MOUSE_MOVEI] = Gfx::EngineMouse(18, 19, -1, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 9.0f, 9.0f)); + m_mice[Gfx::ENG_MOUSE_MOVE] = Gfx::EngineMouse(20, 21, -1, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point(11.0f, 11.0f)); + m_mice[Gfx::ENG_MOUSE_TARGET] = Gfx::EngineMouse(22, 23, -1, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point(15.0f, 15.0f)); + m_mice[Gfx::ENG_MOUSE_SCROLLL] = Gfx::EngineMouse(24, 25, 43, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 2.0f, 9.0f)); + m_mice[Gfx::ENG_MOUSE_SCROLLR] = Gfx::EngineMouse(26, 27, 44, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point(17.0f, 9.0f)); + m_mice[Gfx::ENG_MOUSE_SCROLLU] = Gfx::EngineMouse(28, 29, 45, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 9.0f, 2.0f)); + m_mice[Gfx::ENG_MOUSE_SCROLLD] = Gfx::EngineMouse(30, 31, 46, Gfx::ENG_RSTATE_TTEXTURE_BLACK, Gfx::ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 9.0f, 17.0f)); m_mouseSize = Math::Point(0.04f, 0.04f * (800.0f / 600.0f)); m_mousePos = Math::Point(0.5f, 0.5f); @@ -170,7 +171,7 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_mouseVisible = false; m_texPath = "textures/"; - m_defaultTexParams.format = Gfx::TEX_IMG_RGBA; + m_defaultTexParams.format = Gfx::TEX_IMG_RGB; m_defaultTexParams.mipmap = true; m_defaultTexParams.minFilter = Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR; m_defaultTexParams.magFilter = Gfx::TEX_MAG_FILTER_LINEAR; @@ -190,11 +191,6 @@ Gfx::CEngine::~CEngine() m_terrain = nullptr; } -std::string Gfx::CEngine::GetError() -{ - return m_error; -} - void Gfx::CEngine::SetDevice(Gfx::CDevice *device) { m_device = device; @@ -230,12 +226,12 @@ bool Gfx::CEngine::Create() m_text->SetDevice(m_device); if (! m_text->Create()) { - m_error = std::string("Error creating CText: ") + m_text->GetError(); + std::string error = m_text->GetError(); + GetLogger()->Error("Error creating CText: %s\n", error.c_str()); return false; } m_device->SetClearColor(Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f)); - m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false); m_device->SetShadeModel(Gfx::SHADE_SMOOTH); m_device->SetFillMode(Gfx::FILL_FILL); @@ -289,11 +285,7 @@ void Gfx::CEngine::ResetAfterDeviceChanged() bool Gfx::CEngine::ProcessEvent(const Event &event) { - if (event.type == EVENT_MOUSE_MOVE) - { - m_mousePos = event.mouseMove.pos; - } - else if (event.type == EVENT_KEY_DOWN) + if (event.type == EVENT_KEY_DOWN) { // !! Debug, to be removed later !! @@ -307,6 +299,37 @@ bool Gfx::CEngine::ProcessEvent(const Event &event) int index = static_cast(m_mouseType); m_mouseType = static_cast( (index + 1) % Gfx::ENG_MOUSE_COUNT ); } + else if (event.key.key == KEY(F3)) + { + m_backgroundQuarter = !m_backgroundQuarter; + if (m_backgroundQuarter) + { + m_backgroundFull = true; + m_backgroundName = "geneda.png"; + } + else + { + m_backgroundFull = false; + m_backgroundName = ""; + } + } + else if (event.key.key == KEY(F4)) + { + m_backForce = !m_backForce; + if (m_backForce) + { + m_backgroundColorDown = Gfx::Color(0.2f, 0.2f, 0.2f); + m_backgroundColorUp = Gfx::Color(0.8f, 0.8f, 0.8f); + } + else + { + m_backgroundColorDown = m_backgroundColorUp = Gfx::Color(0.0f, 0.0f, 0.0f); + } + } + } + else if (event.type == EVENT_FRAME) + { + m_highlightTime += event.rTime; } // By default, pass on all events @@ -954,10 +977,28 @@ void Gfx::CEngine::SetState(int state, const Gfx::Color& color) m_device->SetTextureEnabled(0, true); m_device->SetTextureStageParams(0, params); } + else if (state & Gfx::ENG_RSTATE_OPAQUE_TEXTURE) // opaque texture ? + { + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); + m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); + m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, false); + + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, true); + m_device->SetTextureEnabled(0, true); + m_device->SetTextureStageParams(0, Gfx::TextureStageParams()); // default operation + } + else if (state & Gfx::ENG_RSTATE_OPAQUE_COLOR) // opaque color ? + { + m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); + m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); + m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); + m_device->SetRenderState(Gfx::RENDER_STATE_BLENDING, false); + m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false); + } else if (state & Gfx::ENG_RSTATE_TEXT) // font rendering? { m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); - m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_TEST, false); // TODO: depth test setting elsewhere! m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); m_device->SetRenderState(Gfx::RENDER_STATE_ALPHA_TEST, false); @@ -1091,6 +1132,7 @@ void Gfx::CEngine::SetState(int state, const Gfx::Color& color) void Gfx::CEngine::SetMaterial(const Gfx::Material &mat) { + m_lastMaterial = mat; m_device->SetMaterial(mat); } @@ -1112,12 +1154,18 @@ void Gfx::CEngine::SetViewParams(const Math::Vector& eyePt, const Math::Vector& Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName, const Gfx::TextureCreateParams ¶ms) { + if (m_texBlacklist.find(texName) != m_texBlacklist.end()) + return Gfx::Texture(); // invalid texture + + // TODO: detect alpha channel? + CImage img; if (! img.Load(m_app->GetDataFilePath(m_texPath, texName))) { - std::stringstream str; - str << "Couldn't load texture '" << texName << "': " << img.GetError(); - m_error = str.str(); + std::string error = img.GetError(); + GetLogger()->Error("Couldn't load texture '%s': %s\n", texName.c_str(), error.c_str()); + GetLogger()->Error("Blacklisting texture '%s'\n", texName.c_str()); + m_texBlacklist.insert(texName); return Gfx::Texture(); // invalid texture } @@ -1125,9 +1173,10 @@ Gfx::Texture Gfx::CEngine::CreateTexture(const std::string &texName, const Gfx:: if (! result.valid) { - std::stringstream str; - str << "Couldn't load texture '" << texName << "': " << m_device->GetError(); - m_error = str.str(); + std::string error = m_device->GetError(); + GetLogger()->Error("Couldn't load texture '%s': %s\n", texName.c_str(), error.c_str()); + GetLogger()->Error("Blacklisting texture '%s'\n", texName.c_str()); + m_texBlacklist.insert(texName); return result; } @@ -1156,29 +1205,115 @@ void Gfx::CEngine::DestroyTexture(const std::string &texName) m_texNameMap.erase(it); } -bool Gfx::CEngine::LoadTexture(const std::string& name, int stage) +bool Gfx::CEngine::LoadTexture(const std::string& name) { + if (m_texBlacklist.find(name) != m_texBlacklist.end()) + return false; + std::map::iterator it = m_texNameMap.find(name); + if (it != m_texNameMap.end()) + return true; + + Gfx::Texture tex = CreateTexture(name); + return tex.valid; +} + +// TODO: create separate variables for 4 quarter names +void QuarterName(std::string& buffer, const std::string& name, int quarter) +{ + size_t pos = name.find('.'); + if (pos == std::string::npos) + { + buffer = name; + return; + } + + buffer = name.substr(0, pos) + std::string(1, static_cast('a' + quarter)) + name.substr(pos); +} + +bool Gfx::CEngine::LoadAllTextures() +{ + LoadTexture("text.png"); + LoadTexture("mouse.png"); + LoadTexture("button1.png"); + LoadTexture("button2.png"); + LoadTexture("button3.png"); + LoadTexture("effect00.png"); + LoadTexture("effect01.png"); + LoadTexture("effect02.png"); + LoadTexture("map.png"); + + if (! m_backgroundName.empty()) + { + if (m_backgroundQuarter) // image into 4 pieces? + { + for (int i = 0; i < 4; i++) + { + std::string name; + QuarterName(name, m_backgroundName, i); + LoadTexture(name); + } + } + else + { + LoadTexture(m_backgroundName); + } + } + + if (! m_foregroundName.empty()) + LoadTexture(m_foregroundName); + + m_planet->LoadTexture(); + + bool ok = true; + + /* TODO + D3DObjLevel1* p1; + D3DObjLevel2* p2; + int l1; + p1 = m_objectPointer; + for ( l1=0 ; l1totalUsed ; l1++ ) + { + p2 = p1->table[l1]; + + if ( p2 == 0 || p2->texName1[0] != 0 ) + { + if ( !LoadTexture(p2->texName1) ) ok = false; + } + + if ( p2 == 0 || p2->texName2[0] != 0 ) + { + if ( !LoadTexture(p2->texName2) ) ok = false; + } + }*/ + + return ok; +} + +bool Gfx::CEngine::SetTexture(const std::string& name, int stage) +{ + auto it = m_texNameMap.find(name); if (it != m_texNameMap.end()) { m_device->SetTexture(stage, (*it).second); return true; } - // TODO if not present... - return false; -} + if (! LoadTexture(name)) + { + m_device->SetTexture(stage, 0); // invalid texture + return false; + } -bool Gfx::CEngine::LoadAllTextures() -{ - // TODO! - return true; -} + it = m_texNameMap.find(name); + if (it != m_texNameMap.end()) + { + m_device->SetTexture(stage, (*it).second); + return true; + } -bool Gfx::CEngine::SetTexture(const std::string& name, int stage) -{ - // TODO! - return true; + m_device->SetTexture(stage, 0); // invalid texture + return false; // should not happen normally } void Gfx::CEngine::SetLimitLOD(int rank, float limit) @@ -1364,7 +1499,6 @@ float Gfx::CEngine::GetFogStart(int rank) return m_fogStart[rank]; } - void Gfx::CEngine::SetBackground(const std::string& name, Gfx::Color up, Gfx::Color down, Gfx::Color cloudUp, Gfx::Color cloudDown, bool full, bool quarter) @@ -1391,12 +1525,12 @@ void Gfx::CEngine::GetBackground(std::string& name, Gfx::Color& up, Gfx::Color& quarter = m_backgroundQuarter; } -void Gfx::CEngine::SetForegroundImageName(const std::string& name) +void Gfx::CEngine::SetForegroundName(const std::string& name) { - if (! m_foregroundImageName.empty()) - DestroyTexture(m_foregroundImageName); + if (! m_foregroundName.empty()) + DestroyTexture(m_foregroundName); - m_foregroundImageName = name; + m_foregroundName = name; } void Gfx::CEngine::SetOverFront(bool front) @@ -1714,14 +1848,11 @@ void Gfx::CEngine::Render() // Begin the scene m_device->BeginScene(); - if (m_drawWorld) Draw3DScene(); - DrawInterface(); - // End the scene m_device->EndScene(); } @@ -2113,7 +2244,8 @@ void Gfx::CEngine::DrawInterface() void Gfx::CEngine::UpdateGroundSpotTextures() { - // TODO! + // TODO the original code modifying the textures is very complex, so stub for now + GetLogger()->Info("CEngine::UpdateGroundSpotTextures(): stub!\n"); } void Gfx::CEngine::DrawShadow() @@ -2131,7 +2263,7 @@ void Gfx::CEngine::DrawShadow() material.ambient = Gfx::Color(0.5f, 0.5f, 0.5f); SetMaterial(material); - // TODO: wtf? + // TODO: create a separate texture SetTexture("text.png"); Math::Point ts, ti; @@ -2310,6 +2442,7 @@ void Gfx::CEngine::DrawShadow() m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, true); } +// STATUS: TESTED, VERIFIED void Gfx::CEngine::DrawBackground() { if (m_skyMode && m_cloud->GetLevel() != 0.0f) // clouds ? @@ -2323,12 +2456,13 @@ void Gfx::CEngine::DrawBackground() DrawBackgroundGradient(m_backgroundColorUp, m_backgroundColorDown); } - if (m_backForce || (m_skyMode && m_backgroundName[0] != 0) ) + if (m_backForce || (m_skyMode && !m_backgroundName.empty()) ) { DrawBackgroundImage(); // image } } +// STATUS: TESTED void Gfx::CEngine::DrawBackgroundGradient(const Gfx::Color& up, const Gfx::Color& down) { Math::Point p1(0.0f, 0.5f); @@ -2341,12 +2475,7 @@ void Gfx::CEngine::DrawBackgroundGradient(const Gfx::Color& up, const Gfx::Color Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f) }; - m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); - m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false); - m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); - m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false); - - SetState(Gfx::ENG_RSTATE_NORMAL); + SetState(Gfx::ENG_RSTATE_OPAQUE_COLOR); m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface); m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProjInterface); @@ -2364,6 +2493,7 @@ void Gfx::CEngine::DrawBackgroundGradient(const Gfx::Color& up, const Gfx::Color AddStatisticTriangle(2); } +// Status: PART_TESTED void Gfx::CEngine::DrawBackgroundImageQuarter(Math::Point p1, Math::Point p2, const std::string& name) { Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal @@ -2399,12 +2529,8 @@ void Gfx::CEngine::DrawBackgroundImageQuarter(Math::Point p1, Math::Point p2, co v2 = v1+h; } - m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); - m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false); - m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); - SetTexture(name); - SetState(Gfx::ENG_RSTATE_WRAP); + SetState(Gfx::ENG_RSTATE_OPAQUE_TEXTURE | Gfx::ENG_RSTATE_WRAP); m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface); m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProjInterface); @@ -2422,18 +2548,7 @@ void Gfx::CEngine::DrawBackgroundImageQuarter(Math::Point p1, Math::Point p2, co AddStatisticTriangle(2); } -void QuarterName(std::string& buffer, const std::string& name, int quarter) -{ - size_t pos = name.find('.'); - if (pos == std::string::npos) - { - buffer = name; - return; - } - - buffer = name.substr(0, pos) + std::string(1, static_cast('a' + quarter)) + name.substr(pos); -} - +// Status: TESTED, VERIFIED void Gfx::CEngine::DrawBackgroundImage() { Math::Point p1, p2; @@ -2494,9 +2609,10 @@ void Gfx::CEngine::DrawPlanet() m_planet->Draw(); // draws the planets } +// Status: PART_TESTED void Gfx::CEngine::DrawForegroundImage() { - if (m_foregroundImageName.empty()) return; + if (m_foregroundName.empty()) return; Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal @@ -2518,11 +2634,7 @@ void Gfx::CEngine::DrawForegroundImage() Gfx::Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(u2, v1)) }; - m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); - m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false ); - m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); - - SetTexture(m_foregroundImageName); + SetTexture(m_foregroundName); SetState(Gfx::ENG_RSTATE_CLAMP | Gfx::ENG_RSTATE_TTEXTURE_BLACK); m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface); @@ -2533,6 +2645,7 @@ void Gfx::CEngine::DrawForegroundImage() AddStatisticTriangle(2); } +// Status: PART_TESTED void Gfx::CEngine::DrawOverColor() { if (! m_stateColor) return; @@ -2551,29 +2664,31 @@ void Gfx::CEngine::DrawOverColor() Gfx::Color(0.0f, 0.0f, 0.0f, 0.0f) }; + SetState(m_overMode); + + // TODO: set also with m_overMode ? m_device->SetRenderState(Gfx::RENDER_STATE_DEPTH_WRITE, false); m_device->SetRenderState(Gfx::RENDER_STATE_LIGHTING, false); m_device->SetRenderState(Gfx::RENDER_STATE_FOG, false); m_device->SetRenderState(Gfx::RENDER_STATE_TEXTURING, false); - SetState(m_overMode); - m_device->SetTransform(Gfx::TRANSFORM_VIEW, m_matViewInterface); m_device->SetTransform(Gfx::TRANSFORM_PROJECTION, m_matProjInterface); m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_matWorldInterface); Gfx::VertexCol vertex[4] = { - Gfx::VertexCol(Math::Vector(p1.x, p1.y, 0.0f), color[1],color[2]), - Gfx::VertexCol(Math::Vector(p1.x, p2.y, 0.0f), color[0],color[2]), - Gfx::VertexCol(Math::Vector(p2.x, p1.y, 0.0f), color[1],color[2]), - Gfx::VertexCol(Math::Vector(p2.x, p2.y, 0.0f), color[0],color[2]) + Gfx::VertexCol(Math::Vector(p1.x, p1.y, 0.0f), color[1], color[2]), + Gfx::VertexCol(Math::Vector(p1.x, p2.y, 0.0f), color[0], color[2]), + Gfx::VertexCol(Math::Vector(p2.x, p1.y, 0.0f), color[1], color[2]), + Gfx::VertexCol(Math::Vector(p2.x, p2.y, 0.0f), color[0], color[2]) }; m_device->DrawPrimitive(Gfx::PRIMITIVE_TRIANGLE_STRIP, vertex, 4); AddStatisticTriangle(2); } +// Status: TESTED, VERIFIED void Gfx::CEngine::DrawHighlight() { Math::Point min, max; @@ -2609,9 +2724,63 @@ void Gfx::CEngine::DrawHighlight() m_highlight = true; } - // TODO: draw highlight! + if (! m_highlight) + return; + + Math::Point p1 = m_highlightP1; + Math::Point p2 = m_highlightP2; + + int nbOut = 0; + if (p1.x < 0.0f || p1.x > 1.0f) nbOut++; + if (p1.y < 0.0f || p1.y > 1.0f) nbOut++; + if (p2.x < 0.0f || p2.x > 1.0f) nbOut++; + if (p2.y < 0.0f || p2.y > 1.0f) nbOut++; + if (nbOut > 2) + return; + + SetState(Gfx::ENG_RSTATE_OPAQUE_COLOR); + + float d = 0.5f+sinf(m_highlightTime*6.0f)*0.5f; + d *= (p2.x-p1.x)*0.1f; + p1.x += d; + p1.y += d; + p2.x -= d; + p2.y -= d; + + Gfx::Color color(1.0f, 1.0f, 0.0f); // yellow + + Gfx::VertexCol line[3] = + { + Gfx::VertexCol(Math::Vector(), color), + Gfx::VertexCol(Math::Vector(), color), + Gfx::VertexCol(Math::Vector(), color) + }; + + float dx = (p2.x - p1.x) / 5.0f; + float dy = (p2.y - p1.y) / 5.0f; + + line[0].coord = Math::Vector(p1.x, p1.y + dy, 0.0f); + line[1].coord = Math::Vector(p1.x, p1.y, 0.0f); + line[2].coord = Math::Vector(p1.x + dx, p1.y, 0.0f); + m_device->DrawPrimitive(Gfx::PRIMITIVE_LINE_STRIP, line, 3); + + line[0].coord = Math::Vector(p2.x - dx, p1.y, 0.0f); + line[1].coord = Math::Vector(p2.x, p1.y, 0.0f); + line[2].coord = Math::Vector(p2.x, p1.y + dy, 0.0f); + m_device->DrawPrimitive(Gfx::PRIMITIVE_LINE_STRIP, line, 3); + + line[0].coord = Math::Vector(p2.x, p2.y - dy, 0.0f); + line[1].coord = Math::Vector(p2.x, p2.y, 0.0f); + line[2].coord = Math::Vector(p2.x - dx, p2.y, 0.0f); + m_device->DrawPrimitive(Gfx::PRIMITIVE_LINE_STRIP, line, 3); + + line[0].coord = Math::Vector(p1.x + dx, p2.y, 0.0f); + line[1].coord = Math::Vector(p1.x, p2.y, 0.0f); + line[2].coord = Math::Vector(p1.x, p2.y - dy, 0.0f); + m_device->DrawPrimitive(Gfx::PRIMITIVE_LINE_STRIP, line, 3); } +// Status: TESTED, VERIFIED void Gfx::CEngine::DrawMouse() { if (! m_mouseVisible) @@ -2647,6 +2816,7 @@ void Gfx::CEngine::DrawMouse() DrawMouseSprite(pos, m_mouseSize, m_mice[index].icon2); } +// Status: TESTED, VERIFIED void Gfx::CEngine::DrawMouseSprite(Math::Point pos, Math::Point size, int icon) { if (icon == -1) @@ -2671,8 +2841,8 @@ void Gfx::CEngine::DrawMouseSprite(Math::Point pos, Math::Point size, int icon) Gfx::Vertex vertex[4] = { Gfx::Vertex(Math::Vector(p1.x, p1.y, 0.0f), normal, Math::Point(u1, v2)), - Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), normal, Math::Point(u2, v2)), Gfx::Vertex(Math::Vector(p1.x, p2.y, 0.0f), normal, Math::Point(u1, v1)), + Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), normal, Math::Point(u2, v2)), Gfx::Vertex(Math::Vector(p2.x, p2.y, 0.0f), normal, Math::Point(u2, v1)) }; diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index c7ff084e..5a64e4e4 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -37,6 +37,7 @@ #include #include #include +#include class CApplication; @@ -78,7 +79,7 @@ struct EngineTriangle Gfx::VertexTex2 triangle[3]; //! Material Gfx::Material material; - //! Render state (TODO: ?) + //! Render state int state; //! 1st texture Gfx::Texture tex1; @@ -425,7 +426,11 @@ enum EngineRenderState //! The transparent color (white = no) ENG_RSTATE_TCOLOR_WHITE = (1<<17), //! Mode for rendering text - ENG_RSTATE_TEXT = (1<<18) + ENG_RSTATE_TEXT = (1<<18), + //! Only opaque texture, no blending, etc. + ENG_RSTATE_OPAQUE_TEXTURE = (1<<19), + //! Only opaque color, no texture, blending, etc. + ENG_RSTATE_OPAQUE_COLOR = (1<<20) }; @@ -532,9 +537,6 @@ public: CEngine(CInstanceManager* iMan, CApplication* app); ~CEngine(); - //! Returns the last error encountered - std::string GetError(); - //! Sets the device to be used void SetDevice(Gfx::CDevice* device); //! Returns the current device @@ -715,12 +717,21 @@ public: void SetViewParams(const Math::Vector& eyePt, const Math::Vector& lookatPt, const Math::Vector& upVec, float eyeDistance); + //! Creates texture with the specified params Gfx::Texture CreateTexture(const std::string& texName, const Gfx::TextureCreateParams& params); + //! Creates texture Gfx::Texture CreateTexture(const std::string& texName); + + //! Destroys texture, unloading it and removing from cache void DestroyTexture(const std::string& texName); - bool LoadTexture(const std::string& name, int stage = 0); + + //! Loads texture, creating it if not already present + bool LoadTexture(const std::string& name); + //! Loads all necessary textures bool LoadAllTextures(); + + //! Sets texture for given stage; if not present in cache, the texture is loaded bool SetTexture(const std::string& name, int stage = 0); //@{ @@ -831,8 +842,8 @@ public: bool& full, bool& quarter); //@} - //! Specifies the foreground image - void SetForegroundImageName(const std::string& name); + //! Specifies the name of foreground texture + void SetForegroundName(const std::string& name); //! Specifies whether to draw the foreground void SetOverFront(bool front); //! Sets the foreground overlay color @@ -1129,7 +1140,7 @@ protected: bool m_overFront; Gfx::Color m_overColor; int m_overMode; - std::string m_foregroundImageName; + std::string m_foregroundName; bool m_drawWorld; bool m_drawFront; float m_limitLOD[2]; @@ -1156,6 +1167,8 @@ protected: int m_highlightRank[100]; //! Highlight visible? bool m_highlight; + //! Time counter for highlight animation + float m_highlightTime; //@{ //! Highlight rectangle points Math::Point m_highlightP1; @@ -1171,6 +1184,10 @@ protected: std::map m_texNameMap; //! Reverse map of loaded textures (by texture) std::map m_revTexNameMap; + //! Blacklist map of textures + /** Textures on this list were not successful in first loading, + * so are disabled for subsequent load calls. */ + std::set m_texBlacklist; //! Mouse cursor definitions Gfx::EngineMouse m_mice[Gfx::ENG_MOUSE_COUNT]; diff --git a/src/graphics/engine/text.cpp b/src/graphics/engine/text.cpp index 0a57026c..82abd620 100644 --- a/src/graphics/engine/text.cpp +++ b/src/graphics/engine/text.cpp @@ -649,8 +649,8 @@ void Gfx::CText::DrawHighlight(Gfx::FontHighlight hl, Math::Point pos, Math::Poi Gfx::VertexCol quad[] = { Gfx::VertexCol(Math::Vector(p1.x, p1.y, 0.0f), grad[3]), - Gfx::VertexCol(Math::Vector(p2.x, p1.y, 0.0f), grad[2]), Gfx::VertexCol(Math::Vector(p1.x, p2.y, 0.0f), grad[0]), + Gfx::VertexCol(Math::Vector(p2.x, p1.y, 0.0f), grad[2]), Gfx::VertexCol(Math::Vector(p2.x, p2.y, 0.0f), grad[1]) }; @@ -688,8 +688,6 @@ void Gfx::CText::DrawChar(Gfx::UTF8Char ch, Gfx::FontType font, float size, Math cf->cache[ch] = tex; } - m_device->SetRenderState(Gfx::RENDER_STATE_CULLING, false); - Math::Point p1(pos.x, pos.y + tex.charSize.y - tex.texSize.y); Math::Point p2(pos.x + tex.texSize.x, pos.y + tex.charSize.y); @@ -698,8 +696,8 @@ void Gfx::CText::DrawChar(Gfx::UTF8Char ch, Gfx::FontType font, float size, Math Gfx::Vertex quad[4] = { Gfx::Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(0.0f, 1.0f)), - Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(1.0f, 1.0f)), Gfx::Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(0.0f, 0.0f)), + Gfx::Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(1.0f, 1.0f)), Gfx::Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(1.0f, 0.0f)) }; diff --git a/src/graphics/engine/water.cpp b/src/graphics/engine/water.cpp index 0ec52ebf..8fbd1aec 100644 --- a/src/graphics/engine/water.cpp +++ b/src/graphics/engine/water.cpp @@ -519,10 +519,7 @@ void Gfx::CWater::Create(Gfx::WaterType type1, Gfx::WaterType type2, const std:: VaporFlush(); if (! m_fileName.empty()) - { - m_engine->LoadTexture(m_fileName, 0); - m_engine->LoadTexture(m_fileName, 1); - } + m_engine->LoadTexture(m_fileName); if (m_terrain == nullptr) m_terrain = static_cast(m_iMan->SearchInstance(CLASS_TERRAIN)); diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index 4c36053b..caa79eeb 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -73,6 +73,13 @@ Gfx::CGLDevice::~CGLDevice() { } +void Gfx::CGLDevice::DebugHook() +{ + /* This function is only called here, so it can be used + * as a breakpoint when debugging using gDEBugger */ + glColor3i(0, 0, 0); +} + std::string Gfx::CGLDevice::GetError() { return m_error; @@ -1172,17 +1179,19 @@ void Gfx::CGLDevice::GetFogParams(Gfx::FogMode &mode, Gfx::Color &color, float & void Gfx::CGLDevice::SetCullMode(Gfx::CullMode mode) { - if (mode == Gfx::CULL_CW) glCullFace(GL_CW); - else if (mode == Gfx::CULL_CCW) glCullFace(GL_CCW); + // Cull clockwise back faces, so front face is the opposite + // (assuming GL_CULL_FACE is GL_BACK) + if (mode == Gfx::CULL_CW ) glFrontFace(GL_CCW); + else if (mode == Gfx::CULL_CCW) glFrontFace(GL_CW); else assert(false); } Gfx::CullMode Gfx::CGLDevice::GetCullMode() { GLint flag = 0; - glGetIntegerv(GL_CULL_FACE, &flag); - if (flag == GL_CW) return Gfx::CULL_CW; - else if (flag == GL_CCW) return Gfx::CULL_CCW; + glGetIntegerv(GL_FRONT_FACE, &flag); + if (flag == GL_CW) return Gfx::CULL_CCW; + else if (flag == GL_CCW) return Gfx::CULL_CW; else assert(false); return Gfx::CULL_CW; } diff --git a/src/graphics/opengl/gldevice.h b/src/graphics/opengl/gldevice.h index dbe9a526..3daea8a4 100644 --- a/src/graphics/opengl/gldevice.h +++ b/src/graphics/opengl/gldevice.h @@ -76,6 +76,8 @@ public: CGLDevice(const Gfx::GLDeviceConfig &config); virtual ~CGLDevice(); + virtual void DebugHook(); + virtual std::string GetError(); virtual bool Create();