mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
texture garbage collection, removed fixed binding with world camera in world render, cap on minimal volume held by reservoirs
This commit is contained in:
139
DynObj.cpp
139
DynObj.cpp
@@ -989,12 +989,6 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
}
|
||||
// ABu 29.01.05 koniec przeklejenia *************************************
|
||||
|
||||
double ABuAcos(const vector3 &calc_temp)
|
||||
{ // Odpowiednik funkcji Arccos, bo cos
|
||||
// mi tam nie dzialalo.
|
||||
return atan2(-calc_temp.x, calc_temp.z); // Ra: tak prościej
|
||||
}
|
||||
|
||||
TDynamicObject * TDynamicObject::ABuFindNearestObject(TTrack *Track, TDynamicObject *MyPointer, int &CouplNr)
|
||||
{
|
||||
// zwraca wskaznik do obiektu znajdujacego sie na torze (Track), którego sprzęg jest najblizszy kamerze
|
||||
@@ -4056,8 +4050,9 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
std::size_t i = asModel.find( ',' );
|
||||
if ( i != std::string::npos )
|
||||
{ // Ra 2015-01: może szukać przecinka w nazwie modelu, a po przecinku była by liczba tekstur?
|
||||
if (i < asModel.length())
|
||||
m_materialdata.multi_textures = asModel[i + 1] - '0';
|
||||
if( i < asModel.length() ) {
|
||||
m_materialdata.multi_textures = asModel[ i + 1 ] - '0';
|
||||
}
|
||||
m_materialdata.multi_textures = clamp( m_materialdata.multi_textures, 0, 1 ); // na razie ustawiamy na 1
|
||||
}
|
||||
asModel = BaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje
|
||||
@@ -4092,7 +4087,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
int skinindex = 0;
|
||||
do {
|
||||
texture_handle texture = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + ReplacableSkin + "," + std::to_string( skinindex + 1 ), "", Global::iDynamicFiltering, true );
|
||||
if( false == GfxRenderer.Texture( texture ).is_ready ) {
|
||||
if( texture == NULL ) {
|
||||
break;
|
||||
}
|
||||
m_materialdata.replacable_skins[ skinindex + 1 ] = texture;
|
||||
@@ -4105,61 +4100,72 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + ReplacableSkin, "", Global::iDynamicFiltering );
|
||||
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha )
|
||||
m_materialdata.textures_alpha = 0x31310031; // tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
else
|
||||
m_materialdata.textures_alpha = 0x30300030; // wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych
|
||||
if( m_materialdata.replacable_skins[ 2 ] )
|
||||
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 2 ] ).has_alpha )
|
||||
m_materialdata.textures_alpha |= 0x02020002; // tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
if( m_materialdata.replacable_skins[ 3 ] )
|
||||
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 3 ] ).has_alpha )
|
||||
m_materialdata.textures_alpha |= 0x04040004; // tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
if( m_materialdata.replacable_skins[ 4 ] )
|
||||
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 4 ] ).has_alpha )
|
||||
m_materialdata.textures_alpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
}
|
||||
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) {
|
||||
// tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
m_materialdata.textures_alpha = 0x31310031;
|
||||
}
|
||||
else {
|
||||
// wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych
|
||||
m_materialdata.textures_alpha = 0x30300030;
|
||||
}
|
||||
|
||||
if( ( m_materialdata.replacable_skins[ 2 ] )
|
||||
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 2 ] ).has_alpha ) ) {
|
||||
// tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
m_materialdata.textures_alpha |= 0x02020002;
|
||||
}
|
||||
if( ( m_materialdata.replacable_skins[ 3 ] )
|
||||
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 3 ] ).has_alpha ) ) {
|
||||
// tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
m_materialdata.textures_alpha |= 0x04040004;
|
||||
}
|
||||
if( ( m_materialdata.replacable_skins[ 4 ] )
|
||||
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 4 ] ).has_alpha ) ) {
|
||||
// tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
m_materialdata.textures_alpha |= 0x08080008;
|
||||
}
|
||||
}
|
||||
if (!MoverParameters->LoadAccepted.empty())
|
||||
// if (MoverParameters->LoadAccepted!=AnsiString("")); // &&
|
||||
// MoverParameters->LoadType!=AnsiString("passengers"))
|
||||
if (MoverParameters->EnginePowerSource.SourceType == CurrentCollector)
|
||||
{ // wartość niby "pantstate" - nazwa dla formalności, ważna jest ilość
|
||||
if (MoverParameters->Load == 1)
|
||||
MoverParameters->PantFront(true);
|
||||
else if (MoverParameters->Load == 2)
|
||||
MoverParameters->PantRear(true);
|
||||
else if (MoverParameters->Load == 3)
|
||||
{
|
||||
MoverParameters->PantFront(true);
|
||||
MoverParameters->PantRear(true);
|
||||
if( !MoverParameters->LoadAccepted.empty() ) {
|
||||
|
||||
if( MoverParameters->EnginePowerSource.SourceType == CurrentCollector ) {
|
||||
// wartość niby "pantstate" - nazwa dla formalności, ważna jest ilość
|
||||
if( MoverParameters->Load == 1 ) {
|
||||
MoverParameters->PantFront( true );
|
||||
}
|
||||
else if (MoverParameters->Load == 4)
|
||||
MoverParameters->DoubleTr = -1;
|
||||
else if (MoverParameters->Load == 5)
|
||||
{
|
||||
MoverParameters->DoubleTr = -1;
|
||||
MoverParameters->PantRear(true);
|
||||
else if( MoverParameters->Load == 2 ) {
|
||||
MoverParameters->PantRear( true );
|
||||
}
|
||||
else if (MoverParameters->Load == 6)
|
||||
{
|
||||
MoverParameters->DoubleTr = -1;
|
||||
MoverParameters->PantFront(true);
|
||||
else if( MoverParameters->Load == 3 ) {
|
||||
MoverParameters->PantFront( true );
|
||||
MoverParameters->PantRear( true );
|
||||
}
|
||||
else if (MoverParameters->Load == 7)
|
||||
{
|
||||
else if( MoverParameters->Load == 4 ) {
|
||||
MoverParameters->DoubleTr = -1;
|
||||
MoverParameters->PantFront(true);
|
||||
MoverParameters->PantRear(true);
|
||||
}
|
||||
else if( MoverParameters->Load == 5 ) {
|
||||
MoverParameters->DoubleTr = -1;
|
||||
MoverParameters->PantRear( true );
|
||||
}
|
||||
else if( MoverParameters->Load == 6 ) {
|
||||
MoverParameters->DoubleTr = -1;
|
||||
MoverParameters->PantFront( true );
|
||||
}
|
||||
else if( MoverParameters->Load == 7 ) {
|
||||
MoverParameters->DoubleTr = -1;
|
||||
MoverParameters->PantFront( true );
|
||||
MoverParameters->PantRear( true );
|
||||
}
|
||||
}
|
||||
else // Ra: tu wczytywanie modelu ładunku jest w porządku
|
||||
{
|
||||
else {
|
||||
// Ra: tu wczytywanie modelu ładunku jest w porządku
|
||||
if( false == asLoadName.empty() ) {
|
||||
mdLoad = TModelsManager::GetModel( asLoadName, true ); // ladunek
|
||||
}
|
||||
}
|
||||
}
|
||||
Global::asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur
|
||||
do {
|
||||
token = "";
|
||||
@@ -4198,11 +4204,9 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
}
|
||||
// WriteLog("Total animations: "+AnsiString(iAnimations));
|
||||
}
|
||||
/*
|
||||
if( nullptr == pAnimations )
|
||||
*/
|
||||
if( true == pAnimations.empty() )
|
||||
{ // Ra: tworzenie tabeli animacji, jeśli jeszcze nie było
|
||||
|
||||
if( true == pAnimations.empty() ) {
|
||||
// Ra: tworzenie tabeli animacji, jeśli jeszcze nie było
|
||||
/*
|
||||
// disabled as default animation amounts are no longer supported
|
||||
if( !iAnimations ) {
|
||||
@@ -4217,9 +4221,6 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
iAnimType[ANIM_PANTS]=0;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
pAnimations = new TAnim[iAnimations];
|
||||
*/
|
||||
pAnimations.resize( iAnimations );
|
||||
int i, j, k = 0, sm = 0;
|
||||
for (j = 0; j < ANIM_TYPES; ++j)
|
||||
@@ -4229,9 +4230,6 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
if (!pants)
|
||||
if (iAnimType[ANIM_PANTS]) // o ile jakieś pantografy są (a domyślnie są)
|
||||
pants = &pAnimations[k]; // zapamiętanie na potrzeby wyszukania submodeli
|
||||
/*
|
||||
pants = pAnimations + k; // zapamiętanie na potrzeby wyszukania submodeli
|
||||
*/
|
||||
pAnimations[k].iShift = sm; // przesunięcie do przydzielenia wskaźnika
|
||||
sm += pAnimations[k++].TypeSet(j); // ustawienie typu animacji i zliczanie tablicowanych submodeli
|
||||
}
|
||||
@@ -4281,8 +4279,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
if (pAnimations[i].smAnimated)
|
||||
{ //++iAnimatedAxles;
|
||||
pAnimations[i].smAnimated->WillBeAnimated(); // wyłączenie optymalizacji transformu
|
||||
/* pAnimations[i].yUpdate = UpdateAxle; // animacja osi
|
||||
*/ pAnimations[ i ].yUpdate = std::bind( &TDynamicObject::UpdateAxle, this, std::placeholders::_1 );
|
||||
pAnimations[i].yUpdate = std::bind( &TDynamicObject::UpdateAxle, this, std::placeholders::_1 );
|
||||
pAnimations[i].fMaxDist = 50 * MoverParameters->WheelDiameter; // nie kręcić w większej odległości
|
||||
pAnimations[i].fMaxDist *= pAnimations[i].fMaxDist * MoverParameters->WheelDiameter; // 50m do kwadratu, a średnica do trzeciej
|
||||
pAnimations[i].fMaxDist *= Global::fDistanceFactor; // współczynnik przeliczeniowy jakości ekranu
|
||||
@@ -4671,20 +4668,16 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
switch (MoverParameters->DoorOpenMethod)
|
||||
{ // od razu zapinamy potrzebny typ animacji
|
||||
case 1:
|
||||
/* pAnimations[i + j].yUpdate = UpdateDoorTranslate;
|
||||
*/ pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorTranslate, this, std::placeholders::_1 );
|
||||
pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorTranslate, this, std::placeholders::_1 );
|
||||
break;
|
||||
case 2:
|
||||
/* pAnimations[i + j].yUpdate = UpdateDoorRotate;
|
||||
*/ pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorRotate, this, std::placeholders::_1 );
|
||||
pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorRotate, this, std::placeholders::_1 );
|
||||
break;
|
||||
case 3:
|
||||
/* pAnimations[i + j].yUpdate = UpdateDoorFold;
|
||||
*/ pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorFold, this, std::placeholders::_1 );
|
||||
pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorFold, this, std::placeholders::_1 );
|
||||
break; // obrót 3 kolejnych submodeli
|
||||
case 4:
|
||||
/* pAnimations[i + j].yUpdate = UpdateDoorPlug;
|
||||
*/ pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorPlug, this, std::placeholders::_1 );
|
||||
pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorPlug, this, std::placeholders::_1 );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -113,17 +113,18 @@ double PFVd( double PH, double PL, double const S, double LIM, double const DP )
|
||||
if (LIM < PH)
|
||||
{
|
||||
LIM = LIM + 1;
|
||||
PH = PH + 1; // wyzsze cisnienie absolutne
|
||||
PL = PL + 1; // nizsze cisnienie absolutne
|
||||
PH = PH + 1.0; // wyzsze cisnienie absolutne
|
||||
PL = PL + 1.0; // nizsze cisnienie absolutne
|
||||
assert( PH != PL );
|
||||
double sg = PL / PH; // bezwymiarowy stosunek cisnien
|
||||
double FM = PH * 197 * S; // najwyzszy mozliwy przeplyw, wraz z kierunkiem
|
||||
double FM = PH * 197.0 * S; // najwyzszy mozliwy przeplyw, wraz z kierunkiem
|
||||
if ((PH - LIM) < 0.1)
|
||||
FM = FM * (PH - LIM) / DP; // jesli jestesmy przy nastawieniu, to zawor sie przymyka
|
||||
if ((sg > 0.5)) // jesli ponizej stosunku krytycznego
|
||||
if ((PH - PL) < DPL) // niewielka roznica cisnien
|
||||
return (PH - PL) / DPL * FM * 2 * std::sqrt((sg) * (1 - sg));
|
||||
return (PH - PL) / DPL * FM * 2.0 * std::sqrt((sg) * (1.0 - sg));
|
||||
else
|
||||
return FM * 2 * std::sqrt((sg) * (1 - sg));
|
||||
return FM * 2.0 * std::sqrt((sg) * (1.0 - sg));
|
||||
else // powyzej stosunku krytycznego
|
||||
return FM;
|
||||
}
|
||||
@@ -150,7 +151,7 @@ void TReservoir::Flow(double dv)
|
||||
|
||||
void TReservoir::Act()
|
||||
{
|
||||
Vol = Vol + dVol;
|
||||
Vol = std::max( 0.0, Vol + dVol );
|
||||
dVol = 0;
|
||||
}
|
||||
|
||||
@@ -2131,39 +2132,34 @@ double TFV4a::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
{
|
||||
static int const LBDelay = 100;
|
||||
|
||||
double LimPP;
|
||||
double dpPipe;
|
||||
double dpMainValve;
|
||||
double ActFlowSpeed;
|
||||
|
||||
ep = PP; // SPKS!!
|
||||
LimPP = Min0R(BPT[lround(i_bcp) + 2][1], HP);
|
||||
ActFlowSpeed = BPT[lround(i_bcp) + 2][0];
|
||||
double LimPP = std::min(BPT[std::lround(i_bcp) + 2][1], HP);
|
||||
double ActFlowSpeed = BPT[std::lround(i_bcp) + 2][0];
|
||||
|
||||
if ((i_bcp == i_bcpno))
|
||||
LimPP = 2.9;
|
||||
|
||||
CP = CP + 20 * Min0R(abs(LimPP - CP), 0.05) * PR(CP, LimPP) * dt / 1;
|
||||
RP = RP + 20 * Min0R(abs(ep - RP), 0.05) * PR(RP, ep) * dt / 2.5;
|
||||
CP = CP + 20 * std::min(std::abs(LimPP - CP), 0.05) * PR(CP, LimPP) * dt / 1;
|
||||
RP = RP + 20 * std::min(std::abs(ep - RP), 0.05) * PR(RP, ep) * dt / 2.5;
|
||||
|
||||
LimPP = CP;
|
||||
dpPipe = Min0R(HP, LimPP);
|
||||
double dpPipe = std::min(HP, LimPP);
|
||||
|
||||
dpMainValve = PF(dpPipe, PP, ActFlowSpeed / LBDelay) * dt;
|
||||
double dpMainValve = PF(dpPipe, PP, ActFlowSpeed / LBDelay) * dt;
|
||||
if ((CP > RP + 0.05))
|
||||
dpMainValve = PF(Min0R(CP + 0.1, HP), PP, 1.1 * ActFlowSpeed / LBDelay) * dt;
|
||||
dpMainValve = PF(std::min(CP + 0.1, HP), PP, 1.1 * ActFlowSpeed / LBDelay) * dt;
|
||||
if ((CP < RP - 0.05))
|
||||
dpMainValve = PF(CP - 0.1, PP, 1.1 * ActFlowSpeed / LBDelay) * dt;
|
||||
|
||||
if (lround(i_bcp) == -1)
|
||||
{
|
||||
CP = CP + 5 * Min0R(abs(LimPP - CP), 0.2) * PR(CP, LimPP) * dt / 2;
|
||||
CP = CP + 5 * std::min(std::abs(LimPP - CP), 0.2) * PR(CP, LimPP) * dt / 2;
|
||||
if ((CP < RP + 0.03))
|
||||
if ((TP < 5))
|
||||
TP = TP + dt;
|
||||
// if(cp+0.03<5.4)then
|
||||
if ((RP + 0.03 < 5.4) || (CP + 0.03 < 5.4)) // fala
|
||||
dpMainValve = PF(Min0R(HP, 17.1), PP, ActFlowSpeed / LBDelay) * dt;
|
||||
dpMainValve = PF(std::min(HP, 17.1), PP, ActFlowSpeed / LBDelay) * dt;
|
||||
// dpMainValve:=20*Min0R(abs(ep-7.1),0.05)*PF(HP,pp,ActFlowSpeed/LBDelay)*dt;
|
||||
else
|
||||
{
|
||||
@@ -2183,9 +2179,9 @@ double TFV4a::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
TP = TP - dt / 12 / 2;
|
||||
}
|
||||
if ((CP > RP + 0.1) && (CP <= 5))
|
||||
dpMainValve = PF(Min0R(CP + 0.25, HP), PP, 2 * ActFlowSpeed / LBDelay) * dt;
|
||||
dpMainValve = PF(std::min(CP + 0.25, HP), PP, 2 * ActFlowSpeed / LBDelay) * dt;
|
||||
else if (CP > 5)
|
||||
dpMainValve = PF(Min0R(CP, HP), PP, 2 * ActFlowSpeed / LBDelay) * dt;
|
||||
dpMainValve = PF(std::min(CP, HP), PP, 2 * ActFlowSpeed / LBDelay) * dt;
|
||||
else
|
||||
dpMainValve = PF(dpPipe, PP, ActFlowSpeed / LBDelay) * dt;
|
||||
}
|
||||
@@ -2208,8 +2204,8 @@ void TFV4a::Init(double Press)
|
||||
|
||||
double TFV4aM::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
{
|
||||
static int const LBDelay = 100;
|
||||
static double const xpM = 0.3; // mnoznik membrany komory pod
|
||||
int const LBDelay { 100 };
|
||||
double const xpM { 0.3 }; // mnoznik membrany komory pod
|
||||
|
||||
ep = (PP / 2.0) * 1.5 + (ep / 2.0) * 0.5; // SPKS!!
|
||||
|
||||
@@ -2293,13 +2289,10 @@ double TFV4aM::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
|
||||
double const ActFlowSpeed = BPT[ std::lround( i_bcp ) + 2 ][ 0 ];
|
||||
|
||||
double dpMainValve;
|
||||
if( dpPipe > PP ) {
|
||||
dpMainValve = -PFVa( HP, PP, ActFlowSpeed / LBDelay, dpPipe, 0.4 );
|
||||
}
|
||||
else {
|
||||
dpMainValve = PFVd( PP, 0, ActFlowSpeed / LBDelay, dpPipe, 0.4 );
|
||||
}
|
||||
double dpMainValve = (
|
||||
dpPipe > PP ?
|
||||
-PFVa( HP, PP, ActFlowSpeed / LBDelay, dpPipe, 0.4 ) :
|
||||
PFVd( PP, 0, ActFlowSpeed / LBDelay, dpPipe, 0.4 ) );
|
||||
|
||||
if (EQ(i_bcp, -1)) {
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
/*
|
||||
#include "ResourceManager.h"
|
||||
#include "Logs.h"
|
||||
|
||||
@@ -84,3 +86,4 @@ void ResourceManager::Sweep(double currentTime)
|
||||
|
||||
_lastUpdate = currentTime;
|
||||
};
|
||||
*/
|
||||
@@ -7,14 +7,11 @@ obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef RESOURCEMANAGER_H
|
||||
#define RESOURCEMANAGER_H 1
|
||||
|
||||
#pragma once
|
||||
/*
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#pragma hdrstop
|
||||
|
||||
class Resource
|
||||
{
|
||||
|
||||
@@ -57,5 +54,63 @@ class ResourceManager
|
||||
|
||||
static Resources _resources;
|
||||
};
|
||||
*/
|
||||
|
||||
#endif
|
||||
template <class Container_>
|
||||
class garbage_collector {
|
||||
|
||||
public:
|
||||
// constructor:
|
||||
garbage_collector( Container_ &Container, int const Secondstolive, int const Sweepsize, std::string const Resourcename = "resource" ) :
|
||||
m_container( Container ),
|
||||
m_unusedresourcetimetolive { std::chrono::seconds( Secondstolive ) },
|
||||
m_unusedresourcesweepsize( Sweepsize ),
|
||||
m_resourcename( Resourcename )
|
||||
{}
|
||||
|
||||
// methods:
|
||||
// performs resource sweep. returns: number of released resources
|
||||
int
|
||||
sweep() {
|
||||
m_resourcetimestamp = std::chrono::steady_clock::now();
|
||||
// garbage collection sweep is limited to a number of records per call, to reduce impact on framerate
|
||||
auto const sweeplastindex =
|
||||
std::min(
|
||||
m_resourcesweepindex + m_unusedresourcesweepsize,
|
||||
m_container.size() );
|
||||
auto const blanktimestamp { std::chrono::steady_clock::time_point() };
|
||||
int releasecount{ 0 };
|
||||
for( auto resourceindex = m_resourcesweepindex; resourceindex < sweeplastindex; ++resourceindex ) {
|
||||
if( ( m_container[ resourceindex ].second != blanktimestamp )
|
||||
&& ( m_resourcetimestamp - m_container[ resourceindex ].second > m_unusedresourcetimetolive ) ) {
|
||||
|
||||
m_container[ resourceindex ].first->release();
|
||||
m_container[ resourceindex ].second = blanktimestamp;
|
||||
++releasecount;
|
||||
}
|
||||
}
|
||||
/*
|
||||
if( releasecount ) {
|
||||
WriteLog( "Resource garbage sweep released " + std::to_string( releasecount ) + " " + ( releasecount == 1 ? m_resourcename : m_resourcename + "s" ) );
|
||||
}
|
||||
*/
|
||||
m_resourcesweepindex = (
|
||||
m_resourcesweepindex + m_unusedresourcesweepsize >= m_container.size() ?
|
||||
0 : // if the next sweep chunk is beyond actual data, so start anew
|
||||
m_resourcesweepindex + m_unusedresourcesweepsize );
|
||||
|
||||
return releasecount; }
|
||||
|
||||
std::chrono::steady_clock::time_point
|
||||
timestamp() const {
|
||||
return m_resourcetimestamp; }
|
||||
|
||||
private:
|
||||
// members:
|
||||
std::chrono::nanoseconds const m_unusedresourcetimetolive;
|
||||
typename Container_::size_type const m_unusedresourcesweepsize;
|
||||
std::string const m_resourcename;
|
||||
typename Container_ &m_container;
|
||||
typename Container_::size_type m_resourcesweepindex { 0 };
|
||||
std::chrono::steady_clock::time_point m_resourcetimestamp { std::chrono::steady_clock::now() };
|
||||
};
|
||||
|
||||
83
Texture.cpp
83
Texture.cpp
@@ -24,10 +24,12 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "logs.h"
|
||||
#include "sn_utils.h"
|
||||
|
||||
#define EU07_DEFERRED_TEXTURE_UPLOAD
|
||||
|
||||
texture_manager::texture_manager() {
|
||||
|
||||
// since index 0 is used to indicate no texture, we put a blank entry in the first texture slot
|
||||
m_textures.emplace_back( opengl_texture() );
|
||||
m_textures.emplace_back( new opengl_texture(), std::chrono::steady_clock::time_point() );
|
||||
}
|
||||
|
||||
// loads texture data from specified file
|
||||
@@ -518,12 +520,12 @@ opengl_texture::bind() {
|
||||
return data_state;
|
||||
}
|
||||
|
||||
resource_state
|
||||
bool
|
||||
opengl_texture::create() {
|
||||
|
||||
if( data_state != resource_state::good ) {
|
||||
// don't bother until we have useful texture data
|
||||
return data_state;
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: consider creating and storing low-res version of the texture if it's ever unloaded from the gfx card,
|
||||
@@ -562,8 +564,8 @@ opengl_texture::create() {
|
||||
for( int maplevel = 0; maplevel < data_mapcount; ++maplevel ) {
|
||||
|
||||
if( ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT )
|
||||
|| ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT )
|
||||
|| ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ) ) {
|
||||
|| ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT )
|
||||
|| ( data_format == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ) ) {
|
||||
// compressed dds formats
|
||||
int const datablocksize =
|
||||
( data_format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ?
|
||||
@@ -590,15 +592,44 @@ opengl_texture::create() {
|
||||
}
|
||||
}
|
||||
|
||||
data.resize( 0 ); // TBD, TODO: keep the texture data if we start doing some gpu data cleaning down the road
|
||||
data.swap( std::vector<char>() ); // TBD, TODO: keep the texture data if we start doing some gpu data cleaning down the road
|
||||
/*
|
||||
data_state = resource_state::none;
|
||||
*/
|
||||
data_state = resource_state::good;
|
||||
data_state = resource_state::none;
|
||||
is_ready = true;
|
||||
}
|
||||
|
||||
return data_state;
|
||||
return true;
|
||||
}
|
||||
|
||||
// releases resources allocated on the opengl end, storing local copy if requested
|
||||
void
|
||||
opengl_texture::release( bool const Backup ) {
|
||||
|
||||
if( id == -1 ) { return; }
|
||||
|
||||
assert( is_ready );
|
||||
|
||||
if( true == Backup ) {
|
||||
// query texture details needed to perform the backup...
|
||||
::glBindTexture( GL_TEXTURE_2D, id );
|
||||
::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, (GLint *)&data_format );
|
||||
GLint datasize;
|
||||
::glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, (GLint *)&datasize );
|
||||
data.resize( datasize );
|
||||
// ...fetch the data...
|
||||
::glGetCompressedTexImage( GL_TEXTURE_2D, 0, &data[ 0 ] );
|
||||
// ...and update texture object state
|
||||
data_mapcount = 1; // we keep copy of only top mipmap level
|
||||
data_state = resource_state::good;
|
||||
}
|
||||
// release opengl resources
|
||||
::glDeleteTextures( 1, &id );
|
||||
id = -1;
|
||||
is_ready = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -773,8 +804,8 @@ texture_manager::create( std::string Filename, std::string const &Dir, int const
|
||||
return npos;
|
||||
}
|
||||
|
||||
opengl_texture texture;
|
||||
texture.name = filename;
|
||||
auto texture = new opengl_texture();
|
||||
texture->name = filename;
|
||||
if( ( Filter > 0 ) && ( Filter < 10 ) ) {
|
||||
// temporary. TODO, TBD: check how it's used and possibly get rid of it
|
||||
traits += std::to_string( ( Filter < 4 ? Filter + 4 : Filter ) );
|
||||
@@ -783,9 +814,9 @@ texture_manager::create( std::string Filename, std::string const &Dir, int const
|
||||
// temporary code for legacy assets -- textures with names beginning with # are to be sharpened
|
||||
traits += '#';
|
||||
}
|
||||
texture.traits = traits;
|
||||
texture->traits = traits;
|
||||
auto const textureindex = (texture_handle)m_textures.size();
|
||||
m_textures.emplace_back( texture );
|
||||
m_textures.emplace_back( texture, std::chrono::steady_clock::time_point() );
|
||||
m_texturemappings.emplace( filename, textureindex );
|
||||
|
||||
WriteLog( "Created texture object for \"" + filename + "\"" );
|
||||
@@ -796,7 +827,7 @@ texture_manager::create( std::string Filename, std::string const &Dir, int const
|
||||
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||
texture_manager::texture( textureindex ).create();
|
||||
// texture creation binds a different texture, force a re-bind on next use
|
||||
m_activetexture = 0;
|
||||
m_activetexture = -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -806,7 +837,9 @@ texture_manager::create( std::string Filename, std::string const &Dir, int const
|
||||
void
|
||||
texture_manager::bind( texture_handle const Texture ) {
|
||||
|
||||
if( Texture == m_activetexture ) {
|
||||
m_textures[ Texture ].second = m_garbagecollector.timestamp();
|
||||
|
||||
if( ( Texture != 0 ) && ( Texture == m_activetexture ) ) {
|
||||
// don't bind again what's already active
|
||||
return;
|
||||
}
|
||||
@@ -838,10 +871,20 @@ void
|
||||
texture_manager::delete_textures() {
|
||||
for( auto const &texture : m_textures ) {
|
||||
// usunięcie wszyskich tekstur (bez usuwania struktury)
|
||||
if( ( texture.id > 0 )
|
||||
&& ( texture.id != -1 ) ) {
|
||||
::glDeleteTextures( 1, &texture.id );
|
||||
if( ( texture.first->id > 0 )
|
||||
&& ( texture.first->id != -1 ) ) {
|
||||
::glDeleteTextures( 1, &(texture.first->id) );
|
||||
}
|
||||
delete texture.first;
|
||||
}
|
||||
}
|
||||
|
||||
// performs a resource sweep
|
||||
void
|
||||
texture_manager::update() {
|
||||
|
||||
if( m_garbagecollector.sweep() > 0 ) {
|
||||
m_activetexture = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -859,13 +902,13 @@ texture_manager::info() const {
|
||||
|
||||
for( auto const& texture : m_textures ) {
|
||||
|
||||
totaltexturesize += texture.size;
|
||||
totaltexturesize += texture.first->size;
|
||||
#ifdef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||
|
||||
if( texture.is_ready ) {
|
||||
if( texture.first->is_ready ) {
|
||||
|
||||
++readytexturecount;
|
||||
readytexturesize += texture.size;
|
||||
readytexturesize += texture.first->size;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
41
Texture.h
41
Texture.h
@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include <ddraw.h>
|
||||
#include <string>
|
||||
#include "GL/glew.h"
|
||||
#include "ResourceManager.h"
|
||||
|
||||
enum class resource_state {
|
||||
none,
|
||||
@@ -27,12 +28,16 @@ struct opengl_texture {
|
||||
static DDPIXELFORMAT deserialize_ddpf(std::istream&);
|
||||
static DDSCAPS2 deserialize_ddscaps(std::istream&);
|
||||
|
||||
// methods
|
||||
void load();
|
||||
// methods
|
||||
void
|
||||
load();
|
||||
resource_state
|
||||
bind();
|
||||
resource_state
|
||||
bool
|
||||
create();
|
||||
// releases resources allocated on the opengl end, storing local copy if requested
|
||||
void
|
||||
release( bool const Backup = true );
|
||||
inline
|
||||
int
|
||||
width() const {
|
||||
@@ -41,7 +46,7 @@ struct opengl_texture {
|
||||
int
|
||||
height() const {
|
||||
return data_height; }
|
||||
// members
|
||||
// members
|
||||
GLuint id{ (GLuint)-1 }; // associated GL resource
|
||||
bool has_alpha{ false }; // indicates the texture has alpha channel
|
||||
bool is_ready{ false }; // indicates the texture was processed and is ready for use
|
||||
@@ -50,7 +55,7 @@ struct opengl_texture {
|
||||
std::size_t size{ 0 }; // size of the texture data, in kb
|
||||
|
||||
private:
|
||||
// methods
|
||||
// methods
|
||||
void load_BMP();
|
||||
void load_DDS();
|
||||
void load_TEX();
|
||||
@@ -58,7 +63,7 @@ private:
|
||||
void set_filtering();
|
||||
void downsize( GLuint const Format );
|
||||
|
||||
// members
|
||||
// members
|
||||
std::vector<char> data; // texture data
|
||||
resource_state data_state{ resource_state::none }; // current state of texture data
|
||||
int data_width{ 0 },
|
||||
@@ -76,9 +81,6 @@ typedef int texture_handle;
|
||||
|
||||
class texture_manager {
|
||||
|
||||
private:
|
||||
typedef std::vector<opengl_texture> opengltexture_array;
|
||||
|
||||
public:
|
||||
texture_manager();
|
||||
~texture_manager() { delete_textures(); }
|
||||
@@ -88,14 +90,25 @@ public:
|
||||
void
|
||||
bind( texture_handle const Texture );
|
||||
opengl_texture &
|
||||
texture( texture_handle const Texture ) { return m_textures[ Texture ]; }
|
||||
texture( texture_handle const Texture ) { return *(m_textures[ Texture ].first); }
|
||||
// performs a resource sweep
|
||||
void
|
||||
update();
|
||||
// debug performance string
|
||||
std::string
|
||||
info() const;
|
||||
|
||||
private:
|
||||
// types:
|
||||
typedef std::pair<
|
||||
opengl_texture *,
|
||||
std::chrono::steady_clock::time_point > texturetimepoint_pair;
|
||||
|
||||
typedef std::vector< texturetimepoint_pair > texturetimepointpair_sequence;
|
||||
|
||||
typedef std::unordered_map<std::string, std::size_t> index_map;
|
||||
|
||||
// methods:
|
||||
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
||||
texture_handle
|
||||
find_in_databank( std::string const &Texturename ) const;
|
||||
@@ -105,10 +118,12 @@ private:
|
||||
void
|
||||
delete_textures();
|
||||
|
||||
static const texture_handle npos{ 0 }; // should be -1, but the rest of the code uses -1 for something else
|
||||
opengltexture_array m_textures;
|
||||
// members:
|
||||
texture_handle const npos { 0 }; // should be -1, but the rest of the code uses -1 for something else
|
||||
texturetimepointpair_sequence m_textures;
|
||||
index_map m_texturemappings;
|
||||
texture_handle m_activetexture{ 0 }; // last i.e. currently bound texture
|
||||
garbage_collector<texturetimepointpair_sequence> m_garbagecollector { m_textures, 600, 60, "texture" };
|
||||
texture_handle m_activetexture { 0 }; // last i.e. currently bound texture
|
||||
};
|
||||
|
||||
// reduces provided data image to half of original size, using basic 2x2 average
|
||||
|
||||
@@ -1524,8 +1524,8 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
|
||||
Train->ggMainButton.UpdateValue( 1.0 );
|
||||
}
|
||||
// keep track of period the button is held down, to determine when/if circuit closes
|
||||
if( ( false == ( ( Train->mvControlled->EngineType == ElectricSeriesMotor )
|
||||
|| ( Train->mvControlled->EngineType == ElectricInductionMotor ) ) )
|
||||
if( ( ( ( Train->mvControlled->EngineType != ElectricSeriesMotor )
|
||||
&& ( Train->mvControlled->EngineType != ElectricInductionMotor ) ) )
|
||||
|| ( Train->fHVoltage > 0.5 * Train->mvControlled->EnginePowerSource.MaxVoltage ) ) {
|
||||
// prevent the switch from working if there's no power
|
||||
// TODO: consider whether it makes sense for diesel engines and such
|
||||
|
||||
@@ -1253,7 +1253,9 @@ void TWorld::Update_Environment() {
|
||||
|
||||
void TWorld::ResourceSweep()
|
||||
{
|
||||
/*
|
||||
ResourceManager::Sweep( Timer::GetSimulationTime() );
|
||||
*/
|
||||
};
|
||||
|
||||
// rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana
|
||||
@@ -1664,7 +1666,7 @@ TWorld::Update_UI() {
|
||||
+ ( Global::bUseVBO ?
|
||||
"VBO" :
|
||||
"Display Lists" )
|
||||
+ ". ";
|
||||
+ " ";
|
||||
// dump last opengl error, if any
|
||||
GLenum glerror = ::glGetError();
|
||||
if( glerror != GL_NO_ERROR ) {
|
||||
|
||||
@@ -359,25 +359,7 @@ opengl_dlgeometrybank::delete_list( geometry_handle const &Geometry ) {
|
||||
void
|
||||
geometrybank_manager::update() {
|
||||
|
||||
m_resourcetimestamp = std::chrono::steady_clock::now();
|
||||
// garbage collection sweep is limited to a number of records per call, to reduce impact on framerate
|
||||
auto const sweeplastindex =
|
||||
std::min(
|
||||
m_resourcesweepindex + geometrybank_manager::unusedresourcesweepsize,
|
||||
m_geometrybanks.size() );
|
||||
auto const blanktimestamp { std::chrono::steady_clock::time_point() };
|
||||
for( auto bankindex = m_resourcesweepindex; bankindex < sweeplastindex; ++bankindex ) {
|
||||
if( ( m_geometrybanks[ bankindex ].second != blanktimestamp )
|
||||
&& ( m_resourcetimestamp - m_geometrybanks[ bankindex ].second > geometrybank_manager::unusedresourcetimetolive ) ) {
|
||||
|
||||
m_geometrybanks[ bankindex ].first->release();
|
||||
m_geometrybanks[ bankindex ].second = blanktimestamp;
|
||||
}
|
||||
}
|
||||
m_resourcesweepindex = (
|
||||
m_resourcesweepindex + geometrybank_manager::unusedresourcesweepsize >= m_geometrybanks.size() ?
|
||||
0 : // if the next sweep chunk is beyond actual data, so start anew
|
||||
m_resourcesweepindex + geometrybank_manager::unusedresourcesweepsize );
|
||||
m_garbagecollector.sweep();
|
||||
}
|
||||
|
||||
// creates a new geometry bank. returns: handle to the bank or NULL
|
||||
@@ -421,7 +403,7 @@ geometrybank_manager::draw( geometry_handle const &Geometry, unsigned int const
|
||||
|
||||
auto &bankrecord = bank( Geometry );
|
||||
|
||||
bankrecord.second = m_resourcetimestamp;
|
||||
bankrecord.second = m_garbagecollector.timestamp();
|
||||
bankrecord.first->draw( Geometry, Streams );
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#ifdef _WINDOWS
|
||||
#include "GL/wglew.h"
|
||||
#endif
|
||||
#include "ResourceManager.h"
|
||||
|
||||
struct basic_vertex {
|
||||
|
||||
@@ -275,9 +276,9 @@ public:
|
||||
template <typename Iterator_>
|
||||
void
|
||||
draw( Iterator_ First, Iterator_ Last, unsigned int const Streams = basic_streams ) {
|
||||
while( First != Last ) {
|
||||
draw( *First, Streams );
|
||||
++First; } }
|
||||
while( First != Last ) {
|
||||
draw( *First, Streams );
|
||||
++First; } }
|
||||
// provides direct access to vertex data of specfied chunk
|
||||
vertex_array const &
|
||||
vertices( geometry_handle const &Geometry ) const;
|
||||
@@ -290,12 +291,9 @@ private:
|
||||
|
||||
typedef std::deque< geometrybanktimepoint_pair > geometrybanktimepointpair_sequence;
|
||||
|
||||
// members:
|
||||
std::chrono::nanoseconds const unusedresourcetimetolive { std::chrono::seconds { 60 } };
|
||||
geometrybanktimepointpair_sequence::size_type const unusedresourcesweepsize { 300 };
|
||||
// members:
|
||||
geometrybanktimepointpair_sequence m_geometrybanks;
|
||||
geometrybanktimepointpair_sequence::size_type m_resourcesweepindex { 0 };
|
||||
std::chrono::steady_clock::time_point m_resourcetimestamp { std::chrono::steady_clock::now() };
|
||||
garbage_collector<geometrybanktimepointpair_sequence> m_garbagecollector { m_geometrybanks, 60, 120, "geometry buffer" };
|
||||
|
||||
// methods
|
||||
inline
|
||||
|
||||
59
renderer.cpp
59
renderer.cpp
@@ -162,12 +162,22 @@ opengl_renderer::Render() {
|
||||
|
||||
if( World.InitPerformed() ) {
|
||||
|
||||
glm::dmat4 worldcamera;
|
||||
World.Camera.SetMatrix( worldcamera );
|
||||
m_camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), worldcamera );
|
||||
// frustum tests are performed in 'world space' but after we set up frustum
|
||||
// we no longer need camera translation, only rotation
|
||||
::glMultMatrixd( glm::value_ptr( glm::dmat4( glm::dmat3( worldcamera ))));
|
||||
glm::dmat4 viewmatrix;
|
||||
// camera view
|
||||
World.Camera.SetMatrix( viewmatrix );
|
||||
m_camera.position() = glm::make_vec3( Global::pCameraPosition.getArray() );
|
||||
/*
|
||||
// light view
|
||||
m_camera.position() = glm::make_vec3( Global::pCameraPosition.getArray() ) - glm::dvec3( Global::DayLight.direction * 750.0f );
|
||||
m_camera.position().y = std::max( 50.0, m_camera.position().y ); // prevent shadow source from dipping too low
|
||||
viewmatrix = glm::lookAt(
|
||||
m_camera.position(),
|
||||
glm::dvec3( Global::pCameraPosition.x, 0.0, Global::pCameraPosition.z ),
|
||||
glm::dvec3( 0.0f, 1.0f, 0.0f ) );
|
||||
*/
|
||||
m_camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), viewmatrix );
|
||||
// frustum tests are performed in 'world space' but after we set up frustum we no longer need camera translation, only rotation
|
||||
::glMultMatrixd( glm::value_ptr( glm::dmat4( glm::dmat3( viewmatrix ))));
|
||||
|
||||
Render( &World.Environment );
|
||||
Render( &World.Ground );
|
||||
@@ -193,7 +203,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Bind( 0 );
|
||||
Bind( NULL );
|
||||
|
||||
::glDisable( GL_LIGHTING );
|
||||
::glDisable( GL_DEPTH_TEST );
|
||||
@@ -387,7 +397,7 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
|
||||
glm::vec3 const cameraposition( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
|
||||
glm::vec3 const cameraposition { m_camera.position() };
|
||||
int const camerax = static_cast<int>( std::floor( cameraposition.x / 1000.0f ) + iNumRects / 2 );
|
||||
int const cameraz = static_cast<int>( std::floor( cameraposition.z / 1000.0f ) + iNumRects / 2 );
|
||||
int const segmentcount = 2 * static_cast<int>(std::ceil( m_drawrange * Global::fDistanceFactor / 1000.0f ));
|
||||
@@ -461,7 +471,7 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
||||
if( subcell->iNodeCount ) {
|
||||
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
||||
m_drawqueue.emplace_back(
|
||||
( Global::pCameraPosition - glm::dvec3( subcell->m_area.center ) ).LengthSquared(),
|
||||
glm::length2( m_camera.position() - glm::dvec3( subcell->m_area.center ) ),
|
||||
subcell );
|
||||
}
|
||||
}
|
||||
@@ -515,7 +525,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
{ // obiekty renderowane niezależnie od odległości
|
||||
case TP_SUBMODEL:
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->pCenter - Global::pCameraPosition;
|
||||
auto const originoffset = Node->pCenter - m_camera.position();
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
TSubModel::fSquareDist = 0;
|
||||
Render( Node->smTerrain );
|
||||
@@ -523,7 +533,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - m_camera.position() ) / Global::ZoomFactor );
|
||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||
return false;
|
||||
@@ -534,7 +544,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
case TP_TRACK: {
|
||||
// setup
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
auto const originoffset = Node->m_rootposition - m_camera.position();
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
// render
|
||||
Render( Node->pTrack );
|
||||
@@ -544,7 +554,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
}
|
||||
|
||||
case TP_MODEL: {
|
||||
Node->Model->Render( Node->pCenter - Global::pCameraPosition );
|
||||
Node->Model->Render( Node->pCenter - m_camera.position() );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -573,7 +583,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
GfxRenderer.Bind( 0 );
|
||||
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
auto const originoffset = Node->m_rootposition - m_camera.position();
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
|
||||
// render
|
||||
@@ -598,7 +608,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
Bind( Node->TextureID );
|
||||
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
auto const originoffset = Node->m_rootposition - m_camera.position();
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
|
||||
// render
|
||||
@@ -631,7 +641,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
|
||||
// setup
|
||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
||||
auto const originoffset = Dynamic->vPosition - Global::pCameraPosition;
|
||||
auto const originoffset = Dynamic->vPosition - m_camera.position();
|
||||
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||
::glPushMatrix();
|
||||
@@ -970,7 +980,7 @@ opengl_renderer::Render_Alpha( TSubRect *Groundsubcell ) {
|
||||
bool
|
||||
opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - m_camera.position() ) / Global::ZoomFactor );
|
||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||
return false;
|
||||
@@ -1002,7 +1012,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
Bind( NULL );
|
||||
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
auto const originoffset = Node->m_rootposition - m_camera.position();
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
|
||||
// render
|
||||
@@ -1023,7 +1033,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
}
|
||||
}
|
||||
case TP_MODEL: {
|
||||
Node->Model->RenderAlpha( Node->pCenter - Global::pCameraPosition );
|
||||
Node->Model->RenderAlpha( Node->pCenter - m_camera.position() );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1052,7 +1062,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
GfxRenderer.Bind( 0 );
|
||||
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
auto const originoffset = Node->m_rootposition - m_camera.position();
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
|
||||
// render
|
||||
@@ -1077,7 +1087,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
Bind( Node->TextureID );
|
||||
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
auto const originoffset = Node->m_rootposition - m_camera.position();
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
|
||||
// render
|
||||
@@ -1102,7 +1112,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
|
||||
// setup
|
||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
||||
auto const originoffset = Dynamic->vPosition - Global::pCameraPosition;
|
||||
auto const originoffset = Dynamic->vPosition - m_camera.position();
|
||||
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||
::glPushMatrix();
|
||||
@@ -1419,6 +1429,7 @@ opengl_renderer::Update ( double const Deltatime ) {
|
||||
|
||||
// TODO: add garbage collection and other less frequent works here
|
||||
m_geometry.update();
|
||||
m_textures.update();
|
||||
|
||||
if( true == DebugModeFlag ) {
|
||||
m_debuginfo = m_textures.info();
|
||||
@@ -1453,13 +1464,13 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
|
||||
// all lights past this one are bound to be off
|
||||
break;
|
||||
}
|
||||
if( ( Global::pCameraPosition - scenelight.position ).Length() > 1000.0f ) {
|
||||
if( ( m_camera.position() - scenelight.position ).Length() > 1000.0f ) {
|
||||
// we don't care about lights past arbitrary limit of 1 km.
|
||||
// but there could still be weaker lights which are closer, so keep looking
|
||||
continue;
|
||||
}
|
||||
// if the light passed tests so far, it's good enough
|
||||
renderlight->set_position( glm::make_vec3( (scenelight.position - Global::pCameraPosition).readArray() ) );
|
||||
renderlight->set_position( glm::make_vec3( (scenelight.position - m_camera.position()).readArray() ) );
|
||||
renderlight->direction = scenelight.direction;
|
||||
|
||||
auto luminance = Global::fLuminance; // TODO: adjust this based on location, e.g. for tunnels
|
||||
|
||||
@@ -91,10 +91,17 @@ public:
|
||||
visible( bounding_area const &Area ) const;
|
||||
bool
|
||||
visible( TDynamicObject const *Dynamic ) const;
|
||||
inline
|
||||
glm::dvec3 const &
|
||||
position() const { return m_position; }
|
||||
inline
|
||||
glm::dvec3 &
|
||||
position() { return m_position; }
|
||||
|
||||
private:
|
||||
// members:
|
||||
cFrustum m_frustum;
|
||||
glm::dvec3 m_position;
|
||||
};
|
||||
|
||||
// bare-bones render controller, in lack of anything better yet
|
||||
|
||||
Reference in New Issue
Block a user