2014-10-14 13:11:37 +00:00
|
|
|
|
/*
|
|
|
|
|
* This file is part of the Colobot: Gold Edition source code
|
|
|
|
|
* Copyright (C) 2001-2014, Daniel Roux, EPSITEC SA & TerranovaTeam
|
|
|
|
|
* http://epsiteс.ch; http://colobot.info; http://github.com/colobot
|
|
|
|
|
*
|
|
|
|
|
* 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://gnu.org/licenses
|
|
|
|
|
*/
|
2012-06-22 14:31:55 +00:00
|
|
|
|
|
|
|
|
|
|
2012-07-26 20:26:19 +00:00
|
|
|
|
#include "graphics/engine/engine.h"
|
2012-06-22 14:31:55 +00:00
|
|
|
|
|
2012-07-22 20:05:12 +00:00
|
|
|
|
#include "app/app.h"
|
2014-12-11 18:01:57 +00:00
|
|
|
|
#include "app/input.h"
|
2012-09-19 21:50:28 +00:00
|
|
|
|
|
2012-07-22 20:05:12 +00:00
|
|
|
|
#include "common/image.h"
|
|
|
|
|
#include "common/key.h"
|
2012-07-23 19:41:27 +00:00
|
|
|
|
#include "common/logger.h"
|
2012-09-19 21:50:28 +00:00
|
|
|
|
|
2012-07-26 20:26:19 +00:00
|
|
|
|
#include "graphics/core/device.h"
|
2012-08-09 20:50:04 +00:00
|
|
|
|
#include "graphics/engine/camera.h"
|
|
|
|
|
#include "graphics/engine/cloud.h"
|
2012-08-03 21:23:13 +00:00
|
|
|
|
#include "graphics/engine/lightman.h"
|
2012-08-09 20:50:04 +00:00
|
|
|
|
#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"
|
2012-08-03 21:23:13 +00:00
|
|
|
|
#include "graphics/engine/text.h"
|
2012-08-09 20:50:04 +00:00
|
|
|
|
#include "graphics/engine/water.h"
|
2012-09-19 21:50:28 +00:00
|
|
|
|
|
2012-07-01 20:59:22 +00:00
|
|
|
|
#include "math/geometry.h"
|
2012-09-19 21:50:28 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
#include "sound/sound.h"
|
2012-09-19 21:50:28 +00:00
|
|
|
|
|
2012-09-16 08:38:08 +00:00
|
|
|
|
#include "ui/interface.h"
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2013-05-26 17:34:05 +00:00
|
|
|
|
#include <iomanip>
|
|
|
|
|
|
2013-02-16 21:37:43 +00:00
|
|
|
|
template<> Gfx::CEngine* CSingleton<Gfx::CEngine>::m_instance = nullptr;
|
2012-06-25 17:59:17 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
// Graphics module namespace
|
|
|
|
|
namespace Gfx {
|
|
|
|
|
|
2013-02-16 21:37:43 +00:00
|
|
|
|
CEngine::CEngine(CApplication *app)
|
2012-06-25 17:59:17 +00:00
|
|
|
|
{
|
2012-07-01 20:59:22 +00:00
|
|
|
|
m_app = app;
|
2012-08-03 21:23:13 +00:00
|
|
|
|
m_device = nullptr;
|
2012-07-01 20:59:22 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_lightMan = nullptr;
|
2012-08-03 21:23:13 +00:00
|
|
|
|
m_text = nullptr;
|
|
|
|
|
m_particle = nullptr;
|
|
|
|
|
m_water = nullptr;
|
|
|
|
|
m_cloud = nullptr;
|
|
|
|
|
m_lightning = nullptr;
|
|
|
|
|
m_planet = nullptr;
|
|
|
|
|
m_sound = nullptr;
|
|
|
|
|
m_terrain = nullptr;
|
2013-12-31 11:58:45 +00:00
|
|
|
|
m_pause = nullptr;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-20 18:37:37 +00:00
|
|
|
|
m_showStats = false;
|
|
|
|
|
|
2012-07-22 20:05:12 +00:00
|
|
|
|
m_focus = 0.75f;
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-07-22 20:05:12 +00:00
|
|
|
|
m_rankView = 0;
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_ambientColor[0] = Color(0.5f, 0.5f, 0.5f, 0.5f);
|
|
|
|
|
m_ambientColor[1] = Color(0.5f, 0.5f, 0.5f, 0.5f);
|
|
|
|
|
m_fogColor[0] = Color(1.0f, 1.0f, 1.0f, 1.0f);
|
|
|
|
|
m_fogColor[1] = Color(1.0f, 1.0f, 1.0f, 1.0f);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
m_deepView[0] = 1000.0f;
|
|
|
|
|
m_deepView[1] = 1000.0f;
|
|
|
|
|
m_fogStart[0] = 0.75f;
|
|
|
|
|
m_fogStart[1] = 0.75f;
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_waterAddColor = Color(0.0f, 0.0f, 0.0f, 0.0f);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
|
|
|
|
m_render = true;
|
|
|
|
|
m_movieLock = false;
|
|
|
|
|
m_shadowVisible = true;
|
|
|
|
|
m_groundSpotVisible = true;
|
|
|
|
|
m_dirty = true;
|
|
|
|
|
m_fog = true;
|
2014-11-10 19:46:39 +00:00
|
|
|
|
m_secondTex = "";
|
2012-07-22 20:05:12 +00:00
|
|
|
|
m_eyeDirH = 0.0f;
|
|
|
|
|
m_eyeDirV = 0.0f;
|
|
|
|
|
m_backgroundName = ""; // no background image
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_backgroundColorUp = Color();
|
|
|
|
|
m_backgroundColorDown = Color();
|
|
|
|
|
m_backgroundCloudUp = Color();
|
|
|
|
|
m_backgroundCloudDown = Color();
|
2012-07-22 20:05:12 +00:00
|
|
|
|
m_backgroundFull = false;
|
|
|
|
|
m_overFront = true;
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_overColor = Color();
|
2012-07-22 20:05:12 +00:00
|
|
|
|
m_overMode = ENG_RSTATE_TCOLOR_BLACK;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_highlightRank[0] = -1; // empty list
|
2012-08-12 08:45:04 +00:00
|
|
|
|
m_highlightTime = 0.0f;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
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;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_particleDensity = 1.0f;
|
2012-09-22 15:36:10 +00:00
|
|
|
|
m_lastClippingDistance = m_clippingDistance = 1.0f;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
m_objectDetail = 1.0f;
|
|
|
|
|
m_terrainVision = 1000.0f;
|
|
|
|
|
m_gadgetQuantity = 1.0f;
|
|
|
|
|
m_textureQuality = 1;
|
2015-05-06 15:55:10 +00:00
|
|
|
|
m_textureMipmapLevel = 1;
|
|
|
|
|
m_textureAnisotropy = 1;
|
2015-05-11 13:21:17 +00:00
|
|
|
|
m_shadowMapping = false;
|
2015-05-12 11:09:31 +00:00
|
|
|
|
m_offscreenShadowRendering = false;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
m_totoMode = true;
|
|
|
|
|
m_lensMode = true;
|
|
|
|
|
m_waterMode = true;
|
|
|
|
|
m_skyMode = true;
|
2012-09-20 18:37:37 +00:00
|
|
|
|
m_backForce = true;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
m_planetMode = true;
|
|
|
|
|
m_lightMode = true;
|
|
|
|
|
m_editIndentMode = true;
|
|
|
|
|
m_editIndentValue = 4;
|
|
|
|
|
m_tracePrecision = 1.0f;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_updateGeometry = false;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_updateStaticBuffers = false;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-27 21:18:12 +00:00
|
|
|
|
m_interfaceMode = false;
|
|
|
|
|
|
2013-06-17 16:06:39 +00:00
|
|
|
|
m_debugLights = false;
|
|
|
|
|
m_debugDumpLights = false;
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_mice[ENG_MOUSE_NORM] = EngineMouse( 0, 1, 32, ENG_RSTATE_TTEXTURE_WHITE, ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 1.0f, 1.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_WAIT] = EngineMouse( 2, 3, 33, ENG_RSTATE_TTEXTURE_WHITE, ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 8.0f, 12.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_HAND] = EngineMouse( 4, 5, 34, ENG_RSTATE_TTEXTURE_WHITE, ENG_RSTATE_TTEXTURE_BLACK, Math::Point( 7.0f, 2.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_NO] = EngineMouse( 6, 7, 35, ENG_RSTATE_TTEXTURE_WHITE, ENG_RSTATE_TTEXTURE_BLACK, Math::Point(10.0f, 10.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_EDIT] = EngineMouse( 8, 9, -1, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 6.0f, 10.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_CROSS] = EngineMouse(10, 11, -1, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point(10.0f, 10.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_MOVEV] = EngineMouse(12, 13, -1, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 5.0f, 11.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_MOVEH] = EngineMouse(14, 15, -1, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point(11.0f, 5.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_MOVED] = EngineMouse(16, 17, -1, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 9.0f, 9.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_MOVEI] = EngineMouse(18, 19, -1, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 9.0f, 9.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_MOVE] = EngineMouse(20, 21, -1, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point(11.0f, 11.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_TARGET] = EngineMouse(22, 23, -1, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point(15.0f, 15.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_SCROLLL] = EngineMouse(24, 25, 43, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 2.0f, 9.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_SCROLLR] = EngineMouse(26, 27, 44, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point(17.0f, 9.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_SCROLLU] = EngineMouse(28, 29, 45, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 9.0f, 2.0f));
|
|
|
|
|
m_mice[ENG_MOUSE_SCROLLD] = EngineMouse(30, 31, 46, ENG_RSTATE_TTEXTURE_BLACK, ENG_RSTATE_TTEXTURE_WHITE, Math::Point( 9.0f, 17.0f));
|
2012-07-23 19:41:27 +00:00
|
|
|
|
|
|
|
|
|
m_mouseSize = Math::Point(0.04f, 0.04f * (800.0f / 600.0f));
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_mouseType = ENG_MOUSE_NORM;
|
2012-09-20 18:37:37 +00:00
|
|
|
|
|
|
|
|
|
m_fpsCounter = 0;
|
2013-03-23 23:03:37 +00:00
|
|
|
|
m_lastFrameTime = GetSystemUtils()->CreateTimeStamp();
|
|
|
|
|
m_currentFrameTime = GetSystemUtils()->CreateTimeStamp();
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2015-05-06 15:55:10 +00:00
|
|
|
|
TexFilter filter = TEX_FILTER_BILINEAR;
|
|
|
|
|
bool mipmaps = false;
|
|
|
|
|
|
|
|
|
|
int value;
|
|
|
|
|
if (CProfile::GetInstance().GetIntProperty("Setup", "FilterMode", value))
|
|
|
|
|
{
|
|
|
|
|
if (value == 1) filter = TEX_FILTER_NEAREST;
|
|
|
|
|
else if (value == 2) filter = TEX_FILTER_BILINEAR;
|
|
|
|
|
else if (value == 3) filter = TEX_FILTER_TRILINEAR, mipmaps = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (CProfile::GetInstance().GetIntProperty("Setup", "MipmapLevel", value))
|
|
|
|
|
{
|
|
|
|
|
m_textureMipmapLevel = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (CProfile::GetInstance().GetIntProperty("Setup", "Anisotropy", value))
|
|
|
|
|
{
|
|
|
|
|
m_textureAnisotropy = value;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
if (CProfile::GetInstance().GetIntProperty("Setup", "ShadowMapping", value))
|
|
|
|
|
{
|
|
|
|
|
m_shadowMapping = (value > 0);
|
2015-05-12 11:09:31 +00:00
|
|
|
|
m_offscreenShadowRendering = (value > 1);
|
2015-05-11 13:21:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_defaultTexParams.format = TEX_IMG_AUTO;
|
2015-05-06 15:55:10 +00:00
|
|
|
|
m_defaultTexParams.mipmap = mipmaps;
|
|
|
|
|
m_defaultTexParams.filter = filter;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-29 08:40:11 +00:00
|
|
|
|
m_terrainTexParams.format = TEX_IMG_AUTO;
|
2015-05-06 15:55:10 +00:00
|
|
|
|
m_terrainTexParams.mipmap = mipmaps;
|
|
|
|
|
m_terrainTexParams.filter = filter;
|
2015-05-11 13:21:17 +00:00
|
|
|
|
|
|
|
|
|
// Compute bias matrix for shadow mapping
|
|
|
|
|
Math::Matrix temp1, temp2;
|
|
|
|
|
Math::LoadScaleMatrix(temp1, Math::Vector(0.5f, 0.5f, 0.5f));
|
|
|
|
|
Math::LoadTranslationMatrix(temp2, Math::Vector(1.0f, 1.0f, 1.0f));
|
|
|
|
|
//m_shadowBias = Math::MultiplyMatrices(m_shadowBias, temporary);
|
|
|
|
|
m_shadowBias = Math::MultiplyMatrices(temp1, temp2);
|
2012-06-25 17:59:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
CEngine::~CEngine()
|
2012-06-25 17:59:17 +00:00
|
|
|
|
{
|
2013-02-16 21:37:43 +00:00
|
|
|
|
m_app = nullptr;
|
|
|
|
|
m_sound = nullptr;
|
|
|
|
|
m_device = nullptr;
|
|
|
|
|
m_text = nullptr;
|
|
|
|
|
m_lightMan = nullptr;
|
|
|
|
|
m_particle = nullptr;
|
|
|
|
|
m_water = nullptr;
|
|
|
|
|
m_cloud = nullptr;
|
|
|
|
|
m_lightning = nullptr;
|
|
|
|
|
m_planet = nullptr;
|
|
|
|
|
m_terrain = nullptr;
|
2013-12-31 11:58:45 +00:00
|
|
|
|
m_pause = nullptr;
|
2012-09-20 18:37:37 +00:00
|
|
|
|
|
2013-03-23 23:03:37 +00:00
|
|
|
|
GetSystemUtils()->DestroyTimeStamp(m_lastFrameTime);
|
2012-09-20 18:37:37 +00:00
|
|
|
|
m_lastFrameTime = nullptr;
|
2013-03-23 23:03:37 +00:00
|
|
|
|
GetSystemUtils()->DestroyTimeStamp(m_currentFrameTime);
|
2012-09-20 18:37:37 +00:00
|
|
|
|
m_currentFrameTime = nullptr;
|
2012-06-25 17:59:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetDevice(CDevice *device)
|
2012-06-30 23:37:30 +00:00
|
|
|
|
{
|
2012-08-03 21:23:13 +00:00
|
|
|
|
m_device = device;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
CDevice* CEngine::GetDevice()
|
2012-08-03 21:23:13 +00:00
|
|
|
|
{
|
|
|
|
|
return m_device;
|
2012-06-30 23:37:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-02-16 21:37:43 +00:00
|
|
|
|
CText* CEngine::GetText()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2013-02-16 21:37:43 +00:00
|
|
|
|
return m_text;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-02-16 21:37:43 +00:00
|
|
|
|
CLightManager* CEngine::GetLightManager()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2013-02-16 21:37:43 +00:00
|
|
|
|
return m_lightMan;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CParticle* CEngine::GetParticle()
|
|
|
|
|
{
|
|
|
|
|
return m_particle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CTerrain* CEngine::GetTerrain()
|
|
|
|
|
{
|
|
|
|
|
return m_terrain;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CWater* CEngine::GetWater()
|
|
|
|
|
{
|
|
|
|
|
return m_water;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-02-16 21:37:43 +00:00
|
|
|
|
CLightning* CEngine::GetLightning()
|
|
|
|
|
{
|
|
|
|
|
return m_lightning;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CPlanet* CEngine::GetPlanet()
|
|
|
|
|
{
|
|
|
|
|
return m_planet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CCloud* CEngine::GetCloud()
|
|
|
|
|
{
|
|
|
|
|
return m_cloud;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::SetTerrain(CTerrain* terrain)
|
|
|
|
|
{
|
|
|
|
|
m_terrain = terrain;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::Create()
|
2012-06-25 17:59:17 +00:00
|
|
|
|
{
|
2013-01-27 10:43:53 +00:00
|
|
|
|
m_size = m_app->GetVideoConfig().size;
|
2012-06-25 17:59:17 +00:00
|
|
|
|
|
2013-02-16 21:37:43 +00:00
|
|
|
|
m_lightMan = new CLightManager(this);
|
|
|
|
|
m_text = new CText(this);
|
|
|
|
|
m_particle = new CParticle(this);
|
|
|
|
|
m_water = new CWater(this);
|
|
|
|
|
m_cloud = new CCloud(this);
|
|
|
|
|
m_lightning = new CLightning(this);
|
|
|
|
|
m_planet = new CPlanet(this);
|
2013-12-31 11:58:45 +00:00
|
|
|
|
m_pause = new CPauseManager();
|
2012-07-24 22:27:01 +00:00
|
|
|
|
|
2012-08-26 23:02:25 +00:00
|
|
|
|
m_lightMan->SetDevice(m_device);
|
2012-10-05 16:59:49 +00:00
|
|
|
|
m_particle->SetDevice(m_device);
|
2012-08-26 23:02:25 +00:00
|
|
|
|
|
2012-08-03 21:23:13 +00:00
|
|
|
|
m_text->SetDevice(m_device);
|
|
|
|
|
if (! m_text->Create())
|
|
|
|
|
{
|
2012-08-12 08:45:04 +00:00
|
|
|
|
std::string error = m_text->GetError();
|
|
|
|
|
GetLogger()->Error("Error creating CText: %s\n", error.c_str());
|
2012-08-03 21:23:13 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetClearColor(Color(0.0f, 0.0f, 0.0f, 0.0f));
|
|
|
|
|
m_device->SetShadeModel(SHADE_SMOOTH);
|
|
|
|
|
m_device->SetFillMode(FILL_POLY);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
SetFocus(m_focus);
|
2012-08-03 21:23:13 +00:00
|
|
|
|
|
2012-07-22 20:05:12 +00:00
|
|
|
|
m_matWorldInterface.LoadIdentity();
|
|
|
|
|
m_matViewInterface.LoadIdentity();
|
2012-08-03 21:23:13 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
Math::LoadOrthoProjectionMatrix(m_matProjInterface, 0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
|
2012-08-03 21:23:13 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
TextureCreateParams params;
|
2013-10-29 20:59:23 +00:00
|
|
|
|
params.format = TEX_IMG_AUTO;
|
2015-05-06 15:55:10 +00:00
|
|
|
|
params.filter = TEX_FILTER_NEAREST;
|
2012-08-03 21:23:13 +00:00
|
|
|
|
params.mipmap = false;
|
2014-07-24 20:17:49 +00:00
|
|
|
|
m_miceTexture = LoadTexture("textures/interface/mouse.png", params);
|
2012-08-03 21:23:13 +00:00
|
|
|
|
|
2013-03-23 23:03:37 +00:00
|
|
|
|
GetSystemUtils()->GetCurrentTimeStamp(m_currentFrameTime);
|
|
|
|
|
GetSystemUtils()->GetCurrentTimeStamp(m_lastFrameTime);
|
2012-09-20 18:37:37 +00:00
|
|
|
|
|
2012-07-01 20:59:22 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
2012-06-25 17:59:17 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::Destroy()
|
2012-07-01 20:59:22 +00:00
|
|
|
|
{
|
2012-08-03 21:23:13 +00:00
|
|
|
|
m_text->Destroy();
|
2014-10-25 16:00:39 +00:00
|
|
|
|
|
|
|
|
|
delete m_pause;
|
|
|
|
|
m_pause = nullptr;
|
2012-06-25 17:59:17 +00:00
|
|
|
|
|
2012-08-03 21:23:13 +00:00
|
|
|
|
delete m_lightMan;
|
|
|
|
|
m_lightMan = nullptr;
|
2012-07-24 22:27:01 +00:00
|
|
|
|
|
|
|
|
|
delete m_text;
|
2012-08-03 21:23:13 +00:00
|
|
|
|
m_text = nullptr;
|
2012-07-24 22:27:01 +00:00
|
|
|
|
|
|
|
|
|
delete m_particle;
|
2012-08-03 21:23:13 +00:00
|
|
|
|
m_particle = nullptr;
|
2012-07-24 22:27:01 +00:00
|
|
|
|
|
|
|
|
|
delete m_water;
|
2012-08-03 21:23:13 +00:00
|
|
|
|
m_water = nullptr;
|
2012-07-24 22:27:01 +00:00
|
|
|
|
|
|
|
|
|
delete m_cloud;
|
2012-08-03 21:23:13 +00:00
|
|
|
|
m_cloud = nullptr;
|
2012-07-24 22:27:01 +00:00
|
|
|
|
|
|
|
|
|
delete m_lightning;
|
2012-08-03 21:23:13 +00:00
|
|
|
|
m_lightning = nullptr;
|
2012-07-24 22:27:01 +00:00
|
|
|
|
|
|
|
|
|
delete m_planet;
|
2012-08-09 20:50:04 +00:00
|
|
|
|
m_planet = nullptr;
|
2012-07-01 20:59:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::ResetAfterDeviceChanged()
|
2012-07-29 13:09:53 +00:00
|
|
|
|
{
|
2014-10-20 19:54:52 +00:00
|
|
|
|
m_size = m_app->GetVideoConfig().size;
|
2013-01-03 23:29:19 +00:00
|
|
|
|
|
2012-09-30 08:56:35 +00:00
|
|
|
|
m_text->FlushCache();
|
|
|
|
|
|
2013-05-26 12:50:23 +00:00
|
|
|
|
FlushTextureCache();
|
2014-10-25 16:00:39 +00:00
|
|
|
|
|
|
|
|
|
LoadAllTextures();
|
2012-07-29 13:09:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::ProcessEvent(const Event &event)
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2012-08-12 08:45:04 +00:00
|
|
|
|
if (event.type == EVENT_KEY_DOWN)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-20 18:37:37 +00:00
|
|
|
|
if (event.key.key == KEY(F12))
|
2013-06-17 16:06:39 +00:00
|
|
|
|
{
|
2012-09-20 18:37:37 +00:00
|
|
|
|
m_showStats = !m_showStats;
|
2013-06-17 16:06:39 +00:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (event.key.key == KEY(F11))
|
|
|
|
|
{
|
|
|
|
|
m_debugLights = !m_debugLights;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (event.key.key == KEY(F10))
|
|
|
|
|
{
|
|
|
|
|
m_debugDumpLights = true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2012-08-12 08:45:04 +00:00
|
|
|
|
}
|
2012-07-23 19:41:27 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
// By default, pass on all events
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::FrameUpdate()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-20 18:37:37 +00:00
|
|
|
|
m_fpsCounter++;
|
|
|
|
|
|
2013-03-23 23:03:37 +00:00
|
|
|
|
GetSystemUtils()->GetCurrentTimeStamp(m_currentFrameTime);
|
|
|
|
|
float diff = GetSystemUtils()->TimeStampDiff(m_lastFrameTime, m_currentFrameTime, STU_SEC);
|
2012-09-20 18:37:37 +00:00
|
|
|
|
if (diff > 1.0f)
|
|
|
|
|
{
|
2013-03-23 23:03:37 +00:00
|
|
|
|
GetSystemUtils()->CopyTimeStamp(m_lastFrameTime, m_currentFrameTime);
|
2012-09-20 18:37:37 +00:00
|
|
|
|
|
|
|
|
|
m_fps = m_fpsCounter / diff;
|
2012-09-21 22:38:17 +00:00
|
|
|
|
m_fpsCounter = 0;
|
2012-09-20 18:37:37 +00:00
|
|
|
|
|
|
|
|
|
if (m_showStats)
|
|
|
|
|
{
|
|
|
|
|
std::stringstream str;
|
|
|
|
|
str << "FPS: ";
|
|
|
|
|
str.precision(2);
|
|
|
|
|
str.setf(std::ios_base::fixed);
|
|
|
|
|
str << m_fps;
|
|
|
|
|
m_fpsText = str.str();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-12 21:43:04 +00:00
|
|
|
|
float rTime = m_app->GetRelTime();
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_lightMan->UpdateProgression(rTime);
|
2012-10-25 21:29:49 +00:00
|
|
|
|
|
|
|
|
|
m_app->StartPerformanceCounter(PCNT_UPDATE_PARTICLE);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_particle->FrameParticle(rTime);
|
2012-10-25 21:29:49 +00:00
|
|
|
|
m_app->StopPerformanceCounter(PCNT_UPDATE_PARTICLE);
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
ComputeDistance();
|
|
|
|
|
UpdateGeometry();
|
2012-12-26 19:58:02 +00:00
|
|
|
|
UpdateStaticBuffers();
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-12 21:43:04 +00:00
|
|
|
|
m_highlightTime = m_app->GetAbsTime();
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
if (m_groundMark.draw)
|
2012-07-23 19:41:27 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
if (m_groundMark.phase == ENG_GR_MARK_PHASE_INC) // growing?
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
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;
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_groundMark.phase = ENG_GR_MARK_PHASE_FIX;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (m_groundMark.phase == ENG_GR_MARK_PHASE_FIX) // fixed?
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_groundMark.fix += rTime*(1.0f/m_groundMark.delay[1]);
|
|
|
|
|
if (m_groundMark.fix >= 1.0f)
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_groundMark.phase = ENG_GR_MARK_PHASE_DEC;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (m_groundMark.phase == ENG_GR_MARK_PHASE_DEC) // decay?
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_groundMark.intensity -= rTime*(1.0f/m_groundMark.delay[2]);
|
|
|
|
|
if (m_groundMark.intensity < 0.0f)
|
|
|
|
|
{
|
|
|
|
|
m_groundMark.intensity = 0.0f;
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_groundMark.phase = ENG_GR_MARK_PHASE_NULL;
|
2012-10-25 21:29:49 +00:00
|
|
|
|
m_groundMark.draw = false;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
2012-07-23 19:41:27 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::WriteScreenShot(const std::string& fileName, int width, int height)
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2014-06-23 22:35:05 +00:00
|
|
|
|
void *pixels = m_device->GetFrameBufferPixels();
|
|
|
|
|
CImage img({width,height});
|
|
|
|
|
|
|
|
|
|
img.SetDataPixels(pixels);
|
2014-06-24 17:27:31 +00:00
|
|
|
|
img.flipVertically();
|
2014-06-23 22:35:05 +00:00
|
|
|
|
|
|
|
|
|
if ( img.SavePNG(fileName.c_str()) ){
|
|
|
|
|
GetLogger()->Info("Save SceenShot Saved Successfully!\n");
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else{
|
|
|
|
|
GetLogger()->Error("%s!\n",img.GetError().c_str());
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetPause()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2013-12-31 11:58:45 +00:00
|
|
|
|
return m_pause->GetPause();
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetMovieLock(bool lock)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_movieLock = lock;
|
|
|
|
|
}
|
2012-07-23 19:41:27 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetMovieLock()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_movieLock;
|
|
|
|
|
}
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetShowStats(bool show)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_showStats = show;
|
|
|
|
|
}
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetShowStats()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_showStats;
|
|
|
|
|
}
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetRenderEnable(bool enable)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_render = enable;
|
|
|
|
|
}
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Math::IntPoint CEngine::GetWindowSize()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_size;
|
|
|
|
|
}
|
2012-07-23 19:41:27 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Math::Point CEngine::WindowToInterfaceCoords(Math::IntPoint pos)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-11 15:17:04 +00:00
|
|
|
|
return Math::Point( static_cast<float>(pos.x) / static_cast<float>(m_size.x),
|
|
|
|
|
1.0f - static_cast<float>(pos.y) / static_cast<float>(m_size.y) );
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
2012-07-23 19:41:27 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Math::IntPoint CEngine::InterfaceToWindowCoords(Math::Point pos)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-11 15:17:04 +00:00
|
|
|
|
return Math::IntPoint(static_cast<int>(pos.x * m_size.x),
|
|
|
|
|
static_cast<int>((1.0f - pos.y) * m_size.y));
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
2012-07-23 19:41:27 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Math::Point CEngine::WindowToInterfaceSize(Math::IntPoint size)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-11 15:17:04 +00:00
|
|
|
|
return Math::Point(static_cast<float>(size.x) / static_cast<float>(m_size.x),
|
|
|
|
|
static_cast<float>(size.y) / static_cast<float>(m_size.y));
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
2012-07-23 19:41:27 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Math::IntPoint CEngine::InterfaceToWindowSize(Math::Point size)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-11 15:17:04 +00:00
|
|
|
|
return Math::IntPoint(static_cast<int>(size.x * m_size.x),
|
2012-12-26 19:58:02 +00:00
|
|
|
|
static_cast<int>(size.y * m_size.y));
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
2012-07-23 19:41:27 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::AddStatisticTriangle(int count)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_statisticTriangle += count;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
int CEngine::GetStatisticTriangle()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_statisticTriangle;
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-11 16:51:13 +00:00
|
|
|
|
void CEngine::SetStatisticPos(Math::Vector pos)
|
|
|
|
|
{
|
|
|
|
|
m_statisticPos = pos;
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-29 16:53:46 +00:00
|
|
|
|
void CEngine::SetTimerDisplay(const std::string& text)
|
|
|
|
|
{
|
|
|
|
|
m_timerText = text;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************************************
|
|
|
|
|
Object management
|
|
|
|
|
*******************************************************/
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
EngineBaseObjTexTier& CEngine::AddLevel2(EngineBaseObject& p1, const std::string& tex1Name, const std::string& tex2Name)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
for (int i = 0; i < static_cast<int>( p1.next.size() ); i++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
if (p1.next[i].tex1Name == tex1Name && p1.next[i].tex2Name == tex2Name)
|
|
|
|
|
return p1.next[i];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
p1.next.push_back(EngineBaseObjTexTier(tex1Name, tex2Name));
|
|
|
|
|
return p1.next.back();
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
EngineBaseObjLODTier& CEngine::AddLevel3(EngineBaseObjTexTier& p2, LODLevel lodLevel)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 17:28:22 +00:00
|
|
|
|
for (int i = 0; i < static_cast<int>( p2.next.size() ); i++)
|
|
|
|
|
{
|
2013-01-27 10:43:53 +00:00
|
|
|
|
if (p2.next[i].lodLevel == lodLevel)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
return p2.next[i];
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
p2.next.push_back(EngineBaseObjLODTier(lodLevel));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
return p2.next.back();
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjDataTier& CEngine::AddLevel4(EngineBaseObjLODTier& p3, EngineTriangleType type,
|
|
|
|
|
const Material& material, int state)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 17:28:22 +00:00
|
|
|
|
for (int i = 0; i < static_cast<int>( p3.next.size() ); i++)
|
|
|
|
|
{
|
|
|
|
|
if ( (p3.next[i].type == type) && (p3.next[i].material == material) && (p3.next[i].state == state) )
|
|
|
|
|
return p3.next[i];
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
p3.next.push_back(EngineBaseObjDataTier(type, material, state));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
return p3.next.back();
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int CEngine::CreateBaseObject()
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
int baseObjRank = 0;
|
|
|
|
|
for ( ; baseObjRank < static_cast<int>( m_baseObjects.size() ); baseObjRank++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
if (! m_baseObjects[baseObjRank].used)
|
2012-12-26 19:58:02 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
m_baseObjects[baseObjRank].LoadDefault();
|
2012-12-26 19:58:02 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
if (baseObjRank == static_cast<int>( m_baseObjects.size() ))
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_baseObjects.push_back(EngineBaseObject());
|
|
|
|
|
else
|
2012-12-27 13:18:16 +00:00
|
|
|
|
m_baseObjects[baseObjRank].LoadDefault();
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
m_baseObjects[baseObjRank].used = true;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
return baseObjRank;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
}
|
2012-12-14 20:30:35 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::DeleteBaseObject(int baseObjRank)
|
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
|
|
|
|
|
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
|
|
|
|
|
if (! p1.used)
|
|
|
|
|
return;
|
2012-12-14 20:30:35 +00:00
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
2012-12-26 19:58:02 +00:00
|
|
|
|
|
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
|
|
|
|
|
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
|
|
|
|
|
|
|
|
|
m_device->DestroyStaticBuffer(p4.staticBufferId);
|
|
|
|
|
p4.staticBufferId = 0;
|
|
|
|
|
}
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-12-27 13:18:16 +00:00
|
|
|
|
|
|
|
|
|
p1.next.clear();
|
|
|
|
|
|
|
|
|
|
p1.used = false;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::DeleteAllBaseObjects()
|
|
|
|
|
{
|
2013-10-13 12:44:12 +00:00
|
|
|
|
for (int baseObjRank = 0; baseObjRank < static_cast<int>( m_baseObjects.size() ); baseObjRank++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
if (! p1.used)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
|
|
|
|
|
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
|
|
|
|
|
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
|
|
|
|
|
|
|
|
|
m_device->DestroyStaticBuffer(p4.staticBufferId);
|
|
|
|
|
p4.staticBufferId = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_baseObjects.clear();
|
|
|
|
|
}
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::CopyBaseObject(int sourceBaseObjRank, int destBaseObjRank)
|
|
|
|
|
{
|
|
|
|
|
assert(sourceBaseObjRank >= 0 && sourceBaseObjRank < static_cast<int>( m_baseObjects.size() ));
|
|
|
|
|
assert(destBaseObjRank >= 0 && destBaseObjRank < static_cast<int>( m_baseObjects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_baseObjects[destBaseObjRank] = m_baseObjects[sourceBaseObjRank];
|
2013-03-31 11:06:38 +00:00
|
|
|
|
|
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[destBaseObjRank];
|
|
|
|
|
|
|
|
|
|
if (! p1.used)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
|
|
|
|
|
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
|
|
|
|
|
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
|
|
|
|
p4.staticBufferId = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector<VertexTex2>& vertices,
|
|
|
|
|
EngineTriangleType triangleType,
|
|
|
|
|
const Material& material, int state,
|
|
|
|
|
std::string tex1Name, std::string tex2Name,
|
2013-01-27 10:43:53 +00:00
|
|
|
|
LODLevel lodLevel, bool globalUpdate)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name);
|
2013-01-27 10:43:53 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = AddLevel3(p2, lodLevel);
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjDataTier& p4 = AddLevel4(p3, triangleType, material, state);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
p4.vertices.insert(p4.vertices.end(), vertices.begin(), vertices.end());
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
p4.updateStaticBuffer = true;
|
|
|
|
|
m_updateStaticBuffers = true;
|
2012-12-14 20:30:35 +00:00
|
|
|
|
|
2012-08-12 17:28:22 +00:00
|
|
|
|
if (globalUpdate)
|
|
|
|
|
{
|
|
|
|
|
m_updateGeometry = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < static_cast<int>( vertices.size() ); i++)
|
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
p1.bboxMin.x = Math::Min(vertices[i].coord.x, p1.bboxMin.x);
|
|
|
|
|
p1.bboxMin.y = Math::Min(vertices[i].coord.y, p1.bboxMin.y);
|
|
|
|
|
p1.bboxMin.z = Math::Min(vertices[i].coord.z, p1.bboxMin.z);
|
|
|
|
|
p1.bboxMax.x = Math::Max(vertices[i].coord.x, p1.bboxMax.x);
|
|
|
|
|
p1.bboxMax.y = Math::Max(vertices[i].coord.y, p1.bboxMax.y);
|
|
|
|
|
p1.bboxMax.z = Math::Max(vertices[i].coord.z, p1.bboxMax.z);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (triangleType == ENG_TRIANGLE_TYPE_TRIANGLES)
|
2012-12-27 13:18:16 +00:00
|
|
|
|
p1.totalTriangles += vertices.size() / 3;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
else
|
2012-12-27 13:18:16 +00:00
|
|
|
|
p1.totalTriangles += vertices.size() - 2;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buffer,
|
|
|
|
|
std::string tex1Name, std::string tex2Name,
|
2013-01-27 10:43:53 +00:00
|
|
|
|
LODLevel lodLevel, bool globalUpdate)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
EngineBaseObjTexTier& p2 = AddLevel2(p1, tex1Name, tex2Name);
|
2013-01-27 10:43:53 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = AddLevel3(p2, lodLevel);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
p3.next.push_back(buffer);
|
2012-12-14 20:30:35 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next.back();
|
2012-12-14 20:30:35 +00:00
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
UpdateStaticBuffer(p4);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
if (globalUpdate)
|
|
|
|
|
{
|
|
|
|
|
m_updateGeometry = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2012-12-14 20:30:35 +00:00
|
|
|
|
for (int i = 0; i < static_cast<int>( p4.vertices.size() ); i++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
p1.bboxMin.x = Math::Min(p4.vertices[i].coord.x, p1.bboxMin.x);
|
|
|
|
|
p1.bboxMin.y = Math::Min(p4.vertices[i].coord.y, p1.bboxMin.y);
|
|
|
|
|
p1.bboxMin.z = Math::Min(p4.vertices[i].coord.z, p1.bboxMin.z);
|
|
|
|
|
p1.bboxMax.x = Math::Max(p4.vertices[i].coord.x, p1.bboxMax.x);
|
|
|
|
|
p1.bboxMax.y = Math::Max(p4.vertices[i].coord.y, p1.bboxMax.y);
|
|
|
|
|
p1.bboxMax.z = Math::Max(p4.vertices[i].coord.z, p1.bboxMax.z);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-14 20:30:35 +00:00
|
|
|
|
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
|
2012-12-27 13:18:16 +00:00
|
|
|
|
p1.totalTriangles += p4.vertices.size() / 3;
|
2012-12-14 20:30:35 +00:00
|
|
|
|
else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE)
|
2012-12-27 13:18:16 +00:00
|
|
|
|
p1.totalTriangles += p4.vertices.size() - 2;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-06-17 09:48:57 +00:00
|
|
|
|
void CEngine::DebugObject(int objRank)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
CLogger* l = GetLogger();
|
|
|
|
|
|
|
|
|
|
l->Debug("Debug object: %d\n", objRank);
|
|
|
|
|
if (! m_objects[objRank].used)
|
|
|
|
|
{
|
|
|
|
|
l->Debug(" not used\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
l->Debug(" baseObjRank = %d\n", m_objects[objRank].baseObjRank);
|
|
|
|
|
l->Debug(" visible = %s\n", m_objects[objRank].visible ? "true" : "false");
|
|
|
|
|
l->Debug(" drawWorld = %s\n", m_objects[objRank].drawWorld ? "true" : "false");
|
|
|
|
|
l->Debug(" drawFront = %s\n", m_objects[objRank].drawFront ? "true" : "false");
|
|
|
|
|
l->Debug(" type = %d\n", m_objects[objRank].type);
|
|
|
|
|
l->Debug(" distance = %f\n", m_objects[objRank].distance);
|
|
|
|
|
l->Debug(" shadowRank = %d\n", m_objects[objRank].shadowRank);
|
|
|
|
|
l->Debug(" transparency = %f\n", m_objects[objRank].transparency);
|
|
|
|
|
|
|
|
|
|
l->Debug(" baseObj:\n");
|
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
{
|
|
|
|
|
l->Debug(" null\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
|
|
|
|
|
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
if (!p1.used)
|
|
|
|
|
{
|
|
|
|
|
l->Debug(" not used\n");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string vecStr;
|
|
|
|
|
|
|
|
|
|
vecStr = p1.bboxMin.ToString();
|
|
|
|
|
l->Debug(" bboxMin: %s\n", vecStr.c_str());
|
|
|
|
|
vecStr = p1.bboxMax.ToString();
|
|
|
|
|
l->Debug(" bboxMax: %s\n", vecStr.c_str());
|
|
|
|
|
l->Debug(" totalTriangles: %d\n", p1.totalTriangles);
|
|
|
|
|
l->Debug(" radius: %f\n", p1.radius);
|
|
|
|
|
|
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
|
|
|
|
l->Debug(" l2:\n");
|
|
|
|
|
|
|
|
|
|
l->Debug(" tex1: %s (id: %u)\n", p2.tex1Name.c_str(), p2.tex1.id);
|
|
|
|
|
l->Debug(" tex2: %s (id: %u)\n", p2.tex2Name.c_str(), p2.tex2.id);
|
|
|
|
|
|
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
|
|
|
|
|
|
|
|
|
l->Debug(" l3:\n");
|
|
|
|
|
l->Debug(" lodLevel: %d\n", p3.lodLevel);
|
|
|
|
|
|
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
|
|
|
|
|
|
|
|
|
l->Debug(" l4:\n");
|
|
|
|
|
l->Debug(" type: %d\n", p4.type);
|
|
|
|
|
l->Debug(" state: %d\n", p4.state);
|
|
|
|
|
l->Debug(" staticBufferId: %u\n", p4.staticBufferId);
|
|
|
|
|
l->Debug(" updateStaticBuffer: %s\n", p4.updateStaticBuffer ? "true" : "false");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-12-26 19:58:02 +00:00
|
|
|
|
|
|
|
|
|
int CEngine::CreateObject()
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
int objRank = 0;
|
|
|
|
|
for ( ; objRank < static_cast<int>( m_objects.size() ); objRank++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
if (! m_objects[objRank].used)
|
2012-12-26 19:58:02 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
m_objects[objRank].LoadDefault();
|
2012-12-26 19:58:02 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
if (objRank == static_cast<int>( m_objects.size() ))
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_objects.push_back(EngineObject());
|
|
|
|
|
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
m_objects[objRank].used = true;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
|
|
|
|
|
Math::Matrix mat;
|
|
|
|
|
mat.LoadIdentity();
|
2012-12-27 13:18:16 +00:00
|
|
|
|
SetObjectTransform(objRank, mat);
|
2012-12-26 19:58:02 +00:00
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
m_objects[objRank].drawWorld = true;
|
|
|
|
|
m_objects[objRank].distance = 0.0f;
|
2013-10-13 12:44:12 +00:00
|
|
|
|
m_objects[objRank].baseObjRank = -1;
|
2012-12-27 13:18:16 +00:00
|
|
|
|
m_objects[objRank].shadowRank = -1;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
return objRank;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::DeleteAllObjects()
|
|
|
|
|
{
|
|
|
|
|
m_objects.clear();
|
|
|
|
|
m_shadows.clear();
|
|
|
|
|
|
|
|
|
|
DeleteAllGroundSpots();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::DeleteObject(int objRank)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
// Mark object as deleted
|
|
|
|
|
m_objects[objRank].used = false;
|
|
|
|
|
|
|
|
|
|
// Delete associated shadows
|
|
|
|
|
DeleteShadow(objRank);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::SetObjectBaseRank(int objRank, int baseObjRank)
|
|
|
|
|
{
|
2012-12-28 12:23:49 +00:00
|
|
|
|
assert(objRank == -1 || (objRank >= 0 && objRank < static_cast<int>( m_objects.size() )));
|
2012-12-26 19:58:02 +00:00
|
|
|
|
|
|
|
|
|
m_objects[objRank].baseObjRank = baseObjRank;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int CEngine::GetObjectBaseRank(int objRank)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
return m_objects[objRank].baseObjRank;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::SetObjectType(int objRank, EngineObjectType type)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
m_objects[objRank].type = type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EngineObjectType CEngine::GetObjectType(int objRank)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
return m_objects[objRank].type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CEngine::SetObjectTransform(int objRank, const Math::Matrix& transform)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
m_objects[objRank].transform = transform;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::GetObjectTransform(int objRank, Math::Matrix& transform)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
transform = m_objects[objRank].transform;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::SetObjectDrawWorld(int objRank, bool draw)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
m_objects[objRank].drawWorld = draw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::SetObjectDrawFront(int objRank, bool draw)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
m_objects[objRank].drawFront = draw;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::SetObjectTransparency(int objRank, float value)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
m_objects[objRank].transparency = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::GetObjectBBox(int objRank, Math::Vector& min, Math::Vector& max)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
return;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>(m_baseObjects.size()));
|
|
|
|
|
|
|
|
|
|
min = m_baseObjects[baseObjRank].bboxMin;
|
|
|
|
|
max = m_baseObjects[baseObjRank].bboxMax;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int CEngine::GetObjectTotalTriangles(int objRank)
|
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
|
|
|
|
|
|
|
|
|
return m_baseObjects[baseObjRank].totalTriangles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
EngineBaseObjDataTier* CEngine::FindTriangles(int objRank, const Material& material,
|
|
|
|
|
int state, std::string tex1Name,
|
2013-01-27 10:43:53 +00:00
|
|
|
|
std::string tex2Name, int lodLevelMask)
|
2012-12-26 19:58:02 +00:00
|
|
|
|
{
|
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
|
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (p2.tex1Name != tex1Name)
|
|
|
|
|
continue;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
if ((p3.lodLevel & lodLevelMask) == 0)
|
2012-12-26 19:58:02 +00:00
|
|
|
|
continue;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if ( (p4.state & (~(ENG_RSTATE_DUAL_BLACK|ENG_RSTATE_DUAL_WHITE))) != state ||
|
|
|
|
|
p4.material != material )
|
|
|
|
|
continue;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
return &p4;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
int CEngine::GetPartialTriangles(int objRank, int lodLevelMask, float percent, int maxCount,
|
2012-12-26 19:58:02 +00:00
|
|
|
|
std::vector<EngineTriangle>& triangles)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
return 0;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
|
|
|
|
|
int total = p1.totalTriangles;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
int expectedCount = static_cast<int>(percent * total);
|
|
|
|
|
triangles.reserve(Math::Min(maxCount, expectedCount));
|
|
|
|
|
|
|
|
|
|
int actualCount = 0;
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-27 13:18:16 +00:00
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
if ((p3.lodLevel & lodLevelMask) == 0)
|
2012-12-26 19:58:02 +00:00
|
|
|
|
continue;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int i = 0; i < static_cast<int>( p4.vertices.size() ); i += 3)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (static_cast<float>(actualCount) / total >= percent)
|
|
|
|
|
break;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (actualCount >= maxCount)
|
|
|
|
|
break;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineTriangle t;
|
|
|
|
|
t.triangle[0] = p4.vertices[i];
|
|
|
|
|
t.triangle[1] = p4.vertices[i+1];
|
|
|
|
|
t.triangle[2] = p4.vertices[i+2];
|
|
|
|
|
t.material = p4.material;
|
|
|
|
|
t.state = p4.state;
|
|
|
|
|
t.tex1Name = p2.tex1Name;
|
|
|
|
|
t.tex2Name = p2.tex2Name;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
triangles.push_back(t);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
++actualCount;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
2012-12-26 19:58:02 +00:00
|
|
|
|
}
|
|
|
|
|
else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < static_cast<int>( p4.vertices.size() ); i += 1)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (static_cast<float>(actualCount) / total >= percent)
|
|
|
|
|
break;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (actualCount >= maxCount)
|
|
|
|
|
break;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineTriangle t;
|
|
|
|
|
t.triangle[0] = p4.vertices[i];
|
|
|
|
|
t.triangle[1] = p4.vertices[i+1];
|
|
|
|
|
t.triangle[2] = p4.vertices[i+2];
|
|
|
|
|
t.material = p4.material;
|
|
|
|
|
t.state = p4.state;
|
|
|
|
|
t.tex1Name = p2.tex1Name;
|
|
|
|
|
t.tex2Name = p2.tex2Name;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
triangles.push_back(t);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
++actualCount;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return actualCount;
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::ChangeSecondTexture(int objRank, const std::string& tex2Name)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
return;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
2012-12-27 13:18:16 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
|
|
|
|
{
|
2013-06-17 09:48:57 +00:00
|
|
|
|
if (p1.next[l2].tex2Name == tex2Name)
|
2012-12-26 19:58:02 +00:00
|
|
|
|
continue; // already new
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2013-06-17 09:48:57 +00:00
|
|
|
|
std::string tex1Name = p1.next[l2].tex1Name;
|
|
|
|
|
EngineBaseObjTexTier& newP2 = AddLevel2(p1, tex1Name, tex2Name);
|
|
|
|
|
newP2.next.insert(newP2.next.end(), p1.next[l2].next.begin(), p1.next[l2].next.end());
|
|
|
|
|
p1.next[l2].next.clear();
|
|
|
|
|
|
|
|
|
|
if (!newP2.tex1.Valid())
|
2014-07-24 20:17:49 +00:00
|
|
|
|
newP2.tex1 = LoadTexture("textures/"+newP2.tex1Name);
|
2013-06-17 09:48:57 +00:00
|
|
|
|
|
|
|
|
|
if (!newP2.tex2.Valid())
|
2014-07-24 20:17:49 +00:00
|
|
|
|
newP2.tex2 = LoadTexture("textures/"+newP2.tex2Name);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::ChangeTextureMapping(int objRank, const Material& mat, int state,
|
|
|
|
|
const std::string& tex1Name, const std::string& tex2Name,
|
2013-01-27 10:43:53 +00:00
|
|
|
|
int lodLevelMask, EngineTextureMapping mode,
|
2012-12-26 19:58:02 +00:00
|
|
|
|
float au, float bu, float av, float bv)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, lodLevelMask);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
if (p4 == nullptr)
|
2012-12-26 19:58:02 +00:00
|
|
|
|
return;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
int nb = p4->vertices.size();
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
if (mode == ENG_TEX_MAPPING_X)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < nb; i++)
|
|
|
|
|
{
|
|
|
|
|
p4->vertices[i].texCoord.x = p4->vertices[i].coord.z * au + bu;
|
|
|
|
|
p4->vertices[i].texCoord.y = p4->vertices[i].coord.y * av + bv;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (mode == ENG_TEX_MAPPING_Y)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < nb; i++)
|
|
|
|
|
{
|
|
|
|
|
p4->vertices[i].texCoord.x = p4->vertices[i].coord.x * au + bu;
|
|
|
|
|
p4->vertices[i].texCoord.y = p4->vertices[i].coord.z * av + bv;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (mode == ENG_TEX_MAPPING_Z)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < nb; i++)
|
|
|
|
|
{
|
|
|
|
|
p4->vertices[i].texCoord.x = p4->vertices[i].coord.x * au + bu;
|
|
|
|
|
p4->vertices[i].texCoord.y = p4->vertices[i].coord.y * av + bv;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (mode == ENG_TEX_MAPPING_1X)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < nb; i++)
|
|
|
|
|
{
|
|
|
|
|
p4->vertices[i].texCoord.x = p4->vertices[i].coord.x * au + bu;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (mode == ENG_TEX_MAPPING_1Y)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < nb; i++)
|
|
|
|
|
{
|
|
|
|
|
p4->vertices[i].texCoord.y = p4->vertices[i].coord.y * au + bu;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (mode == ENG_TEX_MAPPING_1Z)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < nb; i++)
|
|
|
|
|
{
|
|
|
|
|
p4->vertices[i].texCoord.x = p4->vertices[i].coord.z * au + bu;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
UpdateStaticBuffer(*p4);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::TrackTextureMapping(int objRank, const Material& mat, int state,
|
2012-10-19 20:37:11 +00:00
|
|
|
|
const std::string& tex1Name, const std::string& tex2Name,
|
2013-01-27 10:43:53 +00:00
|
|
|
|
int lodLevelMask, EngineTextureMapping mode,
|
2012-10-19 20:37:11 +00:00
|
|
|
|
float pos, float factor, float tl, float ts, float tt)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-12-27 13:18:16 +00:00
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
EngineBaseObjDataTier* p4 = FindTriangles(objRank, mat, state, tex1Name, tex2Name, lodLevelMask);
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (p4 == nullptr)
|
|
|
|
|
return;
|
2012-10-19 20:37:11 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int tNum = p4->vertices.size();
|
|
|
|
|
if (tNum < 12 || tNum % 6 != 0)
|
|
|
|
|
return;
|
2012-10-19 20:37:11 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
std::vector<Gfx::VertexTex2>& vs = p4->vertices;
|
2012-10-19 20:37:11 +00:00
|
|
|
|
|
|
|
|
|
while (pos < 0.0f)
|
2012-10-19 20:43:18 +00:00
|
|
|
|
pos += 1.0f; // never negative!
|
2012-10-19 20:37:11 +00:00
|
|
|
|
|
|
|
|
|
Math::Vector current;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < 6; j++)
|
|
|
|
|
{
|
|
|
|
|
if (Math::IsEqual(vs[i].coord.x, vs[j+6].coord.x) &&
|
|
|
|
|
Math::IsEqual(vs[i].coord.y, vs[j+6].coord.y))
|
|
|
|
|
{
|
|
|
|
|
current.x = vs[i].coord.x; // position end link
|
|
|
|
|
current.y = vs[i].coord.y;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float ps = 0.0f; // start position on the periphery
|
|
|
|
|
float pe = 0.0f;
|
|
|
|
|
int is[6] = { 0 }, ie[6] = { 0 };
|
|
|
|
|
|
|
|
|
|
int tBase = 0;
|
|
|
|
|
for (int ti = 0; ti < tNum / 6; ti++)
|
|
|
|
|
{
|
|
|
|
|
int s = 0;
|
|
|
|
|
int e = 0;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
|
{
|
|
|
|
|
if (Math::IsEqual(vs[tBase + i].coord.x, current.x, 0.0001f) &&
|
|
|
|
|
Math::IsEqual(vs[tBase + i].coord.y, current.y, 0.0001f))
|
|
|
|
|
{
|
|
|
|
|
ie[e++] = i;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
is[s++] = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (s == 3 && e == 3)
|
|
|
|
|
{
|
|
|
|
|
pe = ps + Math::Point(vs[tBase + is[0]].coord.x - vs[tBase + ie[0]].coord.x,
|
|
|
|
|
vs[tBase + is[0]].coord.y - vs[tBase + ie[0]].coord.y).Length() / factor; // end position on the periphery
|
|
|
|
|
|
|
|
|
|
float pps = ps + pos;
|
|
|
|
|
float ppe = pe + pos;
|
2012-10-19 20:43:18 +00:00
|
|
|
|
int offset = static_cast<int>(pps);
|
2012-10-19 20:37:11 +00:00
|
|
|
|
ppe -= offset;
|
2012-10-19 20:43:18 +00:00
|
|
|
|
pps -= offset;
|
2012-10-19 20:37:11 +00:00
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
|
{
|
2012-10-19 20:43:18 +00:00
|
|
|
|
vs[tBase + is[i]].texCoord.x = ((pps * tl) + ts) / tt;
|
|
|
|
|
vs[tBase + ie[i]].texCoord.x = ((ppe * tl) + ts) / tt;
|
2012-10-19 20:37:11 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ti >= (tNum / 6) - 1)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 6; i++)
|
|
|
|
|
{
|
|
|
|
|
if (!Math::IsEqual(vs[tBase + i+6].coord.x, current.x, 0.0001f) ||
|
|
|
|
|
!Math::IsEqual(vs[tBase + i+6].coord.y, current.y, 0.0001f))
|
|
|
|
|
{
|
|
|
|
|
current.x = vs[tBase + i+6].coord.x; // end next link
|
|
|
|
|
current.y = vs[tBase + i+6].coord.y;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ps = pe; // following start position on the periphery
|
|
|
|
|
tBase += 6;
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
UpdateStaticBuffer(*p4);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::CreateShadow(int objRank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
// Already allocated?
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (m_objects[objRank].shadowRank != -1)
|
|
|
|
|
return;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
int index = 0;
|
|
|
|
|
for ( ; index < static_cast<int>( m_shadows.size() ); index++)
|
|
|
|
|
{
|
|
|
|
|
if (! m_shadows[index].used)
|
|
|
|
|
{
|
|
|
|
|
m_shadows[index].LoadDefault();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (index == static_cast<int>( m_shadows.size() ))
|
|
|
|
|
m_shadows.push_back(EngineShadow());
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
m_shadows[index].used = true;
|
|
|
|
|
m_shadows[index].objRank = objRank;
|
|
|
|
|
m_shadows[index].height = 0.0f;
|
|
|
|
|
|
|
|
|
|
m_objects[objRank].shadowRank = index;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DeleteShadow(int objRank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int shadowRank = m_objects[objRank].shadowRank;
|
|
|
|
|
if (shadowRank == -1)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(shadowRank >= 0 && shadowRank < static_cast<int>( m_shadows.size() ));
|
|
|
|
|
|
|
|
|
|
m_shadows[shadowRank].used = false;
|
|
|
|
|
m_shadows[shadowRank].objRank = -1;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
m_objects[objRank].shadowRank = -1;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectShadowHide(int objRank, bool hide)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int shadowRank = m_objects[objRank].shadowRank;
|
|
|
|
|
if (shadowRank == -1)
|
|
|
|
|
return;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(shadowRank >= 0 && shadowRank < static_cast<int>( m_shadows.size() ));
|
|
|
|
|
|
|
|
|
|
m_shadows[shadowRank].hide = hide;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectShadowType(int objRank, EngineShadowType type)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int shadowRank = m_objects[objRank].shadowRank;
|
|
|
|
|
if (shadowRank == -1)
|
|
|
|
|
return;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(shadowRank >= 0 && shadowRank < static_cast<int>( m_shadows.size() ));
|
|
|
|
|
|
|
|
|
|
m_shadows[shadowRank].type = type;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectShadowPos(int objRank, const Math::Vector& pos)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int shadowRank = m_objects[objRank].shadowRank;
|
|
|
|
|
if (shadowRank == -1)
|
|
|
|
|
return;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(shadowRank >= 0 && shadowRank < static_cast<int>( m_shadows.size() ));
|
|
|
|
|
|
|
|
|
|
m_shadows[shadowRank].pos = pos;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectShadowNormal(int objRank, const Math::Vector& normal)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int shadowRank = m_objects[objRank].shadowRank;
|
|
|
|
|
if (shadowRank == -1)
|
|
|
|
|
return;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(shadowRank >= 0 && shadowRank < static_cast<int>( m_shadows.size() ));
|
|
|
|
|
|
|
|
|
|
m_shadows[shadowRank].normal = normal;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectShadowAngle(int objRank, float angle)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int shadowRank = m_objects[objRank].shadowRank;
|
|
|
|
|
if (shadowRank == -1)
|
|
|
|
|
return;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(shadowRank >= 0 && shadowRank < static_cast<int>( m_shadows.size() ));
|
|
|
|
|
|
|
|
|
|
m_shadows[shadowRank].angle = angle;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectShadowRadius(int objRank, float radius)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int shadowRank = m_objects[objRank].shadowRank;
|
|
|
|
|
if (shadowRank == -1)
|
|
|
|
|
return;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(shadowRank >= 0 && shadowRank < static_cast<int>( m_shadows.size() ));
|
|
|
|
|
|
|
|
|
|
m_shadows[shadowRank].radius = radius;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectShadowIntensity(int objRank, float intensity)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int shadowRank = m_objects[objRank].shadowRank;
|
|
|
|
|
if (shadowRank == -1)
|
|
|
|
|
return;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(shadowRank >= 0 && shadowRank < static_cast<int>( m_shadows.size() ));
|
|
|
|
|
|
|
|
|
|
m_shadows[shadowRank].intensity = intensity;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectShadowHeight(int objRank, float height)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int shadowRank = m_objects[objRank].shadowRank;
|
|
|
|
|
if (shadowRank == -1)
|
|
|
|
|
return;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(shadowRank >= 0 && shadowRank < static_cast<int>( m_shadows.size() ));
|
|
|
|
|
|
|
|
|
|
m_shadows[shadowRank].height = height;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::GetObjectShadowRadius(int objRank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int shadowRank = m_objects[objRank].shadowRank;
|
|
|
|
|
if (shadowRank == -1)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
return 0.0f;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(shadowRank >= 0 && shadowRank < static_cast<int>( m_shadows.size() ));
|
|
|
|
|
|
|
|
|
|
return m_shadows[shadowRank].radius;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetHighlight(Math::Point &p1, Math::Point &p2)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
p1 = m_highlightP1;
|
|
|
|
|
p2 = m_highlightP2;
|
|
|
|
|
return m_highlight;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetHighlightRank(int *rankList)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
while ( *rankList != -1 )
|
|
|
|
|
{
|
|
|
|
|
m_highlightRank[i++] = *rankList++;
|
|
|
|
|
}
|
|
|
|
|
m_highlightRank[i] = -1; // terminator
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetBBox2D(int objRank, Math::Point &min, Math::Point &max)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>( m_objects.size() ));
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
min.x = 1000000.0f;
|
|
|
|
|
min.y = 1000000.0f;
|
|
|
|
|
max.x = -1000000.0f;
|
|
|
|
|
max.y = -1000000.0f;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
return false;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
|
|
|
{
|
|
|
|
|
Math::Vector p;
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
if ( i & (1<<0) ) p.x = p1.bboxMin.x;
|
|
|
|
|
else p.x = p1.bboxMax.x;
|
|
|
|
|
if ( i & (1<<1) ) p.y = p1.bboxMin.y;
|
|
|
|
|
else p.y = p1.bboxMax.y;
|
|
|
|
|
if ( i & (1<<2) ) p.z = p1.bboxMin.z;
|
|
|
|
|
else p.z = p1.bboxMax.z;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (min.x == 1000000.0f ||
|
|
|
|
|
min.y == 1000000.0f ||
|
|
|
|
|
max.x == -1000000.0f ||
|
|
|
|
|
max.y == -1000000.0f)
|
|
|
|
|
return false;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::DeleteAllGroundSpots()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 17:28:22 +00:00
|
|
|
|
m_groundSpots.clear();
|
|
|
|
|
m_firstGroundSpot = true;
|
|
|
|
|
|
2012-10-20 21:06:56 +00:00
|
|
|
|
for (int s = 0; s < 16; s++)
|
|
|
|
|
{
|
|
|
|
|
CImage shadowImg(Math::IntPoint(256, 256));
|
|
|
|
|
shadowImg.Fill(Gfx::IntColor(255, 255, 255, 255));
|
|
|
|
|
|
|
|
|
|
std::stringstream str;
|
|
|
|
|
str << "shadow" << std::setfill('0') << std::setw(2) << s << ".png";
|
|
|
|
|
std::string texName = str.str();
|
|
|
|
|
|
|
|
|
|
DeleteTexture(texName);
|
|
|
|
|
|
|
|
|
|
Gfx::Texture tex = m_device->CreateTexture(&shadowImg, m_defaultTexParams);
|
|
|
|
|
|
|
|
|
|
m_texNameMap[texName] = tex;
|
|
|
|
|
m_revTexNameMap[tex] = texName;
|
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
int CEngine::CreateGroundSpot()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 17:28:22 +00:00
|
|
|
|
int index = 0;
|
|
|
|
|
for ( ; index < static_cast<int>( m_groundSpots.size() ); index++)
|
|
|
|
|
{
|
|
|
|
|
if (! m_groundSpots[index].used)
|
|
|
|
|
{
|
|
|
|
|
m_groundSpots[index].LoadDefault();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_groundSpots.push_back(EngineGroundSpot());
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
m_groundSpots[index].used = true;
|
|
|
|
|
m_groundSpots[index].smooth = 1.0f;
|
|
|
|
|
|
|
|
|
|
return index;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DeleteGroundSpot(int rank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(rank >= 0 && rank < static_cast<int>( m_groundSpots.size() ));
|
|
|
|
|
|
2012-08-12 17:28:22 +00:00
|
|
|
|
m_groundSpots[rank].used = false;
|
|
|
|
|
m_groundSpots[rank].pos = Math::Vector(0.0f, 0.0f, 0.0f);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectGroundSpotPos(int rank, const Math::Vector& pos)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(rank >= 0 && rank < static_cast<int>( m_groundSpots.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
m_groundSpots[rank].pos = pos;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectGroundSpotRadius(int rank, float radius)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(rank >= 0 && rank < static_cast<int>( m_groundSpots.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
m_groundSpots[rank].radius = radius;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectGroundSpotColor(int rank, const Color& color)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(rank >= 0 && rank < static_cast<int>( m_groundSpots.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
m_groundSpots[rank].color = color;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectGroundSpotMinMax(int rank, float min, float max)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(rank >= 0 && rank < static_cast<int>( m_groundSpots.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
m_groundSpots[rank].min = min;
|
|
|
|
|
m_groundSpots[rank].max = max;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::SetObjectGroundSpotSmooth(int rank, float smooth)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(rank >= 0 && rank < static_cast<int>( m_groundSpots.size() ));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
m_groundSpots[rank].smooth = smooth;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::CreateGroundMark(Math::Vector pos, float radius,
|
2012-08-10 21:31:42 +00:00
|
|
|
|
float delay1, float delay2, float delay3,
|
|
|
|
|
int dx, int dy, char* table)
|
|
|
|
|
{
|
2012-08-12 17:28:22 +00:00
|
|
|
|
m_groundMark.LoadDefault();
|
|
|
|
|
|
2012-10-20 14:34:22 +00:00
|
|
|
|
m_groundMark.draw = true;
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_groundMark.phase = ENG_GR_MARK_PHASE_INC;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
m_groundMark.delay[0] = delay1;
|
|
|
|
|
m_groundMark.delay[1] = delay2;
|
|
|
|
|
m_groundMark.delay[2] = delay3;
|
|
|
|
|
m_groundMark.pos = pos;
|
|
|
|
|
m_groundMark.radius = radius;
|
|
|
|
|
m_groundMark.intensity = 0.0f;
|
|
|
|
|
m_groundMark.dx = dx;
|
|
|
|
|
m_groundMark.dy = dy;
|
|
|
|
|
m_groundMark.table = table;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DeleteGroundMark(int rank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 17:28:22 +00:00
|
|
|
|
m_groundMark.LoadDefault();
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::ComputeDistance()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 17:28:22 +00:00
|
|
|
|
for (int i = 0; i < static_cast<int>( m_objects.size() ); i++)
|
|
|
|
|
{
|
|
|
|
|
if (! m_objects[i].used)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Math::Vector v;
|
|
|
|
|
v.x = m_eyePt.x - m_objects[i].transform.Get(1, 4);
|
|
|
|
|
v.y = m_eyePt.y - m_objects[i].transform.Get(2, 4);
|
|
|
|
|
v.z = m_eyePt.z - m_objects[i].transform.Get(3, 4);
|
|
|
|
|
m_objects[i].distance = v.Length();
|
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::UpdateGeometry()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 17:28:22 +00:00
|
|
|
|
if (! m_updateGeometry)
|
|
|
|
|
return;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int baseObjRank = 0; baseObjRank < static_cast<int>( m_baseObjects.size() ); baseObjRank++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObject &p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
if (! p1.used)
|
|
|
|
|
continue;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
p1.bboxMin.LoadZero();
|
|
|
|
|
p1.bboxMax.LoadZero();
|
|
|
|
|
p1.radius = 0;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
for (int i = 0; i < static_cast<int>( p4.vertices.size() ); i++)
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
p1.bboxMin.x = Math::Min(p4.vertices[i].coord.x, p1.bboxMin.x);
|
|
|
|
|
p1.bboxMin.y = Math::Min(p4.vertices[i].coord.y, p1.bboxMin.y);
|
|
|
|
|
p1.bboxMin.z = Math::Min(p4.vertices[i].coord.z, p1.bboxMin.z);
|
|
|
|
|
p1.bboxMax.x = Math::Max(p4.vertices[i].coord.x, p1.bboxMax.x);
|
|
|
|
|
p1.bboxMax.y = Math::Max(p4.vertices[i].coord.y, p1.bboxMax.y);
|
|
|
|
|
p1.bboxMax.z = Math::Max(p4.vertices[i].coord.z, p1.bboxMax.z);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_updateGeometry = false;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::UpdateStaticBuffer(EngineBaseObjDataTier& p4)
|
|
|
|
|
{
|
|
|
|
|
PrimitiveType type;
|
|
|
|
|
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
|
|
|
|
|
type = PRIMITIVE_TRIANGLES;
|
|
|
|
|
else
|
|
|
|
|
type = PRIMITIVE_TRIANGLE_STRIP;
|
|
|
|
|
|
|
|
|
|
if (p4.staticBufferId == 0)
|
|
|
|
|
p4.staticBufferId = m_device->CreateStaticBuffer(type, &p4.vertices[0], p4.vertices.size());
|
|
|
|
|
else
|
|
|
|
|
m_device->UpdateStaticBuffer(p4.staticBufferId, type, &p4.vertices[0], p4.vertices.size());
|
|
|
|
|
|
|
|
|
|
p4.updateStaticBuffer = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::UpdateStaticBuffers()
|
2012-12-14 20:30:35 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (!m_updateStaticBuffers)
|
2012-12-14 20:30:35 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_updateStaticBuffers = false;
|
|
|
|
|
|
|
|
|
|
for (int baseObjRank = 0; baseObjRank < static_cast<int>( m_baseObjects.size() ); baseObjRank++)
|
2012-12-14 20:30:35 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
if (! p1.used)
|
|
|
|
|
continue;
|
2012-12-14 20:30:35 +00:00
|
|
|
|
|
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
2012-12-14 20:30:35 +00:00
|
|
|
|
|
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
2012-12-14 20:30:35 +00:00
|
|
|
|
|
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
2012-12-14 20:30:35 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! p4.updateStaticBuffer)
|
|
|
|
|
continue;
|
2012-12-14 20:30:35 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
UpdateStaticBuffer(p4);
|
2012-12-14 20:30:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::Update()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
ComputeDistance();
|
|
|
|
|
UpdateGeometry();
|
2012-12-26 19:58:02 +00:00
|
|
|
|
UpdateStaticBuffers();
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::DetectBBox(int objRank, Math::Point mouse)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>(m_objects.size()));
|
|
|
|
|
|
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
return false;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>(m_baseObjects.size()));
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
|
2012-08-12 17:28:22 +00:00
|
|
|
|
Math::Point min, 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;
|
|
|
|
|
|
2012-12-27 13:18:16 +00:00
|
|
|
|
if ( i & (1<<0) ) p.x = p1.bboxMin.x;
|
|
|
|
|
else p.x = p1.bboxMax.x;
|
|
|
|
|
if ( i & (1<<1) ) p.y = p1.bboxMin.y;
|
|
|
|
|
else p.y = p1.bboxMax.y;
|
|
|
|
|
if ( i & (1<<2) ) p.z = p1.bboxMin.z;
|
|
|
|
|
else p.z = p1.bboxMax.z;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ( mouse.x >= min.x &&
|
|
|
|
|
mouse.x <= max.x &&
|
|
|
|
|
mouse.y >= min.y &&
|
|
|
|
|
mouse.y <= max.y );
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
int CEngine::DetectObject(Math::Point mouse)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 17:28:22 +00:00
|
|
|
|
float min = 1000000.0f;
|
|
|
|
|
int nearest = -1;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int objRank = 0; objRank < static_cast<int>( m_objects.size() ); objRank++)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! m_objects[objRank].used)
|
|
|
|
|
continue;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (! DetectBBox(objRank, mouse))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
continue;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>(m_baseObjects.size()));
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
if (! p1.used)
|
|
|
|
|
continue;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
if (p3.lodLevel != LOD_Constant && p3.lodLevel != LOD_High)
|
|
|
|
|
continue;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < static_cast<int>( p4.vertices.size() ); i += 3)
|
|
|
|
|
{
|
|
|
|
|
float dist = 0.0f;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (DetectTriangle(mouse, &p4.vertices[i], objRank, dist) && dist < min)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
min = dist;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
nearest = objRank;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (p4.type == ENG_TRIANGLE_TYPE_SURFACE)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < static_cast<int>( p4.vertices.size() ) - 2; i += 1)
|
|
|
|
|
{
|
|
|
|
|
float dist = 0.0f;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (DetectTriangle(mouse, &p4.vertices[i], objRank, dist) && dist < min)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
min = dist;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
nearest = objRank;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nearest;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::DetectTriangle(Math::Point mouse, VertexTex2* triangle, int objRank, float& dist)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>(m_objects.size()));
|
|
|
|
|
|
2012-08-12 17:28:22 +00:00
|
|
|
|
Math::Vector p2D[3], p3D;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
|
|
|
{
|
|
|
|
|
p3D.x = triangle[i].coord.x;
|
|
|
|
|
p3D.y = triangle[i].coord.y;
|
|
|
|
|
p3D.z = triangle[i].coord.z;
|
|
|
|
|
|
|
|
|
|
if (! TransformPoint(p2D[i], objRank, p3D))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (mouse.x < p2D[0].x &&
|
|
|
|
|
mouse.x < p2D[1].x &&
|
|
|
|
|
mouse.x < p2D[2].x)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (mouse.x > p2D[0].x &&
|
|
|
|
|
mouse.x > p2D[1].x &&
|
|
|
|
|
mouse.x > p2D[2].x)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (mouse.y < p2D[0].y &&
|
|
|
|
|
mouse.y < p2D[1].y &&
|
|
|
|
|
mouse.y < p2D[2].y)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (mouse.y > p2D[0].y &&
|
|
|
|
|
mouse.y > p2D[1].y &&
|
|
|
|
|
mouse.y > p2D[2].y)
|
|
|
|
|
return false;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
Math::Point a, b, c;
|
|
|
|
|
a.x = p2D[0].x;
|
|
|
|
|
a.y = p2D[0].y;
|
|
|
|
|
b.x = p2D[1].x;
|
|
|
|
|
b.y = p2D[1].y;
|
|
|
|
|
c.x = p2D[2].x;
|
|
|
|
|
c.y = p2D[2].y;
|
|
|
|
|
|
|
|
|
|
if (! Math::IsInsideTriangle(a, b, c, mouse))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
dist = (p2D[0].z + p2D[1].z + p2D[2].z) / 3.0f;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-20 21:06:56 +00:00
|
|
|
|
//! Use only after world transform already set
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::IsVisible(int objRank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>(m_objects.size()));
|
|
|
|
|
|
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
return false;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>(m_baseObjects.size()));
|
|
|
|
|
|
|
|
|
|
float radius = m_baseObjects[baseObjRank].radius;
|
2012-10-20 21:06:56 +00:00
|
|
|
|
Math::Vector center(0.0f, 0.0f, 0.0f);
|
|
|
|
|
if (m_device->ComputeSphereVisibility(center, radius) == Gfx::FRUSTUM_PLANE_ALL)
|
|
|
|
|
{
|
|
|
|
|
m_objects[objRank].visible = true;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_objects[objRank].visible = false;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
return false;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
bool CEngine::IsWithinLODLimit(float distance, LODLevel lodLevel)
|
|
|
|
|
{
|
|
|
|
|
float min = 0.0f, max = 0.0f;
|
|
|
|
|
|
|
|
|
|
if (lodLevel == LOD_Constant)
|
|
|
|
|
{
|
|
|
|
|
min = 0.0f;
|
|
|
|
|
max = m_terrainVision * m_clippingDistance;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (lodLevel == LOD_High)
|
|
|
|
|
{
|
|
|
|
|
min = 0.0f;
|
|
|
|
|
max = 100.0f;
|
|
|
|
|
}
|
|
|
|
|
else if (lodLevel == LOD_Medium)
|
|
|
|
|
{
|
|
|
|
|
min = 100.0f;
|
|
|
|
|
max = 200.0f;
|
|
|
|
|
}
|
|
|
|
|
else if (lodLevel == LOD_Low)
|
|
|
|
|
{
|
|
|
|
|
min = 100.0f;
|
|
|
|
|
max = 1000000.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
min *= m_size.x / 640.0f;
|
2014-08-06 15:18:52 +00:00
|
|
|
|
min *= 1.0f+m_objectDetail*2.0f;
|
2013-01-27 10:43:53 +00:00
|
|
|
|
|
|
|
|
|
max *= m_size.x / 640.0f;
|
2014-08-06 15:18:52 +00:00
|
|
|
|
max *= 1.0f+m_objectDetail*2.0f;
|
2013-01-27 10:43:53 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return distance >= min && distance < max;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::TransformPoint(Math::Vector& p2D, int objRank, Math::Vector p3D)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(objRank >= 0 && objRank < static_cast<int>(m_objects.size()));
|
|
|
|
|
|
2012-08-11 15:17:04 +00:00
|
|
|
|
p3D = Math::Transform(m_objects[objRank].transform, p3D);
|
|
|
|
|
p3D = Math::Transform(m_matView, p3D);
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (p3D.z < 2.0f)
|
|
|
|
|
return false; // behind?
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************************************
|
|
|
|
|
Mode setting
|
|
|
|
|
*******************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetState(int state, const Color& color)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-11 15:17:04 +00:00
|
|
|
|
if (state == m_lastState && color == m_lastColor)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_lastState = state;
|
|
|
|
|
m_lastColor = color;
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
if (state & ENG_RSTATE_TTEXTURE_BLACK) // transparent black texture?
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, false);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_BLENDING, true);
|
|
|
|
|
m_device->SetBlendFunc(BLEND_ONE, BLEND_INV_SRC_COLOR);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
TextureStageParams params;
|
|
|
|
|
params.colorOperation = TEX_MIX_OPER_MODULATE;
|
|
|
|
|
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
|
|
|
|
|
params.colorArg2 = TEX_MIX_ARG_FACTOR;
|
2012-10-20 21:06:56 +00:00
|
|
|
|
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
|
2012-09-29 20:44:05 +00:00
|
|
|
|
params.factor = color;
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
|
|
|
|
m_device->SetTextureEnabled(0, true);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_device->SetTextureStageParams(0, params);
|
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (state & ENG_RSTATE_TTEXTURE_WHITE) // transparent white texture?
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, false);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_BLENDING, true);
|
|
|
|
|
m_device->SetBlendFunc(BLEND_DST_COLOR, BLEND_ZERO);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
TextureStageParams params;
|
|
|
|
|
params.colorOperation = TEX_MIX_OPER_ADD;
|
|
|
|
|
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
|
|
|
|
|
params.colorArg2 = TEX_MIX_ARG_FACTOR;
|
2012-10-20 21:06:56 +00:00
|
|
|
|
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
|
2012-09-29 20:44:05 +00:00
|
|
|
|
params.factor = color.Inverse();
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
|
|
|
|
m_device->SetTextureEnabled(0, true);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_device->SetTextureStageParams(0, params);
|
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (state & ENG_RSTATE_TCOLOR_BLACK) // transparent black color?
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, false);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_BLENDING, true);
|
|
|
|
|
m_device->SetBlendFunc(BLEND_ONE, BLEND_INV_SRC_COLOR);
|
2012-09-29 17:35:14 +00:00
|
|
|
|
|
|
|
|
|
m_device->SetTextureEnabled(0, false);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (state & ENG_RSTATE_TCOLOR_WHITE) // transparent white color?
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, false);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_BLENDING, true);
|
|
|
|
|
m_device->SetBlendFunc(BLEND_DST_COLOR, BLEND_ZERO);
|
2012-09-29 17:35:14 +00:00
|
|
|
|
|
|
|
|
|
m_device->SetTextureEnabled(0, false);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (state & ENG_RSTATE_TDIFFUSE) // diffuse color as transparent?
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, false);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_BLENDING, true);
|
|
|
|
|
m_device->SetBlendFunc(BLEND_SRC_ALPHA, BLEND_DST_ALPHA);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
TextureStageParams params;
|
|
|
|
|
params.colorOperation = TEX_MIX_OPER_REPLACE;
|
|
|
|
|
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
|
2012-10-20 21:06:56 +00:00
|
|
|
|
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
m_device->SetTextureEnabled(0, true);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
m_device->SetTextureStageParams(0, params);
|
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (state & ENG_RSTATE_OPAQUE_TEXTURE) // opaque texture ?
|
2012-08-12 08:45:04 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_BLENDING, false);
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
|
|
|
|
m_device->SetTextureEnabled(0, true);
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTextureStageParams(0, TextureStageParams()); // default operation
|
2012-08-12 08:45:04 +00:00
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (state & ENG_RSTATE_OPAQUE_COLOR) // opaque color ?
|
2012-08-12 08:45:04 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_BLENDING, false);
|
2012-09-29 17:35:14 +00:00
|
|
|
|
|
|
|
|
|
m_device->SetTextureEnabled(0, false);
|
2012-08-12 08:45:04 +00:00
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (state & ENG_RSTATE_TEXT) // font rendering?
|
2012-08-11 15:17:04 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, false);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_BLENDING, true);
|
|
|
|
|
m_device->SetBlendFunc(BLEND_SRC_ALPHA, BLEND_INV_SRC_ALPHA);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
|
|
|
|
m_device->SetTextureEnabled(0, true);
|
2012-09-27 21:18:12 +00:00
|
|
|
|
m_device->SetTextureStageParams(0, TextureStageParams()); // default operation
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else if (state & ENG_RSTATE_ALPHA) // image with alpha channel?
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_BLENDING, false);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, true);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, true);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, true);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetAlphaTestFunc(COMP_FUNC_GREATER, 0.5f);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
TextureStageParams params;
|
|
|
|
|
params.colorOperation = TEX_MIX_OPER_MODULATE;
|
|
|
|
|
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
|
|
|
|
|
params.colorArg2 = TEX_MIX_ARG_SRC_COLOR;
|
|
|
|
|
params.alphaOperation = TEX_MIX_OPER_REPLACE;
|
|
|
|
|
params.alphaArg1 = TEX_MIX_ARG_TEXTURE;
|
2012-09-29 20:44:05 +00:00
|
|
|
|
params.factor = color;
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_device->SetTextureEnabled(0, true);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
m_device->SetTextureStageParams(0, params);
|
|
|
|
|
}
|
|
|
|
|
else // normal ?
|
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_BLENDING, false);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, true);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, true);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
TextureStageParams params;
|
|
|
|
|
params.colorOperation = TEX_MIX_OPER_DEFAULT; // default modulate
|
2012-10-20 21:06:56 +00:00
|
|
|
|
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-08-11 15:17:04 +00:00
|
|
|
|
m_device->SetTextureEnabled(0, true);
|
|
|
|
|
m_device->SetTextureStageParams(0, params);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
if (state & ENG_RSTATE_FOG)
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, true);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool second = m_groundSpotVisible || m_dirty;
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
if ( !m_groundSpotVisible && (state & ENG_RSTATE_SECOND) != 0 ) second = false;
|
|
|
|
|
if ( !m_dirty && (state & ENG_RSTATE_SECOND) == 0 ) second = false;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-08-11 15:17:04 +00:00
|
|
|
|
if ((state & ENG_RSTATE_DUAL_BLACK) && second)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
TextureStageParams params;
|
|
|
|
|
params.colorOperation = TEX_MIX_OPER_MODULATE;
|
|
|
|
|
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
|
|
|
|
|
params.colorArg2 = TEX_MIX_ARG_COMPUTED_COLOR;
|
2012-10-20 21:06:56 +00:00
|
|
|
|
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
|
2012-09-29 08:40:11 +00:00
|
|
|
|
m_device->SetTextureEnabled(1, true);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
m_device->SetTextureStageParams(1, params);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
2012-08-11 15:17:04 +00:00
|
|
|
|
else if ((state & ENG_RSTATE_DUAL_WHITE) && second)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
TextureStageParams params;
|
|
|
|
|
params.colorOperation = TEX_MIX_OPER_ADD;
|
|
|
|
|
params.colorArg1 = TEX_MIX_ARG_TEXTURE;
|
|
|
|
|
params.colorArg2 = TEX_MIX_ARG_COMPUTED_COLOR;
|
2012-10-20 21:06:56 +00:00
|
|
|
|
params.alphaOperation = TEX_MIX_OPER_DEFAULT;
|
2012-09-29 08:40:11 +00:00
|
|
|
|
m_device->SetTextureEnabled(1, true);
|
2012-08-11 15:17:04 +00:00
|
|
|
|
m_device->SetTextureStageParams(1, params);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_device->SetTextureEnabled(1, false);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
if (state & ENG_RSTATE_WRAP)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-29 08:40:11 +00:00
|
|
|
|
m_device->SetTextureStageWrap(0, TEX_WRAP_REPEAT, TEX_WRAP_REPEAT);
|
|
|
|
|
m_device->SetTextureStageWrap(1, TEX_WRAP_REPEAT, TEX_WRAP_REPEAT);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
else // if (state & ENG_RSTATE_CLAMP) or otherwise
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-29 08:40:11 +00:00
|
|
|
|
m_device->SetTextureStageWrap(0, TEX_WRAP_CLAMP, TEX_WRAP_CLAMP);
|
|
|
|
|
m_device->SetTextureStageWrap(1, TEX_WRAP_CLAMP, TEX_WRAP_CLAMP);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
if (state & ENG_RSTATE_2FACE)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_CULLING, false);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_CULLING, true);
|
|
|
|
|
m_device->SetCullMode(CULL_CCW);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
if (state & ENG_RSTATE_LIGHT)
|
|
|
|
|
m_device->SetGlobalAmbient(Color(1.0f, 1.0f, 1.0f, 1.0f));
|
2012-08-10 21:31:42 +00:00
|
|
|
|
else
|
|
|
|
|
m_device->SetGlobalAmbient(m_ambientColor[m_rankView]);
|
2012-09-27 21:18:12 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// In interface mode, disable lighting
|
|
|
|
|
if (m_interfaceMode)
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetMaterial(const Material& mat)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 08:45:04 +00:00
|
|
|
|
m_lastMaterial = mat;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_device->SetMaterial(mat);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetViewParams(const Math::Vector& eyePt, const Math::Vector& lookatPt,
|
2012-08-10 21:31:42 +00:00
|
|
|
|
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)
|
2013-02-16 21:37:43 +00:00
|
|
|
|
m_sound = m_app->GetSound();
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-09 10:56:09 +00:00
|
|
|
|
if (m_sound != nullptr)
|
|
|
|
|
m_sound->SetListener(eyePt, lookatPt);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-05-26 12:50:23 +00:00
|
|
|
|
Texture CEngine::CreateTexture(const std::string& texName, const TextureCreateParams& params, CImage* image)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-22 15:36:10 +00:00
|
|
|
|
if (texName.empty())
|
|
|
|
|
return Texture(); // invalid texture
|
|
|
|
|
|
2012-08-12 08:45:04 +00:00
|
|
|
|
if (m_texBlacklist.find(texName) != m_texBlacklist.end())
|
2012-09-19 21:50:28 +00:00
|
|
|
|
return Texture(); // invalid texture
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
2012-09-29 22:23:26 +00:00
|
|
|
|
Texture tex;
|
2013-05-26 12:50:23 +00:00
|
|
|
|
CImage img;
|
2012-09-29 22:23:26 +00:00
|
|
|
|
|
|
|
|
|
if (image == nullptr)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2014-07-24 20:17:49 +00:00
|
|
|
|
if (!img.Load(texName))
|
2012-09-29 22:23:26 +00:00
|
|
|
|
{
|
2014-05-18 10:12:47 +00:00
|
|
|
|
std::string error = img.GetError();
|
|
|
|
|
GetLogger()->Error("Couldn't load texture '%s': %s, blacklisting\n", texName.c_str(), error.c_str());
|
|
|
|
|
m_texBlacklist.insert(texName);
|
|
|
|
|
return Texture(); // invalid texture
|
2013-05-26 12:50:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
image = &img;
|
2012-09-29 22:23:26 +00:00
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2013-06-08 15:51:31 +00:00
|
|
|
|
tex = m_device->CreateTexture(image, params);
|
2013-05-26 12:50:23 +00:00
|
|
|
|
|
2012-08-12 17:28:22 +00:00
|
|
|
|
if (! tex.Valid())
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2013-05-26 12:50:23 +00:00
|
|
|
|
GetLogger()->Error("Couldn't load texture '%s', blacklisting\n", texName.c_str());
|
2012-08-12 08:45:04 +00:00
|
|
|
|
m_texBlacklist.insert(texName);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
return tex;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-05-26 12:50:23 +00:00
|
|
|
|
m_texNameMap[texName] = tex;
|
|
|
|
|
m_revTexNameMap[tex] = texName;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-08-12 17:28:22 +00:00
|
|
|
|
return tex;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Texture CEngine::LoadTexture(const std::string& name)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 17:28:22 +00:00
|
|
|
|
return LoadTexture(name, m_defaultTexParams);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-29 22:23:26 +00:00
|
|
|
|
Texture CEngine::LoadTexture(const std::string& name, CImage* image)
|
|
|
|
|
{
|
|
|
|
|
Texture tex = CreateTexture(name, m_defaultTexParams, image);
|
|
|
|
|
return tex;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Texture CEngine::LoadTexture(const std::string& name, const TextureCreateParams& params)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 08:45:04 +00:00
|
|
|
|
if (m_texBlacklist.find(name) != m_texBlacklist.end())
|
2012-09-19 21:50:28 +00:00
|
|
|
|
return Texture();
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
std::map<std::string, Texture>::iterator it = m_texNameMap.find(name);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
if (it != m_texNameMap.end())
|
2012-08-12 17:28:22 +00:00
|
|
|
|
return (*it).second;
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
2013-05-26 12:50:23 +00:00
|
|
|
|
return CreateTexture(name, params);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::LoadAllTextures()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2014-07-24 20:17:49 +00:00
|
|
|
|
LoadTexture("textures/interface/text.png");
|
|
|
|
|
m_miceTexture = LoadTexture("textures/interface/mouse.png");
|
|
|
|
|
LoadTexture("textures/interface/button1.png");
|
|
|
|
|
LoadTexture("textures/interface/button2.png");
|
|
|
|
|
LoadTexture("textures/interface/button3.png");
|
2014-09-27 16:26:29 +00:00
|
|
|
|
LoadTexture("textures/effect00.png");
|
|
|
|
|
LoadTexture("textures/effect01.png");
|
|
|
|
|
LoadTexture("textures/effect02.png");
|
2014-07-24 20:17:49 +00:00
|
|
|
|
LoadTexture("textures/interface/map.png");
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
2012-09-17 21:41:53 +00:00
|
|
|
|
if (! m_backgroundName.empty())
|
2013-05-11 21:05:20 +00:00
|
|
|
|
{
|
|
|
|
|
TextureCreateParams params = m_defaultTexParams;
|
|
|
|
|
params.padToNearestPowerOfTwo = true;
|
2014-07-24 20:17:49 +00:00
|
|
|
|
m_backgroundTex = LoadTexture("textures/"+m_backgroundName, params);
|
2013-05-11 21:05:20 +00:00
|
|
|
|
}
|
2012-08-12 17:28:22 +00:00
|
|
|
|
else
|
2012-09-17 21:41:53 +00:00
|
|
|
|
m_backgroundTex.SetInvalid();
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
|
|
|
|
if (! m_foregroundName.empty())
|
2014-07-24 20:17:49 +00:00
|
|
|
|
m_foregroundTex = LoadTexture("textures/"+m_foregroundName);
|
2012-08-12 17:28:22 +00:00
|
|
|
|
else
|
|
|
|
|
m_foregroundTex.SetInvalid();
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
|
|
|
|
m_planet->LoadTexture();
|
|
|
|
|
|
|
|
|
|
bool ok = true;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int objRank = 0; objRank < static_cast<int>( m_objects.size() ); objRank++)
|
2012-08-12 08:45:04 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! m_objects[objRank].used)
|
|
|
|
|
continue;
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
2012-09-29 08:40:11 +00:00
|
|
|
|
bool terrain = false;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN)
|
|
|
|
|
terrain = true;
|
2012-09-29 08:40:11 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
continue;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
2012-09-29 08:40:11 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
if (! p1.used)
|
|
|
|
|
continue;
|
2012-09-29 08:40:11 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
2012-08-12 08:45:04 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
2012-09-29 08:40:11 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! p2.tex1Name.empty())
|
|
|
|
|
{
|
|
|
|
|
if (terrain)
|
2014-07-24 20:17:49 +00:00
|
|
|
|
p2.tex1 = LoadTexture("textures/"+p2.tex1Name, m_terrainTexParams);
|
2012-12-26 19:58:02 +00:00
|
|
|
|
else
|
2014-07-24 20:17:49 +00:00
|
|
|
|
p2.tex1 = LoadTexture("textures/"+p2.tex1Name);
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! p2.tex1.Valid())
|
|
|
|
|
ok = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! p2.tex2Name.empty())
|
|
|
|
|
{
|
|
|
|
|
if (terrain)
|
2014-07-24 20:17:49 +00:00
|
|
|
|
p2.tex2 = LoadTexture("textures/"+p2.tex2Name, m_terrainTexParams);
|
2012-12-26 19:58:02 +00:00
|
|
|
|
else
|
2014-07-24 20:17:49 +00:00
|
|
|
|
p2.tex2 = LoadTexture("textures/"+p2.tex2Name);
|
2012-09-29 08:40:11 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! p2.tex2.Valid())
|
|
|
|
|
ok = false;
|
|
|
|
|
}
|
2012-08-12 08:45:04 +00:00
|
|
|
|
}
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
|
|
|
|
return ok;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-29 21:37:38 +00:00
|
|
|
|
bool IsExcludeColor(Math::Point *exclude, int x, int y)
|
|
|
|
|
{
|
|
|
|
|
int i = 0;
|
|
|
|
|
while ( exclude[i+0].x != 0.0f || exclude[i+0].y != 0.0f ||
|
|
|
|
|
exclude[i+1].y != 0.0f || exclude[i+1].y != 0.0f )
|
|
|
|
|
{
|
|
|
|
|
if ( x >= static_cast<int>(exclude[i+0].x*256.0f) &&
|
|
|
|
|
x < static_cast<int>(exclude[i+1].x*256.0f) &&
|
|
|
|
|
y >= static_cast<int>(exclude[i+0].y*256.0f) &&
|
2012-12-26 19:58:02 +00:00
|
|
|
|
y < static_cast<int>(exclude[i+1].y*256.0f) )
|
|
|
|
|
return true; // exclude
|
2012-09-29 21:37:38 +00:00
|
|
|
|
|
|
|
|
|
i += 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false; // point to include
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool CEngine::ChangeTextureColor(const std::string& texName,
|
|
|
|
|
Color colorRef1, Color colorNew1,
|
|
|
|
|
Color colorRef2, Color colorNew2,
|
|
|
|
|
float tolerance1, float tolerance2,
|
|
|
|
|
Math::Point ts, Math::Point ti,
|
|
|
|
|
Math::Point *exclude, float shift, bool hsv)
|
|
|
|
|
{
|
|
|
|
|
DeleteTexture(texName);
|
|
|
|
|
|
|
|
|
|
CImage img;
|
2014-07-24 20:17:49 +00:00
|
|
|
|
if (!img.Load(texName))
|
2012-09-29 21:37:38 +00:00
|
|
|
|
{
|
|
|
|
|
std::string error = img.GetError();
|
|
|
|
|
GetLogger()->Error("Couldn't load texture '%s': %s, blacklisting\n", texName.c_str(), error.c_str());
|
|
|
|
|
m_texBlacklist.insert(texName);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2014-11-22 12:30:05 +00:00
|
|
|
|
|
|
|
|
|
bool changeColorsNeeded = true;
|
|
|
|
|
|
2014-11-11 14:30:49 +00:00
|
|
|
|
if (colorRef1.r == colorNew1.r &&
|
|
|
|
|
colorRef1.g == colorNew1.g &&
|
|
|
|
|
colorRef1.b == colorNew1.b &&
|
|
|
|
|
colorRef2.r == colorNew2.r &&
|
|
|
|
|
colorRef2.g == colorNew2.g &&
|
|
|
|
|
colorRef2.b == colorNew2.b)
|
2014-11-22 12:30:05 +00:00
|
|
|
|
{
|
|
|
|
|
changeColorsNeeded = false;
|
|
|
|
|
}
|
2012-09-29 21:37:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int dx = img.GetSize().x;
|
2012-09-30 09:26:59 +00:00
|
|
|
|
int dy = img.GetSize().y;
|
2012-09-29 21:37:38 +00:00
|
|
|
|
|
2012-09-30 09:26:59 +00:00
|
|
|
|
int sx = static_cast<int>(Math::Max(ts.x*dx, 0));
|
|
|
|
|
int sy = static_cast<int>(Math::Max(ts.y*dy, 0));
|
|
|
|
|
|
|
|
|
|
int ex = static_cast<int>(Math::Min(ti.x*dx, dx));
|
|
|
|
|
int ey = static_cast<int>(Math::Min(ti.y*dy, dy));
|
2012-09-29 21:37:38 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ColorHSV cr1 = RGB2HSV(colorRef1);
|
|
|
|
|
ColorHSV cn1 = RGB2HSV(colorNew1);
|
|
|
|
|
ColorHSV cr2 = RGB2HSV(colorRef2);
|
|
|
|
|
ColorHSV cn2 = RGB2HSV(colorNew2);
|
|
|
|
|
|
2014-11-22 12:30:05 +00:00
|
|
|
|
if (changeColorsNeeded)
|
2012-09-29 21:37:38 +00:00
|
|
|
|
{
|
2014-11-22 12:30:05 +00:00
|
|
|
|
for (int y = sy; y < ey; y++)
|
2012-09-29 21:37:38 +00:00
|
|
|
|
{
|
2014-11-22 12:30:05 +00:00
|
|
|
|
for (int x = sx; x < ex; x++)
|
|
|
|
|
{
|
|
|
|
|
if (exclude != nullptr && IsExcludeColor(exclude, x,y) )
|
|
|
|
|
continue;
|
2012-09-29 21:37:38 +00:00
|
|
|
|
|
2014-11-22 12:30:05 +00:00
|
|
|
|
Color color = img.GetPixel(Math::IntPoint(x, y));
|
2012-09-29 21:37:38 +00:00
|
|
|
|
|
2014-11-22 12:30:05 +00:00
|
|
|
|
if (hsv)
|
2012-09-29 21:37:38 +00:00
|
|
|
|
{
|
2014-11-22 12:30:05 +00:00
|
|
|
|
ColorHSV c = RGB2HSV(color);
|
|
|
|
|
if (c.s > 0.01f && fabs(c.h - cr1.h) < tolerance1)
|
|
|
|
|
{
|
|
|
|
|
c.h += cn1.h - cr1.h;
|
|
|
|
|
c.s += cn1.s - cr1.s;
|
|
|
|
|
c.v += cn1.v - cr1.v;
|
|
|
|
|
if (c.h < 0.0f) c.h -= 1.0f;
|
|
|
|
|
if (c.h > 1.0f) c.h += 1.0f;
|
|
|
|
|
color = HSV2RGB(c);
|
|
|
|
|
color.r = Math::Norm(color.r + shift);
|
|
|
|
|
color.g = Math::Norm(color.g + shift);
|
|
|
|
|
color.b = Math::Norm(color.b + shift);
|
|
|
|
|
img.SetPixel(Math::IntPoint(x, y), color);
|
|
|
|
|
}
|
|
|
|
|
else if (tolerance2 != -1.0f &&
|
|
|
|
|
c.s > 0.01f && fabs(c.h - cr2.h) < tolerance2)
|
|
|
|
|
{
|
|
|
|
|
c.h += cn2.h - cr2.h;
|
|
|
|
|
c.s += cn2.s - cr2.s;
|
|
|
|
|
c.v += cn2.v - cr2.v;
|
|
|
|
|
if (c.h < 0.0f) c.h -= 1.0f;
|
|
|
|
|
if (c.h > 1.0f) c.h += 1.0f;
|
|
|
|
|
color = HSV2RGB(c);
|
|
|
|
|
color.r = Math::Norm(color.r + shift);
|
|
|
|
|
color.g = Math::Norm(color.g + shift);
|
|
|
|
|
color.b = Math::Norm(color.b + shift);
|
|
|
|
|
img.SetPixel(Math::IntPoint(x, y), color);
|
|
|
|
|
}
|
2012-09-29 21:37:38 +00:00
|
|
|
|
}
|
2014-11-22 12:30:05 +00:00
|
|
|
|
else
|
2012-09-29 21:37:38 +00:00
|
|
|
|
{
|
2014-11-22 12:30:05 +00:00
|
|
|
|
if ( fabs(color.r - colorRef1.r) +
|
|
|
|
|
fabs(color.g - colorRef1.g) +
|
|
|
|
|
fabs(color.b - colorRef1.b) < tolerance1 * 3.0f)
|
|
|
|
|
{
|
|
|
|
|
color.r = Math::Norm(colorNew1.r + color.r - colorRef1.r + shift);
|
|
|
|
|
color.g = Math::Norm(colorNew1.g + color.g - colorRef1.g + shift);
|
|
|
|
|
color.b = Math::Norm(colorNew1.b + color.b - colorRef1.b + shift);
|
|
|
|
|
img.SetPixel(Math::IntPoint(x, y), color);
|
|
|
|
|
}
|
|
|
|
|
else if (tolerance2 != -1 &&
|
|
|
|
|
fabs(color.r - colorRef2.r) +
|
|
|
|
|
fabs(color.g - colorRef2.g) +
|
|
|
|
|
fabs(color.b - colorRef2.b) < tolerance2 * 3.0f)
|
|
|
|
|
{
|
|
|
|
|
color.r = Math::Norm(colorNew2.r + color.r - colorRef2.r + shift);
|
|
|
|
|
color.g = Math::Norm(colorNew2.g + color.g - colorRef2.g + shift);
|
|
|
|
|
color.b = Math::Norm(colorNew2.b + color.b - colorRef2.b + shift);
|
|
|
|
|
img.SetPixel(Math::IntPoint(x, y), color);
|
|
|
|
|
}
|
2012-09-29 21:37:38 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Texture tex = m_device->CreateTexture(&img, m_defaultTexParams);
|
|
|
|
|
|
|
|
|
|
if (! tex.Valid())
|
|
|
|
|
{
|
|
|
|
|
GetLogger()->Error("Couldn't load texture '%s', blacklisting\n", texName.c_str());
|
|
|
|
|
m_texBlacklist.insert(texName);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_texNameMap[texName] = tex;
|
|
|
|
|
m_revTexNameMap[tex] = texName;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DeleteTexture(const std::string& texName)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
auto it = m_texNameMap.find(texName);
|
|
|
|
|
if (it == m_texNameMap.end())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
auto revIt = m_revTexNameMap.find((*it).second);
|
|
|
|
|
|
|
|
|
|
m_device->DestroyTexture((*it).second);
|
|
|
|
|
|
|
|
|
|
m_revTexNameMap.erase(revIt);
|
|
|
|
|
m_texNameMap.erase(it);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DeleteTexture(const Texture& tex)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
if (! tex.Valid())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
auto revIt = m_revTexNameMap.find(tex);
|
|
|
|
|
if (revIt == m_revTexNameMap.end())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_device->DestroyTexture(tex);
|
|
|
|
|
|
|
|
|
|
auto it = m_texNameMap.find((*revIt).second);
|
|
|
|
|
|
|
|
|
|
m_revTexNameMap.erase(revIt);
|
|
|
|
|
m_texNameMap.erase(it);
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-26 12:50:23 +00:00
|
|
|
|
void CEngine::FlushTextureCache()
|
|
|
|
|
{
|
|
|
|
|
m_texNameMap.clear();
|
|
|
|
|
m_revTexNameMap.clear();
|
|
|
|
|
m_texBlacklist.clear();
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::SetTexture(const std::string& name, int stage)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 08:45:04 +00:00
|
|
|
|
auto it = m_texNameMap.find(name);
|
|
|
|
|
if (it != m_texNameMap.end())
|
|
|
|
|
{
|
|
|
|
|
m_device->SetTexture(stage, (*it).second);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-12 17:28:22 +00:00
|
|
|
|
if (! LoadTexture(name).Valid())
|
2012-08-12 08:45:04 +00:00
|
|
|
|
{
|
|
|
|
|
m_device->SetTexture(stage, 0); // invalid texture
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it = m_texNameMap.find(name);
|
|
|
|
|
if (it != m_texNameMap.end())
|
|
|
|
|
{
|
|
|
|
|
m_device->SetTexture(stage, (*it).second);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_device->SetTexture(stage, 0); // invalid texture
|
|
|
|
|
return false; // should not happen normally
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetTexture(const Texture& tex, int stage)
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
|
|
|
|
m_device->SetTexture(stage, tex);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetTerrainVision(float vision)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_terrainVision = vision;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetFocus(float focus)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_focus = focus;
|
|
|
|
|
m_size = m_app->GetVideoConfig().size;
|
|
|
|
|
|
2012-08-26 23:02:25 +00:00
|
|
|
|
float aspect = (static_cast<float>(m_size.x)) / m_size.y;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
Math::LoadProjectionMatrix(m_matProj, m_focus, aspect, 0.5f, m_deepView[0]);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::GetFocus()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_focus;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetGroundSpot(bool mode)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_groundSpotVisible = mode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetGroundSpot()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_groundSpotVisible;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetShadow(bool mode)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_shadowVisible = mode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetShadow()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_shadowVisible;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetDirty(bool mode)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_dirty = mode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetDirty()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_dirty;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetFog(bool mode)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_fog = mode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetFog()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_fog;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-10 19:46:39 +00:00
|
|
|
|
void CEngine::SetSecondTexture(const std::string& texNum)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2014-11-10 19:46:39 +00:00
|
|
|
|
m_secondTex = texNum;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-11-10 19:46:39 +00:00
|
|
|
|
const std::string& CEngine::GetSecondTexture()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2014-11-10 19:46:39 +00:00
|
|
|
|
return m_secondTex;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetRankView(int rank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
int CEngine::GetRankView()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_rankView;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetDrawWorld(bool draw)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_drawWorld = draw;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetDrawFront(bool draw)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_drawFront = draw;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetAmbientColor(const Color& color, int rank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_ambientColor[rank] = color;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Color CEngine::GetAmbientColor(int rank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_ambientColor[rank];
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetWaterAddColor(const Color& color)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_waterAddColor = color;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Color CEngine::GetWaterAddColor()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_waterAddColor;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetFogColor(const Color& color, int rank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_fogColor[rank] = color;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Color CEngine::GetFogColor(int rank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_fogColor[rank];
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetDeepView(float length, int rank, bool ref)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
if (ref)
|
|
|
|
|
length *= m_clippingDistance;
|
|
|
|
|
|
|
|
|
|
m_deepView[rank] = length;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::GetDeepView(int rank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_deepView[rank];
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetFogStart(float start, int rank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_fogStart[rank] = start;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::GetFogStart(int rank)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_fogStart[rank];
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetBackground(const std::string& name, Color up, Color down,
|
2013-05-11 21:05:20 +00:00
|
|
|
|
Color cloudUp, Color cloudDown, bool full)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-17 21:41:53 +00:00
|
|
|
|
if (m_backgroundTex.Valid())
|
2012-08-12 17:28:22 +00:00
|
|
|
|
{
|
2012-09-17 21:41:53 +00:00
|
|
|
|
DeleteTexture(m_backgroundTex);
|
|
|
|
|
m_backgroundTex.SetInvalid();
|
2012-08-12 17:28:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_backgroundName = name;
|
|
|
|
|
m_backgroundColorUp = up;
|
|
|
|
|
m_backgroundColorDown = down;
|
|
|
|
|
m_backgroundCloudUp = cloudUp;
|
|
|
|
|
m_backgroundCloudDown = cloudDown;
|
|
|
|
|
m_backgroundFull = full;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
if (! m_backgroundName.empty())
|
2013-05-11 21:05:20 +00:00
|
|
|
|
{
|
|
|
|
|
TextureCreateParams params = m_defaultTexParams;
|
|
|
|
|
params.padToNearestPowerOfTwo = true;
|
2014-07-24 20:17:49 +00:00
|
|
|
|
m_backgroundTex = LoadTexture("textures/"+m_backgroundName, params);
|
2013-05-11 21:05:20 +00:00
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::GetBackground(std::string& name, Color& up, Color& down,
|
2013-05-11 21:05:20 +00:00
|
|
|
|
Color& cloudUp, Color& cloudDown, bool &full)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
name = m_backgroundName;
|
|
|
|
|
up = m_backgroundColorUp;
|
|
|
|
|
down = m_backgroundColorDown;
|
|
|
|
|
cloudUp = m_backgroundCloudUp;
|
|
|
|
|
cloudDown = m_backgroundCloudDown;
|
|
|
|
|
full = m_backgroundFull;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetForegroundName(const std::string& name)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 17:28:22 +00:00
|
|
|
|
if (m_foregroundTex.Valid())
|
|
|
|
|
{
|
|
|
|
|
DeleteTexture(m_foregroundTex);
|
|
|
|
|
m_foregroundTex.SetInvalid();
|
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-08-12 08:45:04 +00:00
|
|
|
|
m_foregroundName = name;
|
2012-08-12 17:28:22 +00:00
|
|
|
|
|
|
|
|
|
if (! m_foregroundName.empty())
|
2014-07-24 20:17:49 +00:00
|
|
|
|
m_foregroundTex = LoadTexture("textures/"+m_foregroundName);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetOverFront(bool front)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_overFront = front;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetOverColor(const Color& color, int mode)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_overColor = color;
|
|
|
|
|
m_overMode = mode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetParticleDensity(float value)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
if (value < 0.0f) value = 0.0f;
|
|
|
|
|
if (value > 2.0f) value = 2.0f;
|
|
|
|
|
m_particleDensity = value;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::GetParticleDensity()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_particleDensity;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::ParticleAdapt(float factor)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
if (m_particleDensity == 0.0f)
|
|
|
|
|
return 1000000.0f;
|
|
|
|
|
|
|
|
|
|
return factor / m_particleDensity;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetClippingDistance(float value)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
if (value < 0.5f) value = 0.5f;
|
|
|
|
|
if (value > 2.0f) value = 2.0f;
|
2013-01-27 10:43:53 +00:00
|
|
|
|
m_lastClippingDistance = m_clippingDistance;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_clippingDistance = value;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::GetClippingDistance()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_clippingDistance;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetObjectDetail(float value)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
if ( value < 0.0f ) value = 0.0f;
|
|
|
|
|
if ( value > 2.0f ) value = 2.0f;
|
|
|
|
|
m_objectDetail = value;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::GetObjectDetail()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_objectDetail;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetGadgetQuantity(float value)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
if (value < 0.0f) value = 0.0f;
|
|
|
|
|
if (value > 1.0f) value = 1.0f;
|
|
|
|
|
|
|
|
|
|
m_gadgetQuantity = value;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::GetGadgetQuantity()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_gadgetQuantity;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetTextureQuality(int value)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
if (value < 0) value = 0;
|
|
|
|
|
if (value > 2) value = 2;
|
|
|
|
|
|
|
|
|
|
if (value != m_textureQuality)
|
|
|
|
|
{
|
|
|
|
|
m_textureQuality = value;
|
|
|
|
|
LoadAllTextures();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
int CEngine::GetTextureQuality()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_textureQuality;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-06 15:55:10 +00:00
|
|
|
|
void CEngine::SetTextureFilterMode(TexFilter value)
|
|
|
|
|
{
|
|
|
|
|
m_defaultTexParams.filter = value;
|
|
|
|
|
m_terrainTexParams.filter = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TexFilter CEngine::GetTextureFilterMode()
|
|
|
|
|
{
|
|
|
|
|
return m_terrainTexParams.filter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::SetTextureMipmapLevel(int value)
|
|
|
|
|
{
|
|
|
|
|
if (value < 1) value = 1;
|
|
|
|
|
if (value > 16) value = 16;
|
|
|
|
|
|
|
|
|
|
m_textureMipmapLevel = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int CEngine::GetTextureMipmapLevel()
|
|
|
|
|
{
|
|
|
|
|
return m_textureMipmapLevel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CEngine::SetTextureAnisotropyLevel(int value)
|
|
|
|
|
{
|
|
|
|
|
if (value < 1) value = 1;
|
|
|
|
|
if (value > 16) value = 16;
|
|
|
|
|
|
|
|
|
|
m_textureAnisotropy = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int CEngine::GetTextureAnisotropyLevel()
|
|
|
|
|
{
|
|
|
|
|
return m_textureAnisotropy;
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
void CEngine::SetShadowMapping(bool value)
|
|
|
|
|
{
|
|
|
|
|
m_shadowMapping = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CEngine::GetShadowMapping()
|
|
|
|
|
{
|
|
|
|
|
return m_shadowMapping;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetTotoMode(bool present)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_totoMode = present;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetTotoMode()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_totoMode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetLensMode(bool present)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_lensMode = present;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetLensMode()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_lensMode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetWaterMode(bool present)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_waterMode = present;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetWaterMode()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_waterMode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetLightingMode(bool present)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_lightMode = present;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetLightingMode()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_lightMode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetSkyMode(bool present)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_skyMode = present;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetSkyMode()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_skyMode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetBackForce(bool present)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_backForce = present;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetBackForce()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_backForce;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetPlanetMode(bool present)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_planetMode = present;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetPlanetMode()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_planetMode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetLightMode(bool present)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_lightMode = present;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetLightMode()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_lightMode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetEditIndentMode(bool autoIndent)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_editIndentMode = autoIndent;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::GetEditIndentMode()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_editIndentMode;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetEditIndentValue(int value)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_editIndentValue = value;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
int CEngine::GetEditIndentValue()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_editIndentValue;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetTracePrecision(float factor)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_tracePrecision = factor;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::GetTracePrecision()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_tracePrecision;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::SetMouseType(EngineMouseType type)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_mouseType = type;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
EngineMouseType CEngine::GetMouseType()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_mouseType;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
const Math::Matrix& CEngine::GetMatView()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_matView;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Math::Vector CEngine::GetEyePt()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_eyePt;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Math::Vector CEngine::GetLookatPt()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_lookatPt;
|
|
|
|
|
}
|
2012-08-06 18:20:50 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::GetEyeDirH()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_eyeDirH;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
float CEngine::GetEyeDirV()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return m_eyeDirV;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
bool CEngine::IsVisiblePoint(const Math::Vector &pos)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
return Math::Distance(m_eyePt, pos) <= m_deepView[0];
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::UpdateMatProj()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProj);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::ApplyChange()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_deepView[0] /= m_lastClippingDistance;
|
|
|
|
|
m_deepView[1] /= m_lastClippingDistance;
|
|
|
|
|
|
|
|
|
|
SetFocus(m_focus);
|
|
|
|
|
|
|
|
|
|
m_deepView[0] *= m_clippingDistance;
|
|
|
|
|
m_deepView[1] *= m_clippingDistance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*******************************************************
|
|
|
|
|
Rendering
|
|
|
|
|
*******************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
This function sets up render states, clears the
|
|
|
|
|
viewport, and renders the scene. */
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::Render()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! m_render)
|
|
|
|
|
return;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
m_statisticTriangle = 0;
|
|
|
|
|
m_lastState = -1;
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_lastColor = Color(-1.0f);
|
|
|
|
|
m_lastMaterial = Material();
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
m_lightMan->UpdateLights();
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Color color;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
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();
|
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
if (m_shadowMapping)
|
|
|
|
|
RenderShadowMap();
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
if (m_drawWorld)
|
|
|
|
|
Draw3DScene();
|
|
|
|
|
|
2012-10-25 21:29:49 +00:00
|
|
|
|
m_app->StartPerformanceCounter(PCNT_RENDER_INTERFACE);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
DrawInterface();
|
2012-10-25 21:29:49 +00:00
|
|
|
|
m_app->StopPerformanceCounter(PCNT_RENDER_INTERFACE);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
// End the scene
|
|
|
|
|
m_device->EndScene();
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::Draw3DScene()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, true);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, true);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, true);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
float fogStart = m_deepView[m_rankView]*m_fogStart[m_rankView];
|
|
|
|
|
float fogEnd = m_deepView[m_rankView];
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetFogParams(FOG_LINEAR, m_fogColor[m_rankView], fogStart, fogEnd, 1.0f);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProj);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_VIEW, m_matView);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
if (m_waterMode) m_water->DrawBack(); // draws water background
|
|
|
|
|
|
2012-10-25 21:29:49 +00:00
|
|
|
|
m_app->StartPerformanceCounter(PCNT_RENDER_TERRAIN);
|
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
// Draw terrain
|
|
|
|
|
|
|
|
|
|
m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN);
|
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
// Enable shadow mapping
|
|
|
|
|
if (m_shadowMapping)
|
|
|
|
|
{
|
|
|
|
|
m_device->SetTextureEnabled(2, true);
|
|
|
|
|
m_device->SetTexture(2, m_shadowMap);
|
|
|
|
|
m_device->SetTextureMatrix(2, m_shadowTextureMat);
|
|
|
|
|
|
|
|
|
|
Math::Matrix identity;
|
|
|
|
|
identity.LoadIdentity();
|
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, identity);
|
|
|
|
|
|
|
|
|
|
TextureStageParams params;
|
|
|
|
|
params.colorOperation = TEX_MIX_OPER_MODULATE;
|
|
|
|
|
params.wrapS = TEX_WRAP_CLAMP_TO_BORDER;
|
|
|
|
|
params.wrapT = TEX_WRAP_CLAMP_TO_BORDER;
|
|
|
|
|
m_device->SetTextureStageParams(2, params);
|
|
|
|
|
|
|
|
|
|
TextureGenerationParams genParams;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
genParams.coords[i].mode = TEX_GEN_EYE_LINEAR;
|
|
|
|
|
|
|
|
|
|
for (int j = 0; j < 4; j++)
|
|
|
|
|
{
|
|
|
|
|
genParams.coords[i].plane[j] = (i == j ? 1.0f : 0.0f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_device->SetTextureCoordGeneration(2, genParams);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2014-07-12 19:37:34 +00:00
|
|
|
|
if (! m_objects[objRank].used)
|
|
|
|
|
continue;
|
2012-08-26 23:02:25 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
if (m_objects[objRank].type != ENG_OBJTYPE_TERRAIN)
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
if (! m_objects[objRank].drawWorld)
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
if (! IsVisible(objRank))
|
|
|
|
|
continue;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
continue;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
2012-12-28 12:23:49 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
if (! p1.used)
|
|
|
|
|
continue;
|
2012-12-27 13:18:16 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
2012-08-26 23:02:25 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
SetTexture(p2.tex1, 0);
|
|
|
|
|
SetTexture(p2.tex2, 1);
|
|
|
|
|
|
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
2012-12-26 19:58:02 +00:00
|
|
|
|
{
|
2014-07-12 19:37:34 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
2012-08-26 23:02:25 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel))
|
|
|
|
|
continue;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2014-07-12 19:37:34 +00:00
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
SetMaterial(p4.material);
|
|
|
|
|
SetState(p4.state);
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
DrawObject(p4);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-12 22:14:42 +00:00
|
|
|
|
}
|
2014-07-12 19:37:34 +00:00
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
// Disable shadow mapping
|
|
|
|
|
if (m_shadowMapping)
|
|
|
|
|
{
|
|
|
|
|
Math::Matrix identity;
|
|
|
|
|
identity.LoadIdentity();
|
|
|
|
|
|
|
|
|
|
m_device->SetTexture(2, 0);
|
|
|
|
|
m_device->SetTextureEnabled(2, false);
|
|
|
|
|
m_device->SetTextureMatrix(2, identity);
|
|
|
|
|
|
|
|
|
|
TextureGenerationParams params;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
params.coords[i].mode = TEX_GEN_NONE;
|
|
|
|
|
|
|
|
|
|
m_device->SetTextureCoordGeneration(2, params);
|
2015-05-12 11:09:31 +00:00
|
|
|
|
|
|
|
|
|
m_device->SetTexture(3, 0);
|
|
|
|
|
m_device->SetTextureEnabled(3, false);
|
2015-05-11 13:21:17 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-07-12 19:37:34 +00:00
|
|
|
|
// Draws the shadows , if shadows enabled
|
|
|
|
|
if (m_shadowVisible)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
DrawShadow();
|
2014-07-12 19:37:34 +00:00
|
|
|
|
|
2012-07-23 19:41:27 +00:00
|
|
|
|
|
2012-10-25 21:29:49 +00:00
|
|
|
|
m_app->StopPerformanceCounter(PCNT_RENDER_TERRAIN);
|
|
|
|
|
|
|
|
|
|
// Draw other objects (and if shadows disabled, also terrain)
|
|
|
|
|
|
|
|
|
|
m_app->StartPerformanceCounter(PCNT_RENDER_OBJECTS);
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
bool transparent = false;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
2012-08-12 22:14:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! m_objects[objRank].used)
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN)
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! m_objects[objRank].drawWorld)
|
|
|
|
|
continue;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! IsVisible(objRank))
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
continue;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
if (! p1.used)
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_lightMan->UpdateDeviceLights(m_objects[objRank].type);
|
|
|
|
|
|
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
SetTexture(p2.tex1, 0);
|
|
|
|
|
SetTexture(p2.tex2, 1);
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel))
|
2012-12-26 19:58:02 +00:00
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
|
|
|
|
if (m_objects[objRank].transparency != 0.0f) // transparent ?
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-08-12 22:14:42 +00:00
|
|
|
|
transparent = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetMaterial(p4.material);
|
|
|
|
|
SetState(p4.state);
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
DrawObject(p4);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-12 22:14:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw transparent objects
|
2012-07-23 19:41:27 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
if (transparent)
|
|
|
|
|
{
|
2012-09-29 20:44:05 +00:00
|
|
|
|
int tState = ENG_RSTATE_TTEXTURE_BLACK | ENG_RSTATE_2FACE;
|
|
|
|
|
Color tColor = Color(68.0f / 255.0f, 68.0f / 255.0f, 68.0f / 255.0f, 68.0f / 255.0f);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! m_objects[objRank].used)
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN)
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! m_objects[objRank].drawWorld)
|
|
|
|
|
continue;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! IsVisible(objRank))
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
continue;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
|
|
|
|
|
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
if (! p1.used)
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_lightMan->UpdateDeviceLights(m_objects[objRank].type);
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
SetTexture(p2.tex1, 0);
|
|
|
|
|
SetTexture(p2.tex2, 1);
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel))
|
2012-12-26 19:58:02 +00:00
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
|
|
|
|
if (m_objects[objRank].transparency == 0.0f)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
SetMaterial(p4.material);
|
|
|
|
|
SetState(tState, tColor);
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
DrawObject(p4);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-12 22:14:42 +00:00
|
|
|
|
}
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-10-25 21:29:49 +00:00
|
|
|
|
m_app->StopPerformanceCounter(PCNT_RENDER_OBJECTS);
|
|
|
|
|
|
2012-09-27 21:18:12 +00:00
|
|
|
|
m_lightMan->UpdateDeviceLights(ENG_OBJTYPE_TERRAIN);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2013-06-17 16:06:39 +00:00
|
|
|
|
if (m_debugLights)
|
|
|
|
|
m_device->DebugLights();
|
|
|
|
|
|
|
|
|
|
if (m_debugDumpLights)
|
|
|
|
|
{
|
|
|
|
|
m_debugDumpLights = false;
|
|
|
|
|
m_lightMan->DebugDumpLights();
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-25 21:29:49 +00:00
|
|
|
|
if (m_waterMode)
|
|
|
|
|
{
|
|
|
|
|
m_app->StartPerformanceCounter(PCNT_RENDER_WATER);
|
|
|
|
|
m_water->DrawSurf(); // draws water surface
|
|
|
|
|
m_app->StopPerformanceCounter(PCNT_RENDER_WATER);
|
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-10-25 21:29:49 +00:00
|
|
|
|
m_app->StartPerformanceCounter(PCNT_RENDER_PARTICLE);
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_particle->DrawParticle(SH_WORLD); // draws the particles of the 3D world
|
2012-10-25 21:29:49 +00:00
|
|
|
|
m_app->StopPerformanceCounter(PCNT_RENDER_PARTICLE);
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_lightning->Draw(); // draws lightning
|
2012-09-20 22:01:03 +00:00
|
|
|
|
|
2012-10-19 21:05:41 +00:00
|
|
|
|
if (m_lensMode) DrawForegroundImage(); // draws the foreground
|
2012-09-20 22:01:03 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
if (! m_overFront) DrawOverColor(); // draws the foreground color
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
void CEngine::RenderShadowMap()
|
|
|
|
|
{
|
|
|
|
|
if (!m_shadowMapping) return;
|
|
|
|
|
|
|
|
|
|
m_app->StartPerformanceCounter(PCNT_RENDER_SHADOW_MAP);
|
|
|
|
|
|
|
|
|
|
// If no shadow map texture exists, create it
|
|
|
|
|
if (m_shadowMap.id == 0)
|
|
|
|
|
{
|
|
|
|
|
int width, height;
|
|
|
|
|
|
|
|
|
|
int depth = m_app->GetInstance().GetVideoConfig().depthSize;
|
|
|
|
|
|
2015-05-12 11:09:31 +00:00
|
|
|
|
if (m_offscreenShadowRendering)
|
2015-05-11 13:21:17 +00:00
|
|
|
|
{
|
2015-05-12 11:09:31 +00:00
|
|
|
|
int size;
|
|
|
|
|
|
|
|
|
|
if (CProfile::GetInstance().GetIntProperty("Setup", "OffscreenBuffer", size))
|
|
|
|
|
{
|
|
|
|
|
width = height = size;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
width = height = 2048;
|
|
|
|
|
}
|
2015-05-11 13:21:17 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int min = Math::Min(m_size.x, m_size.y);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 16; i++)
|
|
|
|
|
{
|
|
|
|
|
if (min < (1 << i)) break;
|
|
|
|
|
|
|
|
|
|
width = height = 1 << i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_shadowMap = m_device->CreateDepthTexture(width, height, depth);
|
|
|
|
|
|
2015-05-12 11:09:31 +00:00
|
|
|
|
if (m_offscreenShadowRendering)
|
|
|
|
|
{
|
|
|
|
|
m_device->InitOffscreenBuffer(width, height);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
GetLogger()->Info("Created shadow map texture: %dx%d, depth %d\n", width, height, depth);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-12 11:09:31 +00:00
|
|
|
|
if (m_offscreenShadowRendering)
|
|
|
|
|
{
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_OFFSCREEN_RENDERING, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_device->Clear();
|
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
// change state to rendering shadow maps
|
|
|
|
|
m_device->SetColorMask(false, false, false, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, true);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, true);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_BLENDING, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_CULLING, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_ALPHA_TEST, true);
|
|
|
|
|
|
|
|
|
|
m_device->SetViewport(0, 0, m_shadowMap.size.x, m_shadowMap.size.y);
|
|
|
|
|
|
|
|
|
|
// recompute matrices
|
|
|
|
|
Math::Vector worldUp(1.0f, 0.0f, 0.0f);
|
|
|
|
|
Math::Vector dir = m_lookatPt - m_eyePt;
|
2015-05-12 11:09:31 +00:00
|
|
|
|
float change = Math::Max(0.5f, (5.0f + dir.Length()) / 25.0f);
|
2015-05-11 13:21:17 +00:00
|
|
|
|
dir.Normalize();
|
|
|
|
|
Math::Vector pos = m_lookatPt + 40.0f * dir;
|
|
|
|
|
|
|
|
|
|
Math::Vector lightPos = pos + Math::Vector(3.0f, 30.0f, 3.0f);
|
|
|
|
|
Math::Vector lookAt = pos + Math::Vector(0.0, 100.0f, 0.0f);
|
|
|
|
|
|
2015-05-12 11:09:31 +00:00
|
|
|
|
float dist = 75.0f * change;
|
|
|
|
|
|
|
|
|
|
if (m_offscreenShadowRendering) dist = 400.0f * change;
|
2015-05-11 13:21:17 +00:00
|
|
|
|
|
2015-05-12 11:09:31 +00:00
|
|
|
|
Math::LoadOrthoProjectionMatrix(m_shadowProjMat, -dist, dist, -dist, dist, -200.0f, 200.0f);
|
2015-05-11 13:21:17 +00:00
|
|
|
|
Math::LoadViewMatrix(m_shadowViewMat, lightPos, lookAt, worldUp);
|
|
|
|
|
|
|
|
|
|
Math::Matrix temporary = Math::MultiplyMatrices(m_shadowProjMat, m_shadowViewMat);
|
|
|
|
|
m_shadowTextureMat = Math::MultiplyMatrices(m_shadowBias, temporary);
|
|
|
|
|
|
|
|
|
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_shadowProjMat);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_VIEW, m_shadowViewMat);
|
|
|
|
|
|
|
|
|
|
m_device->SetTexture(0, 0);
|
|
|
|
|
m_device->SetTexture(1, 0);
|
|
|
|
|
|
|
|
|
|
//m_device->SetCullMode(CULL_CW);
|
|
|
|
|
//m_device->SetRenderState(RENDER_STATE_DEPTH_BIAS, true);
|
|
|
|
|
//m_device->SetDepthBias(2.0f, 4.0f);
|
|
|
|
|
|
|
|
|
|
// render objects into shadow map
|
|
|
|
|
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
|
|
|
|
{
|
|
|
|
|
if (!m_objects[objRank].used)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (m_objects[objRank].type == ENG_OBJTYPE_TERRAIN)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
//if (!m_objects[objRank].drawWorld)
|
|
|
|
|
// continue;
|
|
|
|
|
|
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
|
|
|
|
|
|
|
|
|
// TODO: check proper object filtering
|
|
|
|
|
if (!IsVisible(objRank))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>(m_baseObjects.size()));
|
|
|
|
|
|
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
if (!p1.used)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
//m_lightMan->UpdateDeviceLights(m_objects[objRank].type);
|
|
|
|
|
|
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>(p1.next.size()); l2++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
|
|
|
|
|
2015-05-11 16:00:02 +00:00
|
|
|
|
SetTexture(p2.tex1, 0);
|
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>(p2.next.size()); l3++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
|
|
|
|
|
|
|
|
|
if (!IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>(p3.next.size()); l4++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
|
|
|
|
|
|
|
|
|
//if (m_objects[objRank].transparency != 0.0f) // transparent ?
|
|
|
|
|
// continue;
|
|
|
|
|
|
|
|
|
|
DrawObject(p4);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-12 11:09:31 +00:00
|
|
|
|
//m_device->SetRenderState(RENDER_STATE_DEPTH_BIAS, false);
|
2015-05-11 13:21:17 +00:00
|
|
|
|
|
|
|
|
|
// copy depth buffer to shadow map
|
|
|
|
|
m_device->CopyFramebufferToTexture(m_shadowMap, 0, 0, 0, 0, m_shadowMap.size.x, m_shadowMap.size.y);
|
|
|
|
|
|
2015-05-12 11:09:31 +00:00
|
|
|
|
if (m_offscreenShadowRendering)
|
|
|
|
|
{
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_OFFSCREEN_RENDERING, false);
|
|
|
|
|
}
|
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
// restore default state
|
|
|
|
|
m_device->SetViewport(0, 0, m_size.x, m_size.y);
|
|
|
|
|
|
|
|
|
|
m_device->SetColorMask(true, true, true, true);
|
|
|
|
|
m_device->Clear();
|
|
|
|
|
|
|
|
|
|
m_app->StopPerformanceCounter(PCNT_RENDER_SHADOW_MAP);
|
|
|
|
|
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, false);
|
|
|
|
|
}
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
void CEngine::DrawObject(const EngineBaseObjDataTier& p4)
|
2012-12-14 20:30:35 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (p4.staticBufferId != 0)
|
2012-12-14 20:30:35 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_device->DrawStaticBuffer(p4.staticBufferId);
|
2012-12-14 20:30:35 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
|
|
|
|
|
m_statisticTriangle += p4.vertices.size() / 3;
|
2012-12-14 20:30:35 +00:00
|
|
|
|
else
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_statisticTriangle += p4.vertices.size() - 2;
|
2012-12-14 20:30:35 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (p4.type == ENG_TRIANGLE_TYPE_TRIANGLES)
|
2012-12-14 20:30:35 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_TRIANGLES, &p4.vertices[0], p4.vertices.size());
|
|
|
|
|
m_statisticTriangle += p4.vertices.size() / 3;
|
2012-12-14 20:30:35 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, &p4.vertices[0], p4.vertices.size() );
|
|
|
|
|
m_statisticTriangle += p4.vertices.size() - 2;
|
2012-12-14 20:30:35 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DrawInterface()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-27 21:18:12 +00:00
|
|
|
|
// Force new state to disable lighting
|
|
|
|
|
m_interfaceMode = true;
|
|
|
|
|
m_lastState = -1;
|
|
|
|
|
SetState(Gfx::ENG_RSTATE_NORMAL);
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
// Draw the entire interface
|
2013-02-16 21:37:43 +00:00
|
|
|
|
Ui::CInterface* interface = CRobotMain::GetInstancePointer()->GetInterface();
|
2012-08-10 21:31:42 +00:00
|
|
|
|
if (interface != nullptr)
|
2013-02-16 21:37:43 +00:00
|
|
|
|
{
|
2012-08-10 21:31:42 +00:00
|
|
|
|
interface->Draw();
|
2013-02-16 21:37:43 +00:00
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-27 21:18:12 +00:00
|
|
|
|
m_interfaceMode = false;
|
|
|
|
|
m_lastState = -1;
|
|
|
|
|
SetState(Gfx::ENG_RSTATE_NORMAL);
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_particle->DrawParticle(SH_INTERFACE); // draws the particles of the interface
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
// 3D objects drawn in front of interface
|
|
|
|
|
if (m_drawFront)
|
|
|
|
|
{
|
|
|
|
|
// Display the objects
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, true);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProj);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
m_device->SetGlobalAmbient(m_ambientColor[m_rankView]);
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, true);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, true);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
float fogStart = m_deepView[m_rankView]*m_fogStart[m_rankView];
|
|
|
|
|
float fogEnd = m_deepView[m_rankView];
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetFogParams(FOG_LINEAR, m_fogColor[m_rankView], fogStart, fogEnd, 1.0f);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_VIEW, m_matView);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int objRank = 0; objRank < static_cast<int>(m_objects.size()); objRank++)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! m_objects[objRank].used)
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (m_shadowVisible && m_objects[objRank].type == ENG_OBJTYPE_TERRAIN)
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! m_objects[objRank].drawFront)
|
|
|
|
|
continue;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_objects[objRank].transform);
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! IsVisible(objRank))
|
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
int baseObjRank = m_objects[objRank].baseObjRank;
|
2012-12-28 12:23:49 +00:00
|
|
|
|
if (baseObjRank == -1)
|
|
|
|
|
continue;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>( m_baseObjects.size() ));
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObject& p1 = m_baseObjects[baseObjRank];
|
|
|
|
|
if (! p1.used)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
m_lightMan->UpdateDeviceLights(m_objects[objRank].type);
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
|
|
|
|
|
{
|
|
|
|
|
EngineBaseObjTexTier& p2 = p1.next[l2];
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
SetTexture(p2.tex1, 0);
|
|
|
|
|
SetTexture(p2.tex2, 1);
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
|
|
|
|
for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjLODTier& p3 = p2.next[l3];
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
2013-01-27 10:43:53 +00:00
|
|
|
|
if (! IsWithinLODLimit(m_objects[objRank].distance, p3.lodLevel))
|
2012-12-26 19:58:02 +00:00
|
|
|
|
continue;
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
|
|
|
|
for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
EngineBaseObjDataTier& p4 = p3.next[l4];
|
2012-08-12 22:14:42 +00:00
|
|
|
|
|
|
|
|
|
SetMaterial(p4.material);
|
|
|
|
|
SetState(p4.state);
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
DrawObject(p4);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-12 22:14:42 +00:00
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_particle->DrawParticle(SH_FRONT); // draws the particles of the 3D world
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_TEST, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Draw foreground color
|
|
|
|
|
if (m_overFront)
|
|
|
|
|
DrawOverColor();
|
|
|
|
|
|
2012-09-20 18:37:37 +00:00
|
|
|
|
// At the end to not overlap
|
2012-08-10 21:31:42 +00:00
|
|
|
|
DrawMouse();
|
|
|
|
|
DrawHighlight();
|
2012-09-20 18:37:37 +00:00
|
|
|
|
DrawStats();
|
2014-10-29 16:53:46 +00:00
|
|
|
|
DrawTimer();
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::UpdateGroundSpotTextures()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-10-20 14:34:22 +00:00
|
|
|
|
if (!m_firstGroundSpot &&
|
|
|
|
|
m_groundMark.drawPos.x == m_groundMark.pos.x &&
|
|
|
|
|
m_groundMark.drawPos.z == m_groundMark.pos.z &&
|
|
|
|
|
m_groundMark.drawRadius == m_groundMark.radius &&
|
2012-12-26 19:58:02 +00:00
|
|
|
|
m_groundMark.drawIntensity == m_groundMark.intensity)
|
|
|
|
|
return;
|
2012-10-20 14:34:22 +00:00
|
|
|
|
|
|
|
|
|
for (int s = 0; s < 16; s++)
|
|
|
|
|
{
|
|
|
|
|
Math::Point min, max;
|
|
|
|
|
min.x = (s%4) * 254.0f - 1.0f; // 1 pixel cover
|
|
|
|
|
min.y = (s/4) * 254.0f - 1.0f;
|
|
|
|
|
max.x = min.x + 254.0f + 2.0f;
|
|
|
|
|
max.y = min.y + 254.0f + 2.0f;
|
|
|
|
|
|
|
|
|
|
bool clear = false;
|
|
|
|
|
bool set = false;
|
|
|
|
|
|
|
|
|
|
// Calculate the area to be erased.
|
|
|
|
|
int dot = static_cast<int>(m_groundMark.drawRadius/2.0f);
|
|
|
|
|
|
|
|
|
|
float tu, tv;
|
|
|
|
|
float cx, cy;
|
|
|
|
|
|
|
|
|
|
tu = (m_groundMark.drawPos.x+1600.0f)/3200.0f;
|
|
|
|
|
tv = (m_groundMark.drawPos.z+1600.0f)/3200.0f; // 0..1
|
|
|
|
|
|
|
|
|
|
cx = (tu*254.0f*4.0f)-0.5f;
|
|
|
|
|
cy = (tv*254.0f*4.0f)-0.5f;
|
|
|
|
|
|
|
|
|
|
if (dot == 0)
|
|
|
|
|
{
|
|
|
|
|
cx += 0.5f;
|
|
|
|
|
cy += 0.5f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float px = cx-Math::Mod(cx, 1.0f);
|
|
|
|
|
float py = cy-Math::Mod(cy, 1.0f); // multiple of 1
|
|
|
|
|
|
|
|
|
|
if (m_firstGroundSpot ||
|
|
|
|
|
(m_groundMark.drawRadius != 0.0f &&
|
|
|
|
|
px+dot >= min.x && py+dot >= min.y &&
|
|
|
|
|
px-dot <= max.x && py-dot <= max.y))
|
|
|
|
|
{
|
|
|
|
|
clear = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Calculate the area to draw.
|
|
|
|
|
dot = static_cast<int>(m_groundMark.radius/2.0f);
|
|
|
|
|
|
|
|
|
|
tu = (m_groundMark.pos.x+1600.0f)/3200.0f;
|
|
|
|
|
tv = (m_groundMark.pos.z+1600.0f)/3200.0f; // 0..1
|
|
|
|
|
|
|
|
|
|
cx = (tu*254.0f*4.0f)-0.5f;
|
|
|
|
|
cy = (tv*254.0f*4.0f)-0.5f;
|
|
|
|
|
|
|
|
|
|
if ( dot == 0 )
|
|
|
|
|
{
|
|
|
|
|
cx += 0.5f;
|
|
|
|
|
cy += 0.5f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
px = cx - Math::Mod(cx, 1.0f);
|
|
|
|
|
py = cy - Math::Mod(cy, 1.0f); // multiple of 1
|
|
|
|
|
|
|
|
|
|
if (m_groundMark.draw &&
|
|
|
|
|
px+dot >= min.x && py+dot >= min.y &&
|
|
|
|
|
px-dot <= max.x && py-dot <= max.y)
|
|
|
|
|
{
|
|
|
|
|
set = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (clear || set)
|
|
|
|
|
{
|
|
|
|
|
CImage shadowImg(Math::IntPoint(256, 256));
|
|
|
|
|
shadowImg.Fill(Gfx::IntColor(255, 255, 255, 255));
|
|
|
|
|
|
|
|
|
|
// Draw the new shadows.
|
|
|
|
|
for (int i = 0; i < static_cast<int>( m_groundSpots.size() ); i++)
|
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (m_groundSpots[i].used == false ||
|
|
|
|
|
m_groundSpots[i].radius == 0.0f)
|
|
|
|
|
continue;
|
2012-10-20 14:34:22 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (m_groundSpots[i].min == 0.0f &&
|
|
|
|
|
m_groundSpots[i].max == 0.0f)
|
2012-10-20 14:34:22 +00:00
|
|
|
|
{
|
|
|
|
|
dot = static_cast<int>(m_groundSpots[i].radius/2.0f);
|
|
|
|
|
|
|
|
|
|
tu = (m_groundSpots[i].pos.x+1600.0f)/3200.0f;
|
|
|
|
|
tv = (m_groundSpots[i].pos.z+1600.0f)/3200.0f; // 0..1
|
|
|
|
|
|
|
|
|
|
cx = (tu*254.0f*4.0f) - 0.5f;
|
|
|
|
|
cy = (tv*254.0f*4.0f) - 0.5f;
|
|
|
|
|
|
|
|
|
|
if (dot == 0)
|
|
|
|
|
{
|
|
|
|
|
cx += 0.5f;
|
|
|
|
|
cy += 0.5f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
px = cx-Math::Mod(cx, 1.0f);
|
|
|
|
|
py = cy-Math::Mod(cy, 1.0f); // multiple of 1
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (px+dot < min.x || py+dot < min.y ||
|
|
|
|
|
px-dot > max.x || py-dot > max.y)
|
|
|
|
|
continue;
|
2012-10-20 14:34:22 +00:00
|
|
|
|
|
|
|
|
|
for (int iy = -dot; iy <= dot; iy++)
|
|
|
|
|
{
|
|
|
|
|
for (int ix =- dot; ix <= dot; ix++)
|
|
|
|
|
{
|
|
|
|
|
float ppx = px+ix;
|
|
|
|
|
float ppy = py+iy;
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (ppx < min.x || ppy < min.y ||
|
|
|
|
|
ppx >= max.x || ppy >= max.y)
|
|
|
|
|
continue;
|
2012-10-20 14:34:22 +00:00
|
|
|
|
|
|
|
|
|
float intensity;
|
|
|
|
|
if (dot == 0)
|
|
|
|
|
intensity = 0.0f;
|
|
|
|
|
else
|
|
|
|
|
intensity = Math::Point(ppx-cx, ppy-cy).Length()/dot;
|
|
|
|
|
|
|
|
|
|
Gfx::Color color;
|
|
|
|
|
color.r = Math::Norm(m_groundSpots[i].color.r+intensity);
|
|
|
|
|
color.g = Math::Norm(m_groundSpots[i].color.g+intensity);
|
|
|
|
|
color.b = Math::Norm(m_groundSpots[i].color.b+intensity);
|
|
|
|
|
|
|
|
|
|
ppx -= min.x; // on the texture
|
|
|
|
|
ppy -= min.y;
|
|
|
|
|
|
|
|
|
|
shadowImg.SetPixel(Math::IntPoint(ppx, ppy), color);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int iy = 0; iy < 256; iy++)
|
|
|
|
|
{
|
|
|
|
|
for (int ix = 0; ix < 256; ix++)
|
|
|
|
|
{
|
|
|
|
|
Math::Vector pos;
|
|
|
|
|
pos.x = (256.0f * (s%4) + ix) * 3200.0f/1024.0f - 1600.0f;
|
|
|
|
|
pos.z = (256.0f * (s/4) + iy) * 3200.0f/1024.0f - 1600.0f;
|
|
|
|
|
pos.y = 0.0f;
|
|
|
|
|
|
|
|
|
|
float level = m_terrain->GetFloorLevel(pos, true);
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (level < m_groundSpots[i].min ||
|
|
|
|
|
level > m_groundSpots[i].max)
|
|
|
|
|
continue;
|
2012-10-20 14:34:22 +00:00
|
|
|
|
|
|
|
|
|
float intensity;
|
|
|
|
|
if (level > (m_groundSpots[i].max+m_groundSpots[i].min)/2.0f)
|
|
|
|
|
intensity = 1.0f - (m_groundSpots[i].max-level) / m_groundSpots[i].smooth;
|
|
|
|
|
else
|
|
|
|
|
intensity = 1.0f - (level-m_groundSpots[i].min) / m_groundSpots[i].smooth;
|
|
|
|
|
|
|
|
|
|
if (intensity < 0.0f) intensity = 0.0f;
|
|
|
|
|
|
|
|
|
|
Gfx::Color color;
|
|
|
|
|
color.r = Math::Norm(m_groundSpots[i].color.r+intensity);
|
|
|
|
|
color.g = Math::Norm(m_groundSpots[i].color.g+intensity);
|
|
|
|
|
color.b = Math::Norm(m_groundSpots[i].color.b+intensity);
|
|
|
|
|
|
|
|
|
|
shadowImg.SetPixel(Math::IntPoint(ix, iy), color);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (set)
|
|
|
|
|
{
|
|
|
|
|
dot = static_cast<int>(m_groundMark.radius/2.0f);
|
|
|
|
|
|
|
|
|
|
tu = (m_groundMark.pos.x + 1600.0f) / 3200.0f;
|
|
|
|
|
tv = (m_groundMark.pos.z + 1600.0f) / 3200.0f; // 0..1
|
|
|
|
|
|
|
|
|
|
cx = (tu*254.0f*4.0f)-0.5f;
|
|
|
|
|
cy = (tv*254.0f*4.0f)-0.5f;
|
|
|
|
|
|
|
|
|
|
if (dot == 0)
|
|
|
|
|
{
|
|
|
|
|
cx += 0.5f;
|
|
|
|
|
cy += 0.5f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
px = cx-Math::Mod(cx, 1.0f);
|
|
|
|
|
py = cy-Math::Mod(cy, 1.0f); // multiple of 1
|
|
|
|
|
|
|
|
|
|
for (int iy = -dot; iy <= dot; iy++)
|
|
|
|
|
{
|
|
|
|
|
for (int ix = -dot; ix <= dot; ix++)
|
|
|
|
|
{
|
|
|
|
|
float ppx = px+ix;
|
|
|
|
|
float ppy = py+iy;
|
|
|
|
|
|
|
|
|
|
if (ppx < min.x || ppy < min.y ||
|
2012-12-26 19:58:02 +00:00
|
|
|
|
ppx >= max.x || ppy >= max.y)
|
|
|
|
|
continue;
|
2012-10-20 14:34:22 +00:00
|
|
|
|
|
|
|
|
|
ppx -= min.x; // on the texture
|
|
|
|
|
ppy -= min.y;
|
|
|
|
|
|
|
|
|
|
float intensity = 1.0f - Math::Point(ix, iy).Length() / dot;
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (intensity <= 0.0f)
|
|
|
|
|
continue;
|
|
|
|
|
|
2012-10-20 14:34:22 +00:00
|
|
|
|
intensity *= m_groundMark.intensity;
|
|
|
|
|
|
|
|
|
|
int j = (ix+dot) + (iy+dot) * m_groundMark.dx;
|
|
|
|
|
if (m_groundMark.table[j] == 1) // green ?
|
|
|
|
|
{
|
|
|
|
|
Gfx::Color color;
|
|
|
|
|
color.r = Math::Norm(1.0f-intensity);
|
|
|
|
|
color.g = 1.0f;
|
|
|
|
|
color.b = Math::Norm(1.0f-intensity);
|
|
|
|
|
shadowImg.SetPixel(Math::IntPoint(ppx, ppy), color);
|
|
|
|
|
}
|
|
|
|
|
if (m_groundMark.table[j] == 2) // red ?
|
|
|
|
|
{
|
|
|
|
|
Gfx::Color color;
|
|
|
|
|
color.r = 1.0f;
|
|
|
|
|
color.g = Math::Norm(1.0f-intensity);
|
|
|
|
|
color.b = Math::Norm(1.0f-intensity);
|
|
|
|
|
shadowImg.SetPixel(Math::IntPoint(ppx, ppy), color);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::stringstream str;
|
2014-07-24 20:17:49 +00:00
|
|
|
|
str << "textures/shadow" << std::setfill('0') << std::setw(2) << s << ".png";
|
2012-10-20 14:34:22 +00:00
|
|
|
|
std::string texName = str.str();
|
|
|
|
|
|
|
|
|
|
DeleteTexture(texName);
|
|
|
|
|
|
|
|
|
|
Gfx::Texture tex = m_device->CreateTexture(&shadowImg, m_defaultTexParams);
|
|
|
|
|
|
|
|
|
|
m_texNameMap[texName] = tex;
|
|
|
|
|
m_revTexNameMap[tex] = texName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < static_cast<int>( m_groundSpots.size() ); i++)
|
|
|
|
|
{
|
|
|
|
|
if (m_groundSpots[i].used == false ||
|
|
|
|
|
m_groundSpots[i].radius == 0.0f)
|
|
|
|
|
{
|
|
|
|
|
m_groundSpots[i].drawRadius = 0.0f;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_groundSpots[i].drawPos = m_groundSpots[i].pos;
|
|
|
|
|
m_groundSpots[i].drawRadius = m_groundSpots[i].radius;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_groundMark.drawPos = m_groundMark.pos;
|
|
|
|
|
m_groundMark.drawRadius = m_groundMark.radius;
|
|
|
|
|
m_groundMark.drawIntensity = m_groundMark.intensity;
|
|
|
|
|
|
|
|
|
|
m_firstGroundSpot = false;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DrawShadow()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
Math::Matrix matrix;
|
|
|
|
|
matrix.LoadIdentity();
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, matrix);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Material material;
|
|
|
|
|
material.diffuse = Color(1.0f, 1.0f, 1.0f);
|
|
|
|
|
material.ambient = Color(0.5f, 0.5f, 0.5f);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
SetMaterial(material);
|
|
|
|
|
|
2012-08-12 08:45:04 +00:00
|
|
|
|
// TODO: create a separate texture
|
2014-07-24 20:17:49 +00:00
|
|
|
|
SetTexture("textures/interface/text.png");
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
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;
|
2012-08-11 15:17:04 +00:00
|
|
|
|
for (int i = 0; i < static_cast<int>( m_shadows.size() ); i++)
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2013-04-29 10:51:37 +00:00
|
|
|
|
if (m_shadows[i].hide || !m_shadows[i].used)
|
2012-12-26 19:58:02 +00:00
|
|
|
|
continue;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-08-11 15:17:04 +00:00
|
|
|
|
Math::Vector pos = m_shadows[i].pos; // pos = center of the shadow on the ground
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (m_eyePt.y == pos.y)
|
|
|
|
|
continue; // camera at the same level?
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
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;
|
2012-08-11 15:17:04 +00:00
|
|
|
|
float h = m_shadows[i].radius;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
float max = height*0.5f;
|
|
|
|
|
if ( h > max ) h = max;
|
|
|
|
|
if ( h > 4.0f ) h = 4.0f;
|
|
|
|
|
|
|
|
|
|
D = Math::Distance(m_eyePt, pos);
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (D >= endDeepView)
|
|
|
|
|
continue;
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
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;
|
2012-08-11 15:17:04 +00:00
|
|
|
|
float h = m_shadows[i].radius;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
float max = height*0.1f;
|
|
|
|
|
if ( h > max ) h = max;
|
|
|
|
|
if ( h > 4.0f ) h = 4.0f;
|
|
|
|
|
|
|
|
|
|
D = Math::Distance(m_eyePt, pos);
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (D >= endDeepView)
|
|
|
|
|
continue;
|
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
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.
|
2012-08-11 15:17:04 +00:00
|
|
|
|
float hFactor = m_shadows[i].height/20.0f;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2012-08-11 15:17:04 +00:00
|
|
|
|
float radius = m_shadows[i].radius*1.5f;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
radius *= 2.0f-hFactor; // greater if high
|
|
|
|
|
radius *= 1.0f-d/D; // smaller if close
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Math::Vector corner[4];
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
if (m_shadows[i].type == ENG_SHADOW_NORM)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
2012-08-11 15:17:04 +00:00
|
|
|
|
rot = Math::RotatePoint(-m_shadows[i].angle, Math::Point(radius, radius));
|
2012-08-10 21:31:42 +00:00
|
|
|
|
corner[0].x = rot.x;
|
|
|
|
|
corner[0].z = rot.y;
|
|
|
|
|
corner[0].y = 0.0f;
|
|
|
|
|
|
2012-08-11 15:17:04 +00:00
|
|
|
|
rot = Math::RotatePoint(-m_shadows[i].angle, Math::Point(-radius, radius));
|
2012-08-10 21:31:42 +00:00
|
|
|
|
corner[1].x = rot.x;
|
|
|
|
|
corner[1].z = rot.y;
|
|
|
|
|
corner[1].y = 0.0f;
|
|
|
|
|
|
2012-08-11 15:17:04 +00:00
|
|
|
|
rot = Math::RotatePoint(-m_shadows[i].angle, Math::Point(radius, -radius));
|
2012-08-10 21:31:42 +00:00
|
|
|
|
corner[2].x = rot.x;
|
|
|
|
|
corner[2].z = rot.y;
|
|
|
|
|
corner[2].y = 0.0f;
|
|
|
|
|
|
2012-08-11 15:17:04 +00:00
|
|
|
|
rot = Math::RotatePoint(-m_shadows[i].angle, Math::Point(-radius, -radius));
|
2012-08-10 21:31:42 +00:00
|
|
|
|
corner[3].x = rot.x;
|
|
|
|
|
corner[3].z = rot.y;
|
|
|
|
|
corner[3].y = 0.0f;
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
if (m_shadows[i].type == ENG_SHADOW_WORM)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-08-11 15:17:04 +00:00
|
|
|
|
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);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
corner[0] += pos;
|
|
|
|
|
corner[1] += pos;
|
|
|
|
|
corner[2] += pos;
|
|
|
|
|
corner[3] += pos;
|
|
|
|
|
|
|
|
|
|
ts.x += dp;
|
|
|
|
|
ti.x -= dp;
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Vertex vertex[4] =
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Vertex(corner[1], n, Math::Point(ts.x, ts.y)),
|
|
|
|
|
Vertex(corner[0], n, Math::Point(ti.x, ts.y)),
|
|
|
|
|
Vertex(corner[3], n, Math::Point(ts.x, ti.y)),
|
|
|
|
|
Vertex(corner[2], n, Math::Point(ti.x, ti.y))
|
2012-08-10 21:31:42 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-08-11 15:17:04 +00:00
|
|
|
|
float intensity = (0.5f+m_shadows[i].intensity*0.5f)*hFactor;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (intensity == 0.0f)
|
|
|
|
|
continue;
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
if (lastIntensity != intensity) // intensity changed?
|
|
|
|
|
{
|
|
|
|
|
lastIntensity = intensity;
|
2012-09-19 21:50:28 +00:00
|
|
|
|
SetState(ENG_RSTATE_TTEXTURE_WHITE, Color(intensity, intensity, intensity, intensity));
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
AddStatisticTriangle(2);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, true);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, true);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DrawBackground()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
if (m_skyMode && m_cloud->GetLevel() != 0.0f) // clouds ?
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2012-08-10 21:31:42 +00:00
|
|
|
|
if (m_backgroundCloudUp != m_backgroundCloudDown) // degraded?
|
|
|
|
|
DrawBackgroundGradient(m_backgroundCloudUp, m_backgroundCloudDown);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2012-08-10 21:31:42 +00:00
|
|
|
|
if (m_backgroundColorUp != m_backgroundColorDown) // degraded?
|
|
|
|
|
DrawBackgroundGradient(m_backgroundColorUp, m_backgroundColorDown);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-08-12 08:45:04 +00:00
|
|
|
|
if (m_backForce || (m_skyMode && !m_backgroundName.empty()) )
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2012-08-10 21:31:42 +00:00
|
|
|
|
DrawBackgroundImage(); // image
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
2012-08-10 21:31:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DrawBackgroundGradient(const Color& up, const Color& down)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
Math::Point p1(0.0f, 0.5f);
|
|
|
|
|
Math::Point p2(1.0f, 1.0f);
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Color color[3] =
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2012-08-10 21:31:42 +00:00
|
|
|
|
up,
|
|
|
|
|
down,
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Color(0.0f, 0.0f, 0.0f, 0.0f)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
SetState(ENG_RSTATE_OPAQUE_COLOR);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
VertexCol vertex[4] =
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2012-09-26 14:31:04 +00:00
|
|
|
|
VertexCol(Math::Vector(p1.x, p1.y, 0.0f), color[1]),
|
|
|
|
|
VertexCol(Math::Vector(p1.x, p2.y, 0.0f), color[0]),
|
|
|
|
|
VertexCol(Math::Vector(p2.x, p1.y, 0.0f), color[1]),
|
|
|
|
|
VertexCol(Math::Vector(p2.x, p2.y, 0.0f), color[0])
|
2012-08-10 21:31:42 +00:00
|
|
|
|
};
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
AddStatisticTriangle(2);
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DrawBackgroundImage()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-17 21:41:53 +00:00
|
|
|
|
Math::Point p1, p2;
|
|
|
|
|
p1.x = 0.0f;
|
|
|
|
|
p1.y = 0.0f;
|
|
|
|
|
p2.x = 1.0f;
|
|
|
|
|
p2.y = 1.0f;
|
|
|
|
|
|
2012-10-19 20:37:11 +00:00
|
|
|
|
Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
|
|
|
|
float u1, u2, v1, v2;
|
|
|
|
|
if (m_backgroundFull)
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2012-08-10 21:31:42 +00:00
|
|
|
|
u1 = 0.0f;
|
|
|
|
|
v1 = 0.0f;
|
|
|
|
|
u2 = 1.0f;
|
|
|
|
|
v2 = 1.0f;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2012-08-10 21:31:42 +00:00
|
|
|
|
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;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2013-05-11 21:05:20 +00:00
|
|
|
|
Math::Point backgroundScale;
|
|
|
|
|
backgroundScale.x = static_cast<float>(m_backgroundTex.originalSize.x) / static_cast<float>(m_backgroundTex.size.x);
|
|
|
|
|
backgroundScale.y = static_cast<float>(m_backgroundTex.originalSize.y) / static_cast<float>(m_backgroundTex.size.y);
|
|
|
|
|
|
|
|
|
|
u2 *= backgroundScale.x;
|
|
|
|
|
v2 *= backgroundScale.y;
|
2012-09-17 21:41:53 +00:00
|
|
|
|
|
|
|
|
|
SetTexture(m_backgroundTex);
|
2012-09-19 21:50:28 +00:00
|
|
|
|
SetState(ENG_RSTATE_OPAQUE_TEXTURE | ENG_RSTATE_WRAP);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Vertex vertex[4] =
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(u1, v2)),
|
|
|
|
|
Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(u1, v1)),
|
|
|
|
|
Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(u2, v2)),
|
|
|
|
|
Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(u2, v1))
|
2012-08-10 21:31:42 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
AddStatisticTriangle(2);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DrawPlanet()
|
2012-07-01 20:59:22 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (! m_planet->PlanetExist())
|
|
|
|
|
return;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetRenderState(RENDER_STATE_DEPTH_WRITE, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_LIGHTING, false);
|
|
|
|
|
m_device->SetRenderState(RENDER_STATE_FOG, false);
|
2012-07-23 19:41:27 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
2012-07-01 20:59:22 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
m_planet->Draw(); // draws the planets
|
|
|
|
|
}
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DrawForegroundImage()
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if (m_foregroundName.empty())
|
|
|
|
|
return;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
Math::Vector n = Math::Vector(0.0f, 0.0f, -1.0f); // normal
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
Math::Point p1(0.0f, 0.0f);
|
|
|
|
|
Math::Point p2(1.0f, 1.0f);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
float u1 = -m_eyeDirH/(Math::PI*0.6f)+Math::PI*0.5f;
|
|
|
|
|
float u2 = u1+0.50f;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
float v1 = 0.2f;
|
|
|
|
|
float v2 = 1.0f;
|
2012-07-01 20:59:22 +00:00
|
|
|
|
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Vertex vertex[4] =
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Vertex(Math::Vector(p1.x, p1.y, 0.0f), n, Math::Point(u1, v2)),
|
|
|
|
|
Vertex(Math::Vector(p1.x, p2.y, 0.0f), n, Math::Point(u1, v1)),
|
|
|
|
|
Vertex(Math::Vector(p2.x, p1.y, 0.0f), n, Math::Point(u2, v2)),
|
|
|
|
|
Vertex(Math::Vector(p2.x, p2.y, 0.0f), n, Math::Point(u2, v1))
|
2012-08-10 21:31:42 +00:00
|
|
|
|
};
|
2012-07-01 20:59:22 +00:00
|
|
|
|
|
2012-08-12 17:28:22 +00:00
|
|
|
|
SetTexture(m_foregroundTex);
|
2012-09-19 21:50:28 +00:00
|
|
|
|
SetState(ENG_RSTATE_CLAMP | ENG_RSTATE_TTEXTURE_BLACK);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
AddStatisticTriangle(2);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DrawOverColor()
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2012-12-26 19:58:02 +00:00
|
|
|
|
if ((m_overColor == Color(0.0f, 0.0f, 0.0f, 0.0f) && m_overMode == ENG_RSTATE_TCOLOR_BLACK) ||
|
|
|
|
|
(m_overColor == Color(1.0f, 1.0f, 1.0f, 1.0f) && m_overMode == ENG_RSTATE_TCOLOR_WHITE))
|
|
|
|
|
return;
|
2012-07-01 20:59:22 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
Math::Point p1(0.0f, 0.0f);
|
|
|
|
|
Math::Point p2(1.0f, 1.0f);
|
2012-08-06 18:20:50 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Color color[3] =
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
|
|
|
|
m_overColor,
|
|
|
|
|
m_overColor,
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Color(0.0f, 0.0f, 0.0f, 0.0f)
|
2012-08-10 21:31:42 +00:00
|
|
|
|
};
|
2012-08-03 21:23:13 +00:00
|
|
|
|
|
2012-08-12 08:45:04 +00:00
|
|
|
|
SetState(m_overMode);
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->SetTransform(TRANSFORM_VIEW, m_matViewInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_PROJECTION, m_matProjInterface);
|
|
|
|
|
m_device->SetTransform(TRANSFORM_WORLD, m_matWorldInterface);
|
2012-08-06 18:20:50 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
VertexCol vertex[4] =
|
2012-08-10 21:31:42 +00:00
|
|
|
|
{
|
2012-09-26 14:31:04 +00:00
|
|
|
|
VertexCol(Math::Vector(p1.x, p1.y, 0.0f), color[1]),
|
|
|
|
|
VertexCol(Math::Vector(p1.x, p2.y, 0.0f), color[0]),
|
|
|
|
|
VertexCol(Math::Vector(p2.x, p1.y, 0.0f), color[1]),
|
|
|
|
|
VertexCol(Math::Vector(p2.x, p2.y, 0.0f), color[0])
|
2012-08-10 21:31:42 +00:00
|
|
|
|
};
|
2012-08-03 21:23:13 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
|
2012-08-10 21:31:42 +00:00
|
|
|
|
AddStatisticTriangle(2);
|
2012-08-03 21:23:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DrawHighlight()
|
2012-08-03 21:23:13 +00:00
|
|
|
|
{
|
2012-08-10 21:31:42 +00:00
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-08-03 21:23:13 +00:00
|
|
|
|
|
2012-08-10 21:31:42 +00:00
|
|
|
|
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;
|
|
|
|
|
}
|
2012-08-03 21:23:13 +00:00
|
|
|
|
|
2012-08-12 08:45:04 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
SetState(ENG_RSTATE_OPAQUE_COLOR);
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Color color(1.0f, 1.0f, 0.0f); // yellow
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
VertexCol line[3] =
|
2012-08-12 08:45:04 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
VertexCol(Math::Vector(), color),
|
|
|
|
|
VertexCol(Math::Vector(), color),
|
|
|
|
|
VertexCol(Math::Vector(), color)
|
2012-08-12 08:45:04 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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);
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_LINE_STRIP, line, 3);
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
|
|
|
|
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);
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_LINE_STRIP, line, 3);
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
|
|
|
|
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);
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_LINE_STRIP, line, 3);
|
2012-08-12 08:45:04 +00:00
|
|
|
|
|
|
|
|
|
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);
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_LINE_STRIP, line, 3);
|
2012-08-08 19:32:44 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DrawMouse()
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2012-09-20 18:37:37 +00:00
|
|
|
|
MouseMode mode = m_app->GetMouseMode();
|
|
|
|
|
if (mode != MOUSE_ENGINE && mode != MOUSE_BOTH)
|
2012-07-22 20:05:12 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Material material;
|
|
|
|
|
material.diffuse = Color(1.0f, 1.0f, 1.0f);
|
|
|
|
|
material.ambient = Color(0.5f, 0.5f, 0.5f);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-07-24 22:27:01 +00:00
|
|
|
|
m_device->SetMaterial(material);
|
|
|
|
|
m_device->SetTexture(0, m_miceTexture);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-07-23 19:41:27 +00:00
|
|
|
|
int index = static_cast<int>(m_mouseType);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2014-12-11 18:01:57 +00:00
|
|
|
|
Math::Point pos = CInput::GetInstancePointer()->GetMousePos();
|
2012-09-20 18:37:37 +00:00
|
|
|
|
pos.x = pos.x - (m_mice[index].hotPoint.x * m_mouseSize.x) / 32.0f;
|
|
|
|
|
pos.y = pos.y - ((32.0f - m_mice[index].hotPoint.y) * m_mouseSize.y) / 32.0f;
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-07-23 19:41:27 +00:00
|
|
|
|
Math::Point shadowPos;
|
|
|
|
|
shadowPos.x = pos.x + (4.0f/800.0f);
|
|
|
|
|
shadowPos.y = pos.y - (3.0f/600.0f);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
SetState(ENG_RSTATE_TCOLOR_WHITE);
|
2012-07-23 19:41:27 +00:00
|
|
|
|
DrawMouseSprite(shadowPos, m_mouseSize, m_mice[index].iconShadow);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-07-23 19:41:27 +00:00
|
|
|
|
SetState(m_mice[index].mode1);
|
|
|
|
|
DrawMouseSprite(pos, m_mouseSize, m_mice[index].icon1);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
2012-07-23 19:41:27 +00:00
|
|
|
|
SetState(m_mice[index].mode2);
|
|
|
|
|
DrawMouseSprite(pos, m_mouseSize, m_mice[index].icon2);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
void CEngine::DrawMouseSprite(Math::Point pos, Math::Point size, int icon)
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
|
|
|
|
if (icon == -1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Math::Point p1 = pos;
|
|
|
|
|
Math::Point p2 = p1 + size;
|
|
|
|
|
|
|
|
|
|
float u1 = (32.0f / 256.0f) * (icon % 8);
|
|
|
|
|
float v1 = (32.0f / 256.0f) * (icon / 8);
|
2012-07-23 19:41:27 +00:00
|
|
|
|
float u2 = u1 + (32.0f / 256.0f);
|
|
|
|
|
float v2 = v1 + (32.0f / 256.0f);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
|
|
|
|
|
float dp = 0.5f / 256.0f;
|
|
|
|
|
u1 += dp;
|
|
|
|
|
v1 += dp;
|
|
|
|
|
u2 -= dp;
|
|
|
|
|
v2 -= dp;
|
|
|
|
|
|
|
|
|
|
Math::Vector normal(0.0f, 0.0f, -1.0f);
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Vertex vertex[4] =
|
2012-07-22 20:05:12 +00:00
|
|
|
|
{
|
2012-09-19 21:50:28 +00:00
|
|
|
|
Vertex(Math::Vector(p1.x, p1.y, 0.0f), normal, Math::Point(u1, v2)),
|
|
|
|
|
Vertex(Math::Vector(p1.x, p2.y, 0.0f), normal, Math::Point(u1, v1)),
|
|
|
|
|
Vertex(Math::Vector(p2.x, p1.y, 0.0f), normal, Math::Point(u2, v2)),
|
|
|
|
|
Vertex(Math::Vector(p2.x, p2.y, 0.0f), normal, Math::Point(u2, v1))
|
2012-07-22 20:05:12 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
|
2012-07-22 20:05:12 +00:00
|
|
|
|
AddStatisticTriangle(2);
|
|
|
|
|
}
|
2012-09-19 21:50:28 +00:00
|
|
|
|
|
2012-09-20 18:37:37 +00:00
|
|
|
|
void CEngine::DrawStats()
|
|
|
|
|
{
|
|
|
|
|
if (!m_showStats)
|
|
|
|
|
return;
|
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
float height = m_text->GetAscent(FONT_COLOBOT, 13.0f);
|
|
|
|
|
float width = 0.25f;
|
2012-09-20 18:37:37 +00:00
|
|
|
|
|
2014-01-11 16:51:13 +00:00
|
|
|
|
Math::Point pos(0.04f, 0.04f + 20 * height);
|
2012-09-20 18:37:37 +00:00
|
|
|
|
|
|
|
|
|
SetState(ENG_RSTATE_OPAQUE_COLOR);
|
|
|
|
|
|
|
|
|
|
Gfx::Color black(0.0f, 0.0f, 0.0f, 0.0f);
|
|
|
|
|
|
|
|
|
|
VertexCol vertex[4] =
|
|
|
|
|
{
|
2014-01-11 16:51:13 +00:00
|
|
|
|
VertexCol(Math::Vector(pos.x , pos.y - 20 * height, 0.0f), black),
|
2012-09-20 18:37:37 +00:00
|
|
|
|
VertexCol(Math::Vector(pos.x , pos.y + height, 0.0f), black),
|
2014-01-11 16:51:13 +00:00
|
|
|
|
VertexCol(Math::Vector(pos.x + width, pos.y - 20 * height, 0.0f), black),
|
2012-09-20 18:37:37 +00:00
|
|
|
|
VertexCol(Math::Vector(pos.x + width, pos.y + height, 0.0f), black)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
m_device->DrawPrimitive(PRIMITIVE_TRIANGLE_STRIP, vertex, 4);
|
|
|
|
|
|
|
|
|
|
SetState(ENG_RSTATE_TEXT);
|
|
|
|
|
|
2012-10-25 21:29:49 +00:00
|
|
|
|
std::stringstream str;
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Event processing: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_EVENT_PROCESSING);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Frame update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_ALL);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Engine update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_ENGINE);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Particle update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_PARTICLE);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Game update: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_UPDATE_GAME);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
float otherUpdate = Math::Max(0.0f, m_app->GetPerformanceCounterData(PCNT_UPDATE_ALL) -
|
|
|
|
|
m_app->GetPerformanceCounterData(PCNT_UPDATE_ENGINE) -
|
|
|
|
|
m_app->GetPerformanceCounterData(PCNT_UPDATE_PARTICLE) -
|
|
|
|
|
m_app->GetPerformanceCounterData(PCNT_UPDATE_GAME));
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Other update: " << std::fixed << std::setprecision(2) << otherUpdate;
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Frame render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_ALL);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Particle render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_PARTICLE);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Water render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_WATER);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Terrain render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_TERRAIN);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Objects render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_OBJECTS);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "UI render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_INTERFACE);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
2015-05-11 13:21:17 +00:00
|
|
|
|
str.str("");
|
|
|
|
|
str << "Shadow map render: " << std::fixed << std::setprecision(2) << m_app->GetPerformanceCounterData(PCNT_RENDER_SHADOW_MAP);
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
2012-10-25 21:29:49 +00:00
|
|
|
|
float otherRender = m_app->GetPerformanceCounterData(PCNT_RENDER_ALL) -
|
|
|
|
|
m_app->GetPerformanceCounterData(PCNT_RENDER_PARTICLE) -
|
|
|
|
|
m_app->GetPerformanceCounterData(PCNT_RENDER_WATER) -
|
|
|
|
|
m_app->GetPerformanceCounterData(PCNT_RENDER_TERRAIN) -
|
|
|
|
|
m_app->GetPerformanceCounterData(PCNT_RENDER_OBJECTS) -
|
2015-05-11 13:21:17 +00:00
|
|
|
|
m_app->GetPerformanceCounterData(PCNT_RENDER_INTERFACE) -
|
|
|
|
|
m_app->GetPerformanceCounterData(PCNT_RENDER_SHADOW_MAP);
|
2012-10-25 21:29:49 +00:00
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Other render: " << std::fixed << std::setprecision(2) << otherRender;
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Triangles: " << m_statisticTriangle;
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
2012-09-20 18:37:37 +00:00
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
2012-09-30 08:56:35 +00:00
|
|
|
|
m_text->DrawText(m_fpsText, FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
2014-01-11 16:51:13 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Position x: " << std::fixed << std::setprecision(2) << m_statisticPos.x/g_unit;
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
|
|
|
|
|
pos.y -= height;
|
|
|
|
|
|
|
|
|
|
str.str("");
|
|
|
|
|
str << "Position y: " << std::fixed << std::setprecision(2) << m_statisticPos.z/g_unit;
|
|
|
|
|
m_text->DrawText(str.str(), FONT_COLOBOT, 12.0f, pos, 1.0f, TEXT_ALIGN_LEFT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
2012-09-20 18:37:37 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-10-29 16:53:46 +00:00
|
|
|
|
void CEngine::DrawTimer()
|
|
|
|
|
{
|
|
|
|
|
SetState(ENG_RSTATE_TEXT);
|
|
|
|
|
|
|
|
|
|
Math::Point pos(0.98f, 0.98f-m_text->GetAscent(FONT_COLOBOT, 15.0f));
|
|
|
|
|
m_text->DrawText(m_timerText, FONT_COLOBOT, 15.0f, pos, 1.0f, TEXT_ALIGN_RIGHT, 0, Color(1.0f, 1.0f, 1.0f, 1.0f));
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-19 21:50:28 +00:00
|
|
|
|
|
|
|
|
|
} // namespace Gfx
|
2013-05-26 15:47:54 +00:00
|
|
|
|
|