mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 22:09:19 +02:00
merge and shadow fixes
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 *************************************
|
// 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)
|
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
|
// 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( ',' );
|
std::size_t i = asModel.find( ',' );
|
||||||
if ( i != std::string::npos )
|
if ( i != std::string::npos )
|
||||||
{ // Ra 2015-01: może szukać przecinka w nazwie modelu, a po przecinku była by liczba tekstur?
|
{ // Ra 2015-01: może szukać przecinka w nazwie modelu, a po przecinku była by liczba tekstur?
|
||||||
if (i < asModel.length())
|
if( i < asModel.length() ) {
|
||||||
m_materialdata.multi_textures = asModel[i + 1] - '0';
|
m_materialdata.multi_textures = asModel[ i + 1 ] - '0';
|
||||||
|
}
|
||||||
m_materialdata.multi_textures = clamp( m_materialdata.multi_textures, 0, 1 ); // na razie ustawiamy na 1
|
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
|
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;
|
int skinindex = 0;
|
||||||
do {
|
do {
|
||||||
texture_handle texture = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + ReplacableSkin + "," + std::to_string( skinindex + 1 ), "", Global::iDynamicFiltering, true );
|
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;
|
break;
|
||||||
}
|
}
|
||||||
m_materialdata.replacable_skins[ skinindex + 1 ] = texture;
|
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 );
|
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
|
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 1 ] ).has_alpha ) {
|
||||||
else
|
// tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||||
m_materialdata.textures_alpha = 0x30300030; // wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych
|
m_materialdata.textures_alpha = 0x31310031;
|
||||||
if( m_materialdata.replacable_skins[ 2 ] )
|
}
|
||||||
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 2 ] ).has_alpha )
|
else {
|
||||||
m_materialdata.textures_alpha |= 0x02020002; // tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
// wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych
|
||||||
if( m_materialdata.replacable_skins[ 3 ] )
|
m_materialdata.textures_alpha = 0x30300030;
|
||||||
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( ( m_materialdata.replacable_skins[ 2 ] )
|
||||||
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 4 ] ).has_alpha )
|
&& ( GfxRenderer.Texture( m_materialdata.replacable_skins[ 2 ] ).has_alpha ) ) {
|
||||||
m_materialdata.textures_alpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
// 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.empty() ) {
|
||||||
// if (MoverParameters->LoadAccepted!=AnsiString("")); // &&
|
|
||||||
// MoverParameters->LoadType!=AnsiString("passengers"))
|
if( MoverParameters->EnginePowerSource.SourceType == CurrentCollector ) {
|
||||||
if (MoverParameters->EnginePowerSource.SourceType == CurrentCollector)
|
// wartość niby "pantstate" - nazwa dla formalności, ważna jest ilość
|
||||||
{ // wartość niby "pantstate" - nazwa dla formalności, ważna jest ilość
|
if( MoverParameters->Load == 1 ) {
|
||||||
if (MoverParameters->Load == 1)
|
MoverParameters->PantFront( true );
|
||||||
MoverParameters->PantFront(true);
|
|
||||||
else if (MoverParameters->Load == 2)
|
|
||||||
MoverParameters->PantRear(true);
|
|
||||||
else if (MoverParameters->Load == 3)
|
|
||||||
{
|
|
||||||
MoverParameters->PantFront(true);
|
|
||||||
MoverParameters->PantRear(true);
|
|
||||||
}
|
}
|
||||||
else if (MoverParameters->Load == 4)
|
else if( MoverParameters->Load == 2 ) {
|
||||||
MoverParameters->DoubleTr = -1;
|
MoverParameters->PantRear( true );
|
||||||
else if (MoverParameters->Load == 5)
|
|
||||||
{
|
|
||||||
MoverParameters->DoubleTr = -1;
|
|
||||||
MoverParameters->PantRear(true);
|
|
||||||
}
|
}
|
||||||
else if (MoverParameters->Load == 6)
|
else if( MoverParameters->Load == 3 ) {
|
||||||
{
|
MoverParameters->PantFront( true );
|
||||||
MoverParameters->DoubleTr = -1;
|
MoverParameters->PantRear( true );
|
||||||
MoverParameters->PantFront(true);
|
|
||||||
}
|
}
|
||||||
else if (MoverParameters->Load == 7)
|
else if( MoverParameters->Load == 4 ) {
|
||||||
{
|
|
||||||
MoverParameters->DoubleTr = -1;
|
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() ) {
|
if( false == asLoadName.empty() ) {
|
||||||
mdLoad = TModelsManager::GetModel( asLoadName, true ); // ladunek
|
mdLoad = TModelsManager::GetModel( asLoadName, true ); // ladunek
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Global::asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur
|
Global::asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur
|
||||||
do {
|
do {
|
||||||
token = "";
|
token = "";
|
||||||
@@ -4198,11 +4204,9 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
|||||||
}
|
}
|
||||||
// WriteLog("Total animations: "+AnsiString(iAnimations));
|
// 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
|
// disabled as default animation amounts are no longer supported
|
||||||
if( !iAnimations ) {
|
if( !iAnimations ) {
|
||||||
@@ -4217,9 +4221,6 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
|||||||
iAnimType[ANIM_PANTS]=0;
|
iAnimType[ANIM_PANTS]=0;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
pAnimations = new TAnim[iAnimations];
|
|
||||||
*/
|
|
||||||
pAnimations.resize( iAnimations );
|
pAnimations.resize( iAnimations );
|
||||||
int i, j, k = 0, sm = 0;
|
int i, j, k = 0, sm = 0;
|
||||||
for (j = 0; j < ANIM_TYPES; ++j)
|
for (j = 0; j < ANIM_TYPES; ++j)
|
||||||
@@ -4229,9 +4230,6 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
|||||||
if (!pants)
|
if (!pants)
|
||||||
if (iAnimType[ANIM_PANTS]) // o ile jakieś pantografy są (a domyślnie są)
|
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
|
||||||
/*
|
|
||||||
pants = pAnimations + k; // zapamiętanie na potrzeby wyszukania submodeli
|
|
||||||
*/
|
|
||||||
pAnimations[k].iShift = sm; // przesunięcie do przydzielenia wskaźnika
|
pAnimations[k].iShift = sm; // przesunięcie do przydzielenia wskaźnika
|
||||||
sm += pAnimations[k++].TypeSet(j); // ustawienie typu animacji i zliczanie tablicowanych submodeli
|
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)
|
if (pAnimations[i].smAnimated)
|
||||||
{ //++iAnimatedAxles;
|
{ //++iAnimatedAxles;
|
||||||
pAnimations[i].smAnimated->WillBeAnimated(); // wyłączenie optymalizacji transformu
|
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 = 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 *= pAnimations[i].fMaxDist * MoverParameters->WheelDiameter; // 50m do kwadratu, a średnica do trzeciej
|
||||||
pAnimations[i].fMaxDist *= Global::fDistanceFactor; // współczynnik przeliczeniowy jakości ekranu
|
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)
|
switch (MoverParameters->DoorOpenMethod)
|
||||||
{ // od razu zapinamy potrzebny typ animacji
|
{ // od razu zapinamy potrzebny typ animacji
|
||||||
case 1:
|
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;
|
break;
|
||||||
case 2:
|
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;
|
break;
|
||||||
case 3:
|
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
|
break; // obrót 3 kolejnych submodeli
|
||||||
case 4:
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
13
Gauge.cpp
13
Gauge.cpp
@@ -150,16 +150,21 @@ double TGauge::GetValue() const {
|
|||||||
return ( fValue - fOffset ) / fScale;
|
return ( fValue - fOffset ) / fScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TGauge::Update()
|
void TGauge::Update() {
|
||||||
{
|
|
||||||
float dt = Timer::GetDeltaTime();
|
float dt = Timer::GetDeltaTime();
|
||||||
if( ( fFriction > 0 ) && ( dt < 0.5 * fFriction ) ) {
|
if( ( fFriction > 0 ) && ( dt < 0.5 * fFriction ) ) {
|
||||||
// McZapkie-281102: zabezpieczenie przed oscylacjami dla dlugich czasow
|
// McZapkie-281102: zabezpieczenie przed oscylacjami dla dlugich czasow
|
||||||
fValue += dt * ( fDesiredValue - fValue ) / fFriction;
|
fValue += dt * ( fDesiredValue - fValue ) / fFriction;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
fValue = fDesiredValue;
|
fValue = fDesiredValue;
|
||||||
if (SubModel)
|
}
|
||||||
|
if( std::abs( fDesiredValue - fValue ) <= 0.001 ) {
|
||||||
|
// close enough, we can stop updating the model
|
||||||
|
fValue = fDesiredValue; // set it exactly as requested just in case it matters
|
||||||
|
}
|
||||||
|
if( SubModel )
|
||||||
{ // warunek na wszelki wypadek, gdyby się submodel nie podłączył
|
{ // warunek na wszelki wypadek, gdyby się submodel nie podłączył
|
||||||
TSubModel *sm;
|
TSubModel *sm;
|
||||||
switch (eType)
|
switch (eType)
|
||||||
|
|||||||
@@ -113,17 +113,18 @@ double PFVd( double PH, double PL, double const S, double LIM, double const DP )
|
|||||||
if (LIM < PH)
|
if (LIM < PH)
|
||||||
{
|
{
|
||||||
LIM = LIM + 1;
|
LIM = LIM + 1;
|
||||||
PH = PH + 1; // wyzsze cisnienie absolutne
|
PH = PH + 1.0; // wyzsze cisnienie absolutne
|
||||||
PL = PL + 1; // nizsze cisnienie absolutne
|
PL = PL + 1.0; // nizsze cisnienie absolutne
|
||||||
|
assert( PH != PL );
|
||||||
double sg = PL / PH; // bezwymiarowy stosunek cisnien
|
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)
|
if ((PH - LIM) < 0.1)
|
||||||
FM = FM * (PH - LIM) / DP; // jesli jestesmy przy nastawieniu, to zawor sie przymyka
|
FM = FM * (PH - LIM) / DP; // jesli jestesmy przy nastawieniu, to zawor sie przymyka
|
||||||
if ((sg > 0.5)) // jesli ponizej stosunku krytycznego
|
if ((sg > 0.5)) // jesli ponizej stosunku krytycznego
|
||||||
if ((PH - PL) < DPL) // niewielka roznica cisnien
|
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
|
else
|
||||||
return FM * 2 * std::sqrt((sg) * (1 - sg));
|
return FM * 2.0 * std::sqrt((sg) * (1.0 - sg));
|
||||||
else // powyzej stosunku krytycznego
|
else // powyzej stosunku krytycznego
|
||||||
return FM;
|
return FM;
|
||||||
}
|
}
|
||||||
@@ -150,7 +151,7 @@ void TReservoir::Flow(double dv)
|
|||||||
|
|
||||||
void TReservoir::Act()
|
void TReservoir::Act()
|
||||||
{
|
{
|
||||||
Vol = Vol + dVol;
|
Vol = std::max( 0.0, Vol + dVol );
|
||||||
dVol = 0;
|
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;
|
static int const LBDelay = 100;
|
||||||
|
|
||||||
double LimPP;
|
|
||||||
double dpPipe;
|
|
||||||
double dpMainValve;
|
|
||||||
double ActFlowSpeed;
|
|
||||||
|
|
||||||
ep = PP; // SPKS!!
|
ep = PP; // SPKS!!
|
||||||
LimPP = Min0R(BPT[lround(i_bcp) + 2][1], HP);
|
double LimPP = std::min(BPT[std::lround(i_bcp) + 2][1], HP);
|
||||||
ActFlowSpeed = BPT[lround(i_bcp) + 2][0];
|
double ActFlowSpeed = BPT[std::lround(i_bcp) + 2][0];
|
||||||
|
|
||||||
if ((i_bcp == i_bcpno))
|
if ((i_bcp == i_bcpno))
|
||||||
LimPP = 2.9;
|
LimPP = 2.9;
|
||||||
|
|
||||||
CP = CP + 20 * Min0R(abs(LimPP - CP), 0.05) * PR(CP, LimPP) * dt / 1;
|
CP = CP + 20 * std::min(std::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;
|
RP = RP + 20 * std::min(std::abs(ep - RP), 0.05) * PR(RP, ep) * dt / 2.5;
|
||||||
|
|
||||||
LimPP = CP;
|
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))
|
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))
|
if ((CP < RP - 0.05))
|
||||||
dpMainValve = PF(CP - 0.1, PP, 1.1 * ActFlowSpeed / LBDelay) * dt;
|
dpMainValve = PF(CP - 0.1, PP, 1.1 * ActFlowSpeed / LBDelay) * dt;
|
||||||
|
|
||||||
if (lround(i_bcp) == -1)
|
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 ((CP < RP + 0.03))
|
||||||
if ((TP < 5))
|
if ((TP < 5))
|
||||||
TP = TP + dt;
|
TP = TP + dt;
|
||||||
// if(cp+0.03<5.4)then
|
// if(cp+0.03<5.4)then
|
||||||
if ((RP + 0.03 < 5.4) || (CP + 0.03 < 5.4)) // fala
|
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;
|
// dpMainValve:=20*Min0R(abs(ep-7.1),0.05)*PF(HP,pp,ActFlowSpeed/LBDelay)*dt;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2183,9 +2179,9 @@ double TFV4a::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
|||||||
TP = TP - dt / 12 / 2;
|
TP = TP - dt / 12 / 2;
|
||||||
}
|
}
|
||||||
if ((CP > RP + 0.1) && (CP <= 5))
|
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)
|
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
|
else
|
||||||
dpMainValve = PF(dpPipe, PP, ActFlowSpeed / LBDelay) * dt;
|
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)
|
double TFV4aM::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||||
{
|
{
|
||||||
static int const LBDelay = 100;
|
int const LBDelay { 100 };
|
||||||
static double const xpM = 0.3; // mnoznik membrany komory pod
|
double const xpM { 0.3 }; // mnoznik membrany komory pod
|
||||||
|
|
||||||
ep = (PP / 2.0) * 1.5 + (ep / 2.0) * 0.5; // SPKS!!
|
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 const ActFlowSpeed = BPT[ std::lround( i_bcp ) + 2 ][ 0 ];
|
||||||
|
|
||||||
double dpMainValve;
|
double dpMainValve = (
|
||||||
if( dpPipe > PP ) {
|
dpPipe > PP ?
|
||||||
dpMainValve = -PFVa( HP, PP, ActFlowSpeed / LBDelay, dpPipe, 0.4 );
|
-PFVa( HP, PP, ActFlowSpeed / LBDelay, dpPipe, 0.4 ) :
|
||||||
}
|
PFVd( PP, 0, ActFlowSpeed / LBDelay, dpPipe, 0.4 ) );
|
||||||
else {
|
|
||||||
dpMainValve = PFVd( PP, 0, ActFlowSpeed / LBDelay, dpPipe, 0.4 );
|
|
||||||
}
|
|
||||||
|
|
||||||
if (EQ(i_bcp, -1)) {
|
if (EQ(i_bcp, -1)) {
|
||||||
|
|
||||||
|
|||||||
55
Model3d.cpp
55
Model3d.cpp
@@ -106,7 +106,7 @@ int TSubModel::SeekFaceNormal(std::vector<unsigned int> const &Masks, int const
|
|||||||
// pętla po trójkątach, od trójkąta (f)
|
// pętla po trójkątach, od trójkąta (f)
|
||||||
if( Masks[ faceidx ] & Mask ) {
|
if( Masks[ faceidx ] & Mask ) {
|
||||||
// jeśli wspólna maska powierzchni
|
// jeśli wspólna maska powierzchni
|
||||||
for( int vertexidx = 0; vertexidx < 2; ++vertexidx ) {
|
for( int vertexidx = 0; vertexidx < 3; ++vertexidx ) {
|
||||||
if( Vertices[ 3 * faceidx + vertexidx ].position == Position ) {
|
if( Vertices[ 3 * faceidx + vertexidx ].position == Position ) {
|
||||||
return 3 * faceidx + vertexidx;
|
return 3 * faceidx + vertexidx;
|
||||||
}
|
}
|
||||||
@@ -374,11 +374,27 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
|
|||||||
// transformation matrix
|
// transformation matrix
|
||||||
fMatrix = new float4x4();
|
fMatrix = new float4x4();
|
||||||
readMatrix(parser, *fMatrix); // wczytanie transform
|
readMatrix(parser, *fMatrix); // wczytanie transform
|
||||||
if (!fMatrix->IdentityIs())
|
if( !fMatrix->IdentityIs() ) {
|
||||||
iFlags |= 0x8000; // transform niejedynkowy - trzeba go przechować
|
iFlags |= 0x8000; // transform niejedynkowy - trzeba go przechować
|
||||||
if( std::abs( Det( *fMatrix ) - 1.0f ) > 0.01f ) {
|
// check the scaling
|
||||||
ErrorLog( "Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factor: " + to_string( Det( *fMatrix ), 2 ) + ")" );
|
auto const matrix = glm::make_mat4( fMatrix->readArray() );
|
||||||
m_normalizenormals = true;
|
glm::vec3 const scale{
|
||||||
|
glm::length( glm::vec3( glm::column( matrix, 0 ) ) ),
|
||||||
|
glm::length( glm::vec3( glm::column( matrix, 1 ) ) ),
|
||||||
|
glm::length( glm::vec3( glm::column( matrix, 2 ) ) ) };
|
||||||
|
if( ( std::abs( scale.x - 1.0f ) > 0.01 )
|
||||||
|
|| ( std::abs( scale.y - 1.0f ) > 0.01 )
|
||||||
|
|| ( std::abs( scale.z - 1.0f ) > 0.01 ) ) {
|
||||||
|
ErrorLog(
|
||||||
|
"Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factors: "
|
||||||
|
+ to_string( scale.x, 2 ) + ", "
|
||||||
|
+ to_string( scale.y, 2 ) + ", "
|
||||||
|
+ to_string( scale.z, 2 ) + ")" );
|
||||||
|
m_normalizenormals = (
|
||||||
|
( ( std::abs( scale.x - scale.y ) < 0.01f ) && ( std::abs( scale.y - scale.z ) < 0.01f ) ) ?
|
||||||
|
rescale :
|
||||||
|
normalize );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (eType < TP_ROTATOR)
|
if (eType < TP_ROTATOR)
|
||||||
{ // wczytywanie wierzchołków
|
{ // wczytywanie wierzchołków
|
||||||
@@ -1539,7 +1555,7 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
|||||||
auto normallength = glm::length2( vertex.normal );
|
auto normallength = glm::length2( vertex.normal );
|
||||||
if( ( false == submodel.m_normalizenormals )
|
if( ( false == submodel.m_normalizenormals )
|
||||||
&& ( std::abs( normallength - 1.0f ) > 0.01f ) ) {
|
&& ( std::abs( normallength - 1.0f ) > 0.01f ) ) {
|
||||||
submodel.m_normalizenormals = true;
|
submodel.m_normalizenormals = TSubModel::normalize; // we don't know if uniform scaling would suffice
|
||||||
WriteLog( "Bad model: non-unit normal vector(s) encountered during sub-model geometry deserialization" );
|
WriteLog( "Bad model: non-unit normal vector(s) encountered during sub-model geometry deserialization" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1695,13 +1711,26 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
|
|||||||
|
|
||||||
iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem tablic)
|
iFlags &= ~0x0200; // wczytano z pliku binarnego (nie jest właścicielem tablic)
|
||||||
|
|
||||||
if( ( fMatrix != nullptr )
|
if( fMatrix != nullptr ) {
|
||||||
&& ( std::abs( Det( *fMatrix ) - 1.0f ) > 0.01f ) ) {
|
auto const matrix = glm::make_mat4( fMatrix->readArray() );
|
||||||
// check whether we need to enable normal vectors normalization for this submodel
|
glm::vec3 const scale {
|
||||||
ErrorLog( "Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factor: " + to_string( Det( *fMatrix ), 2 ) + ")" );
|
glm::length( glm::vec3( glm::column( matrix, 0 ) ) ),
|
||||||
m_normalizenormals = true;
|
glm::length( glm::vec3( glm::column( matrix, 1 ) ) ),
|
||||||
|
glm::length( glm::vec3( glm::column( matrix, 2 ) ) ) };
|
||||||
|
if( ( std::abs( scale.x - 1.0f ) > 0.01 )
|
||||||
|
|| ( std::abs( scale.y - 1.0f ) > 0.01 )
|
||||||
|
|| ( std::abs( scale.z - 1.0f ) > 0.01 ) ) {
|
||||||
|
ErrorLog(
|
||||||
|
"Bad model: transformation matrix for sub-model \"" + pName + "\" imposes geometry scaling (factors: "
|
||||||
|
+ to_string( scale.x, 2 ) + ", "
|
||||||
|
+ to_string( scale.y, 2 ) + ", "
|
||||||
|
+ to_string( scale.z, 2 ) + ")" );
|
||||||
|
m_normalizenormals = (
|
||||||
|
( ( std::abs( scale.x - scale.y ) < 0.01f ) && ( std::abs( scale.y - scale.z ) < 0.01f ) ) ?
|
||||||
|
rescale :
|
||||||
|
normalize );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void TModel3d::LoadFromBinFile(std::string const &FileName, bool dynamic)
|
void TModel3d::LoadFromBinFile(std::string const &FileName, bool dynamic)
|
||||||
|
|||||||
@@ -58,6 +58,13 @@ class TSubModel
|
|||||||
friend class TModel3d; // temporary workaround. TODO: clean up class content/hierarchy
|
friend class TModel3d; // temporary workaround. TODO: clean up class content/hierarchy
|
||||||
friend class TDynamicObject; // temporary etc
|
friend class TDynamicObject; // temporary etc
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum normalization {
|
||||||
|
none = 0,
|
||||||
|
rescale,
|
||||||
|
normalize
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int iNext{ NULL };
|
int iNext{ NULL };
|
||||||
int iChild{ NULL };
|
int iChild{ NULL };
|
||||||
@@ -96,7 +103,7 @@ private:
|
|||||||
f4Diffuse { 1.0f,1.0f,1.0f,1.0f },
|
f4Diffuse { 1.0f,1.0f,1.0f,1.0f },
|
||||||
f4Specular { 0.0f,0.0f,0.0f,1.0f },
|
f4Specular { 0.0f,0.0f,0.0f,1.0f },
|
||||||
f4Emision { 1.0f,1.0f,1.0f,1.0f };
|
f4Emision { 1.0f,1.0f,1.0f,1.0f };
|
||||||
bool m_normalizenormals { false }; // indicates vectors need to be normalized due to scaling etc
|
normalization m_normalizenormals { normalization::none }; // indicates vectors need to be normalized due to scaling etc
|
||||||
float fWireSize { 0.0f }; // nie używane, ale wczytywane
|
float fWireSize { 0.0f }; // nie używane, ale wczytywane
|
||||||
float fSquareMaxDist { 10000.0f * 10000.0f };
|
float fSquareMaxDist { 10000.0f * 10000.0f };
|
||||||
float fSquareMinDist { 0.0f };
|
float fSquareMinDist { 0.0f };
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
|
||||||
|
/*
|
||||||
#include "ResourceManager.h"
|
#include "ResourceManager.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
|
|
||||||
@@ -84,3 +86,4 @@ void ResourceManager::Sweep(double currentTime)
|
|||||||
|
|
||||||
_lastUpdate = currentTime;
|
_lastUpdate = currentTime;
|
||||||
};
|
};
|
||||||
|
*/
|
||||||
@@ -7,14 +7,11 @@ obtain one at
|
|||||||
http://mozilla.org/MPL/2.0/.
|
http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef RESOURCEMANAGER_H
|
#pragma once
|
||||||
#define RESOURCEMANAGER_H 1
|
/*
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#pragma hdrstop
|
|
||||||
|
|
||||||
class Resource
|
class Resource
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -57,5 +54,63 @@ class ResourceManager
|
|||||||
|
|
||||||
static Resources _resources;
|
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() };
|
||||||
|
};
|
||||||
|
|||||||
81
Texture.cpp
81
Texture.cpp
@@ -24,10 +24,12 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "sn_utils.h"
|
#include "sn_utils.h"
|
||||||
|
|
||||||
|
#define EU07_DEFERRED_TEXTURE_UPLOAD
|
||||||
|
|
||||||
texture_manager::texture_manager() {
|
texture_manager::texture_manager() {
|
||||||
|
|
||||||
// since index 0 is used to indicate no texture, we put a blank entry in the first texture slot
|
// 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
|
// loads texture data from specified file
|
||||||
@@ -518,12 +520,12 @@ opengl_texture::bind() {
|
|||||||
return data_state;
|
return data_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
resource_state
|
bool
|
||||||
opengl_texture::create() {
|
opengl_texture::create() {
|
||||||
|
|
||||||
if( data_state != resource_state::good ) {
|
if( data_state != resource_state::good ) {
|
||||||
// don't bother until we have useful texture data
|
// 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,
|
// TODO: consider creating and storing low-res version of the texture if it's ever unloaded from the gfx card,
|
||||||
@@ -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::none;
|
||||||
*/
|
*/
|
||||||
data_state = resource_state::good;
|
data_state = resource_state::none;
|
||||||
is_ready = true;
|
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
|
void
|
||||||
@@ -773,8 +804,8 @@ texture_manager::create( std::string Filename, std::string const &Dir, int const
|
|||||||
return npos;
|
return npos;
|
||||||
}
|
}
|
||||||
|
|
||||||
opengl_texture texture;
|
auto texture = new opengl_texture();
|
||||||
texture.name = filename;
|
texture->name = filename;
|
||||||
if( ( Filter > 0 ) && ( Filter < 10 ) ) {
|
if( ( Filter > 0 ) && ( Filter < 10 ) ) {
|
||||||
// temporary. TODO, TBD: check how it's used and possibly get rid of it
|
// temporary. TODO, TBD: check how it's used and possibly get rid of it
|
||||||
traits += std::to_string( ( Filter < 4 ? Filter + 4 : Filter ) );
|
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
|
// temporary code for legacy assets -- textures with names beginning with # are to be sharpened
|
||||||
traits += '#';
|
traits += '#';
|
||||||
}
|
}
|
||||||
texture.traits = traits;
|
texture->traits = traits;
|
||||||
auto const textureindex = (texture_handle)m_textures.size();
|
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 );
|
m_texturemappings.emplace( filename, textureindex );
|
||||||
|
|
||||||
WriteLog( "Created texture object for \"" + filename + "\"" );
|
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
|
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||||
texture_manager::texture( textureindex ).create();
|
texture_manager::texture( textureindex ).create();
|
||||||
// texture creation binds a different texture, force a re-bind on next use
|
// texture creation binds a different texture, force a re-bind on next use
|
||||||
m_activetexture = 0;
|
m_activetexture = -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -806,7 +837,9 @@ texture_manager::create( std::string Filename, std::string const &Dir, int const
|
|||||||
void
|
void
|
||||||
texture_manager::bind( texture_handle const Texture ) {
|
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
|
// don't bind again what's already active
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -815,7 +848,7 @@ texture_manager::bind( texture_handle const Texture ) {
|
|||||||
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
#ifndef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||||
// NOTE: we could bind dedicated 'error' texture here if the id isn't valid
|
// NOTE: we could bind dedicated 'error' texture here if the id isn't valid
|
||||||
::glBindTexture( GL_TEXTURE_2D, texture(Texture).id );
|
::glBindTexture( GL_TEXTURE_2D, texture(Texture).id );
|
||||||
m_activetexture = Texture;
|
m_activetexture = Texture;
|
||||||
#else
|
#else
|
||||||
if( texture( Texture ).bind() == resource_state::good ) {
|
if( texture( Texture ).bind() == resource_state::good ) {
|
||||||
m_activetexture = Texture;
|
m_activetexture = Texture;
|
||||||
@@ -838,10 +871,20 @@ void
|
|||||||
texture_manager::delete_textures() {
|
texture_manager::delete_textures() {
|
||||||
for( auto const &texture : m_textures ) {
|
for( auto const &texture : m_textures ) {
|
||||||
// usunięcie wszyskich tekstur (bez usuwania struktury)
|
// usunięcie wszyskich tekstur (bez usuwania struktury)
|
||||||
if( ( texture.id > 0 )
|
if( ( texture.first->id > 0 )
|
||||||
&& ( texture.id != -1 ) ) {
|
&& ( texture.first->id != -1 ) ) {
|
||||||
::glDeleteTextures( 1, &texture.id );
|
::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 ) {
|
for( auto const& texture : m_textures ) {
|
||||||
|
|
||||||
totaltexturesize += texture.size;
|
totaltexturesize += texture.first->size;
|
||||||
#ifdef EU07_DEFERRED_TEXTURE_UPLOAD
|
#ifdef EU07_DEFERRED_TEXTURE_UPLOAD
|
||||||
|
|
||||||
if( texture.is_ready ) {
|
if( texture.first->is_ready ) {
|
||||||
|
|
||||||
++readytexturecount;
|
++readytexturecount;
|
||||||
readytexturesize += texture.size;
|
readytexturesize += texture.first->size;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
41
Texture.h
41
Texture.h
@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include <ddraw.h>
|
#include <ddraw.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "GL/glew.h"
|
#include "GL/glew.h"
|
||||||
|
#include "ResourceManager.h"
|
||||||
|
|
||||||
enum class resource_state {
|
enum class resource_state {
|
||||||
none,
|
none,
|
||||||
@@ -27,12 +28,16 @@ struct opengl_texture {
|
|||||||
static DDPIXELFORMAT deserialize_ddpf(std::istream&);
|
static DDPIXELFORMAT deserialize_ddpf(std::istream&);
|
||||||
static DDSCAPS2 deserialize_ddscaps(std::istream&);
|
static DDSCAPS2 deserialize_ddscaps(std::istream&);
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
void load();
|
void
|
||||||
|
load();
|
||||||
resource_state
|
resource_state
|
||||||
bind();
|
bind();
|
||||||
resource_state
|
bool
|
||||||
create();
|
create();
|
||||||
|
// releases resources allocated on the opengl end, storing local copy if requested
|
||||||
|
void
|
||||||
|
release( bool const Backup = true );
|
||||||
inline
|
inline
|
||||||
int
|
int
|
||||||
width() const {
|
width() const {
|
||||||
@@ -41,7 +46,7 @@ struct opengl_texture {
|
|||||||
int
|
int
|
||||||
height() const {
|
height() const {
|
||||||
return data_height; }
|
return data_height; }
|
||||||
// members
|
// members
|
||||||
GLuint id{ (GLuint)-1 }; // associated GL resource
|
GLuint id{ (GLuint)-1 }; // associated GL resource
|
||||||
bool has_alpha{ false }; // indicates the texture has alpha channel
|
bool has_alpha{ false }; // indicates the texture has alpha channel
|
||||||
bool is_ready{ false }; // indicates the texture was processed and is ready for use
|
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
|
std::size_t size{ 0 }; // size of the texture data, in kb
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// methods
|
// methods
|
||||||
void load_BMP();
|
void load_BMP();
|
||||||
void load_DDS();
|
void load_DDS();
|
||||||
void load_TEX();
|
void load_TEX();
|
||||||
@@ -58,7 +63,7 @@ private:
|
|||||||
void set_filtering();
|
void set_filtering();
|
||||||
void downsize( GLuint const Format );
|
void downsize( GLuint const Format );
|
||||||
|
|
||||||
// members
|
// members
|
||||||
std::vector<char> data; // texture data
|
std::vector<char> data; // texture data
|
||||||
resource_state data_state{ resource_state::none }; // current state of texture data
|
resource_state data_state{ resource_state::none }; // current state of texture data
|
||||||
int data_width{ 0 },
|
int data_width{ 0 },
|
||||||
@@ -76,9 +81,6 @@ typedef int texture_handle;
|
|||||||
|
|
||||||
class texture_manager {
|
class texture_manager {
|
||||||
|
|
||||||
private:
|
|
||||||
typedef std::vector<opengl_texture> opengltexture_array;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
texture_manager();
|
texture_manager();
|
||||||
~texture_manager() { delete_textures(); }
|
~texture_manager() { delete_textures(); }
|
||||||
@@ -88,14 +90,25 @@ public:
|
|||||||
void
|
void
|
||||||
bind( texture_handle const Texture );
|
bind( texture_handle const Texture );
|
||||||
opengl_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
|
// debug performance string
|
||||||
std::string
|
std::string
|
||||||
info() const;
|
info() const;
|
||||||
|
|
||||||
private:
|
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;
|
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.
|
// checks whether specified texture is in the texture bank. returns texture id, or npos.
|
||||||
texture_handle
|
texture_handle
|
||||||
find_in_databank( std::string const &Texturename ) const;
|
find_in_databank( std::string const &Texturename ) const;
|
||||||
@@ -105,10 +118,12 @@ private:
|
|||||||
void
|
void
|
||||||
delete_textures();
|
delete_textures();
|
||||||
|
|
||||||
static const texture_handle npos{ 0 }; // should be -1, but the rest of the code uses -1 for something else
|
// members:
|
||||||
opengltexture_array m_textures;
|
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;
|
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
|
// reduces provided data image to half of original size, using basic 2x2 average
|
||||||
|
|||||||
174
Train.cpp
174
Train.cpp
@@ -1225,24 +1225,28 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
|
|||||||
// sound feedback
|
// sound feedback
|
||||||
Train->play_sound( Train->dsbSwitch );
|
Train->play_sound( Train->dsbSwitch );
|
||||||
// visual feedback
|
// visual feedback
|
||||||
if( Train->ggPantFrontButton.SubModel ) {
|
Train->ggPantFrontButton.UpdateValue( 1.0 );
|
||||||
Train->ggPantFrontButton.UpdateValue( 1.0 );
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
}
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
if( Train->ggPantFrontButtonOff.SubModel != nullptr ) {
|
Train->ggPantSelectedButton.UpdateValue( 1.0 );
|
||||||
// pantograph control can have two-button setup
|
// pantograph control can have two-button setup
|
||||||
Train->ggPantFrontButtonOff.UpdateValue( 0.0 );
|
Train->ggPantFrontButtonOff.UpdateValue( 0.0 );
|
||||||
}
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
Train->ggPantSelectedDownButton.UpdateValue( 0.0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// ...or turn off
|
// ...or turn off
|
||||||
if( ( Train->mvOccupied->PantSwitchType == "impulse" )
|
if( Train->mvOccupied->PantSwitchType == "impulse" ) {
|
||||||
&& ( Train->ggPantFrontButtonOff.SubModel == nullptr ) ) {
|
if( ( Train->ggPantFrontButtonOff.SubModel == nullptr )
|
||||||
// with impulse buttons we expect a dedicated switch to lower the pantograph, and if the cabin lacks it
|
&& ( Train->ggPantSelectedDownButton.SubModel == nullptr ) ) {
|
||||||
// then another control has to be used (like pantographlowerall)
|
// with impulse buttons we expect a dedicated switch to lower the pantograph, and if the cabin lacks it
|
||||||
// TODO: we should have a way to define presense of cab controls without having to bind these to 3d submodels
|
// then another control has to be used (like pantographlowerall)
|
||||||
return;
|
// TODO: we should have a way to define presense of cab controls without having to bind these to 3d submodels
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Train->mvControlled->PantFrontSP = false;
|
Train->mvControlled->PantFrontSP = false;
|
||||||
@@ -1252,8 +1256,14 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
|
|||||||
Train->play_sound( Train->dsbSwitch );
|
Train->play_sound( Train->dsbSwitch );
|
||||||
// visual feedback
|
// visual feedback
|
||||||
Train->ggPantFrontButton.UpdateValue( 0.0 );
|
Train->ggPantFrontButton.UpdateValue( 0.0 );
|
||||||
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
Train->ggPantSelectedButton.UpdateValue( 0.0 );
|
||||||
// pantograph control can have two-button setup
|
// pantograph control can have two-button setup
|
||||||
Train->ggPantFrontButtonOff.UpdateValue( 1.0 );
|
Train->ggPantFrontButtonOff.UpdateValue( 1.0 );
|
||||||
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
Train->ggPantSelectedDownButton.UpdateValue( 1.0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1264,9 +1274,10 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
|
|||||||
if( Train->ggPantFrontButton.GetValue() > 0.35 ) {
|
if( Train->ggPantFrontButton.GetValue() > 0.35 ) {
|
||||||
Train->play_sound( Train->dsbSwitch );
|
Train->play_sound( Train->dsbSwitch );
|
||||||
}
|
}
|
||||||
if( Train->ggPantFrontButton.SubModel ) {
|
Train->ggPantFrontButton.UpdateValue( 0.0 );
|
||||||
Train->ggPantFrontButton.UpdateValue( 0.0 );
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
}
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
Train->ggPantSelectedButton.UpdateValue( 0.0 );
|
||||||
// also the switch off button, in cabs which have it
|
// also the switch off button, in cabs which have it
|
||||||
if( Train->ggPantFrontButtonOff.GetValue() > 0.35 ) {
|
if( Train->ggPantFrontButtonOff.GetValue() > 0.35 ) {
|
||||||
Train->play_sound( Train->dsbSwitch );
|
Train->play_sound( Train->dsbSwitch );
|
||||||
@@ -1274,6 +1285,11 @@ void TTrain::OnCommand_pantographtogglefront( TTrain *Train, command_data const
|
|||||||
if( Train->ggPantFrontButtonOff.SubModel ) {
|
if( Train->ggPantFrontButtonOff.SubModel ) {
|
||||||
Train->ggPantFrontButtonOff.UpdateValue( 0.0 );
|
Train->ggPantFrontButtonOff.UpdateValue( 0.0 );
|
||||||
}
|
}
|
||||||
|
if( Train->ggPantSelectedDownButton.SubModel ) {
|
||||||
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
Train->ggPantSelectedDownButton.UpdateValue( 0.0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1290,24 +1306,28 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
|
|||||||
// sound feedback
|
// sound feedback
|
||||||
Train->play_sound( Train->dsbSwitch );
|
Train->play_sound( Train->dsbSwitch );
|
||||||
// visual feedback
|
// visual feedback
|
||||||
if( Train->ggPantRearButton.SubModel ) {
|
Train->ggPantRearButton.UpdateValue( 1.0 );
|
||||||
Train->ggPantRearButton.UpdateValue( 1.0 );
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
}
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
if( Train->ggPantRearButtonOff.SubModel != nullptr ) {
|
Train->ggPantSelectedButton.UpdateValue( 1.0 );
|
||||||
// pantograph control can have two-button setup
|
// pantograph control can have two-button setup
|
||||||
Train->ggPantRearButtonOff.UpdateValue( 0.0 );
|
Train->ggPantRearButtonOff.UpdateValue( 0.0 );
|
||||||
}
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
Train->ggPantSelectedDownButton.UpdateValue( 0.0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// ...or turn off
|
// ...or turn off
|
||||||
if( ( Train->mvOccupied->PantSwitchType == "impulse" )
|
if( Train->mvOccupied->PantSwitchType == "impulse" ) {
|
||||||
&& ( Train->ggPantRearButtonOff.SubModel == nullptr ) ) {
|
if( ( Train->ggPantRearButtonOff.SubModel == nullptr )
|
||||||
// with impulse buttons we expect a dedicated switch to lower the pantograph, and if the cabin lacks it
|
&& ( Train->ggPantSelectedDownButton.SubModel == nullptr ) ) {
|
||||||
// then another control has to be used (like pantographlowerall)
|
// with impulse buttons we expect a dedicated switch to lower the pantograph, and if the cabin lacks it
|
||||||
// TODO: we should have a way to define presense of cab controls without having to bind these to 3d submodels
|
// then another control has to be used (like pantographlowerall)
|
||||||
return;
|
// TODO: we should have a way to define presense of cab controls without having to bind these to 3d submodels
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Train->mvControlled->PantRearSP = false;
|
Train->mvControlled->PantRearSP = false;
|
||||||
@@ -1317,8 +1337,14 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
|
|||||||
Train->play_sound( Train->dsbSwitch );
|
Train->play_sound( Train->dsbSwitch );
|
||||||
// visual feedback
|
// visual feedback
|
||||||
Train->ggPantRearButton.UpdateValue( 0.0 );
|
Train->ggPantRearButton.UpdateValue( 0.0 );
|
||||||
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
Train->ggPantSelectedButton.UpdateValue( 0.0 );
|
||||||
// pantograph control can have two-button setup
|
// pantograph control can have two-button setup
|
||||||
Train->ggPantRearButtonOff.UpdateValue( 1.0 );
|
Train->ggPantRearButtonOff.UpdateValue( 1.0 );
|
||||||
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
Train->ggPantSelectedDownButton.UpdateValue( 1.0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1329,9 +1355,10 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
|
|||||||
if( Train->ggPantRearButton.GetValue() > 0.35 ) {
|
if( Train->ggPantRearButton.GetValue() > 0.35 ) {
|
||||||
Train->play_sound( Train->dsbSwitch );
|
Train->play_sound( Train->dsbSwitch );
|
||||||
}
|
}
|
||||||
if( Train->ggPantRearButton.SubModel ) {
|
Train->ggPantRearButton.UpdateValue( 0.0 );
|
||||||
Train->ggPantRearButton.UpdateValue( 0.0 );
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
}
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
Train->ggPantSelectedButton.UpdateValue( 0.0 );
|
||||||
// also the switch off button, in cabs which have it
|
// also the switch off button, in cabs which have it
|
||||||
if( Train->ggPantRearButtonOff.GetValue() > 0.35 ) {
|
if( Train->ggPantRearButtonOff.GetValue() > 0.35 ) {
|
||||||
Train->play_sound( Train->dsbSwitch );
|
Train->play_sound( Train->dsbSwitch );
|
||||||
@@ -1339,6 +1366,11 @@ void TTrain::OnCommand_pantographtogglerear( TTrain *Train, command_data const &
|
|||||||
if( Train->ggPantRearButtonOff.SubModel ) {
|
if( Train->ggPantRearButtonOff.SubModel ) {
|
||||||
Train->ggPantRearButtonOff.UpdateValue( 0.0 );
|
Train->ggPantRearButtonOff.UpdateValue( 0.0 );
|
||||||
}
|
}
|
||||||
|
if( Train->ggPantSelectedDownButton.SubModel ) {
|
||||||
|
// NOTE: currently we animate the selectable pantograph control based on standard key presses
|
||||||
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
Train->ggPantSelectedDownButton.UpdateValue( 0.0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1400,7 +1432,8 @@ void TTrain::OnCommand_pantographcompressoractivate( TTrain *Train, command_data
|
|||||||
|
|
||||||
void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Command ) {
|
void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Command ) {
|
||||||
|
|
||||||
if( Train->ggPantAllDownButton.SubModel == nullptr ) {
|
if( ( Train->ggPantAllDownButton.SubModel == nullptr )
|
||||||
|
&& ( Train->ggPantSelectedDownButton.SubModel == nullptr ) ) {
|
||||||
// TODO: expand definition of cab controls so we can know if the control is present without testing for presence of 3d switch
|
// TODO: expand definition of cab controls so we can know if the control is present without testing for presence of 3d switch
|
||||||
if( Command.action == GLFW_PRESS ) {
|
if( Command.action == GLFW_PRESS ) {
|
||||||
WriteLog( "Lower All Pantographs switch is missing, or wasn't defined" );
|
WriteLog( "Lower All Pantographs switch is missing, or wasn't defined" );
|
||||||
@@ -1423,6 +1456,9 @@ void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Co
|
|||||||
}
|
}
|
||||||
// visual feedback
|
// visual feedback
|
||||||
Train->ggPantAllDownButton.UpdateValue( 1.0 );
|
Train->ggPantAllDownButton.UpdateValue( 1.0 );
|
||||||
|
if( Train->ggPantSelectedDownButton.SubModel != nullptr ) {
|
||||||
|
Train->ggPantSelectedDownButton.UpdateValue( 1.0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if( Command.action == GLFW_RELEASE ) {
|
else if( Command.action == GLFW_RELEASE ) {
|
||||||
// release the button
|
// release the button
|
||||||
@@ -1436,6 +1472,9 @@ void TTrain::OnCommand_pantographlowerall( TTrain *Train, command_data const &Co
|
|||||||
*/
|
*/
|
||||||
// visual feedback
|
// visual feedback
|
||||||
Train->ggPantAllDownButton.UpdateValue( 0.0 );
|
Train->ggPantAllDownButton.UpdateValue( 0.0 );
|
||||||
|
if( Train->ggPantSelectedDownButton.SubModel != nullptr ) {
|
||||||
|
Train->ggPantSelectedDownButton.UpdateValue( 0.0 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1485,8 +1524,8 @@ void TTrain::OnCommand_linebreakertoggle( TTrain *Train, command_data const &Com
|
|||||||
Train->ggMainButton.UpdateValue( 1.0 );
|
Train->ggMainButton.UpdateValue( 1.0 );
|
||||||
}
|
}
|
||||||
// keep track of period the button is held down, to determine when/if circuit closes
|
// keep track of period the button is held down, to determine when/if circuit closes
|
||||||
if( ( false == ( ( Train->mvControlled->EngineType == ElectricSeriesMotor )
|
if( ( ( ( Train->mvControlled->EngineType != ElectricSeriesMotor )
|
||||||
|| ( Train->mvControlled->EngineType == ElectricInductionMotor ) ) )
|
&& ( Train->mvControlled->EngineType != ElectricInductionMotor ) ) )
|
||||||
|| ( Train->fHVoltage > 0.5 * Train->mvControlled->EnginePowerSource.MaxVoltage ) ) {
|
|| ( Train->fHVoltage > 0.5 * Train->mvControlled->EnginePowerSource.MaxVoltage ) ) {
|
||||||
// prevent the switch from working if there's no power
|
// prevent the switch from working if there's no power
|
||||||
// TODO: consider whether it makes sense for diesel engines and such
|
// TODO: consider whether it makes sense for diesel engines and such
|
||||||
@@ -4830,15 +4869,10 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
// NBMX wrzesien 2003 - drzwi
|
// NBMX wrzesien 2003 - drzwi
|
||||||
ggDoorLeftButton.Update();
|
ggDoorLeftButton.Update();
|
||||||
ggDoorRightButton.Update();
|
ggDoorRightButton.Update();
|
||||||
ggDepartureSignalButton.Update();
|
ggDoorSignallingButton.Update();
|
||||||
// NBMX dzwignia sprezarki
|
// NBMX dzwignia sprezarki
|
||||||
ggCompressorButton.Update();
|
ggCompressorButton.Update();
|
||||||
ggCompressorLocalButton.Update();
|
ggCompressorLocalButton.Update();
|
||||||
ggMainButton.Update();
|
|
||||||
ggRadioButton.Update();
|
|
||||||
ggConverterButton.Update();
|
|
||||||
ggConverterLocalButton.Update();
|
|
||||||
ggConverterOffButton.Update();
|
|
||||||
|
|
||||||
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
|
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
|
||||||
if( ( ( DynamicObject->iLights[ 0 ] ) == 0 ) && ( ( DynamicObject->iLights[ 1 ] ) == 0 ) )
|
if( ( ( DynamicObject->iLights[ 0 ] ) == 0 ) && ( ( DynamicObject->iLights[ 1 ] ) == 0 ) )
|
||||||
@@ -4989,15 +5023,6 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
}
|
}
|
||||||
ggDimHeadlightsButton.Update();
|
ggDimHeadlightsButton.Update();
|
||||||
//---------
|
//---------
|
||||||
// Winger 010304 - pantografy
|
|
||||||
// NOTE: shouldn't the pantograph updates check whether it's front or rear cabin?
|
|
||||||
ggPantFrontButton.Update();
|
|
||||||
ggPantRearButton.Update();
|
|
||||||
ggPantFrontButtonOff.Update();
|
|
||||||
ggTrainHeatingButton.Update();
|
|
||||||
ggSignallingButton.Update();
|
|
||||||
ggDoorSignallingButton.Update();
|
|
||||||
// Winger 020304 - ogrzewanie
|
|
||||||
// hunter-080812: poprawka na ogrzewanie w elektrykach - usuniete uzaleznienie od przetwornicy
|
// hunter-080812: poprawka na ogrzewanie w elektrykach - usuniete uzaleznienie od przetwornicy
|
||||||
if ((((mvControlled->EngineType == ElectricSeriesMotor) && (mvControlled->Mains == true) &&
|
if ((((mvControlled->EngineType == ElectricSeriesMotor) && (mvControlled->Mains == true) &&
|
||||||
(mvControlled->ConvOvldFlag == false)) ||
|
(mvControlled->ConvOvldFlag == false)) ||
|
||||||
@@ -5813,10 +5838,15 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
ggStLinOffButton.Update();
|
ggStLinOffButton.Update();
|
||||||
ggRadioButton.Update();
|
ggRadioButton.Update();
|
||||||
ggDepartureSignalButton.Update();
|
ggDepartureSignalButton.Update();
|
||||||
|
|
||||||
ggPantFrontButton.Update();
|
ggPantFrontButton.Update();
|
||||||
ggPantRearButton.Update();
|
ggPantRearButton.Update();
|
||||||
|
ggPantSelectedButton.Update();
|
||||||
ggPantFrontButtonOff.Update();
|
ggPantFrontButtonOff.Update();
|
||||||
ggPantRearButtonOff.Update();
|
ggPantRearButtonOff.Update();
|
||||||
|
ggPantSelectedDownButton.Update();
|
||||||
|
ggPantAllDownButton.Update();
|
||||||
|
|
||||||
ggUpperLightButton.Update();
|
ggUpperLightButton.Update();
|
||||||
ggLeftLightButton.Update();
|
ggLeftLightButton.Update();
|
||||||
ggRightLightButton.Update();
|
ggRightLightButton.Update();
|
||||||
@@ -5829,8 +5859,8 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
ggRearLeftEndLightButton.Update();
|
ggRearLeftEndLightButton.Update();
|
||||||
ggRearRightEndLightButton.Update();
|
ggRearRightEndLightButton.Update();
|
||||||
//------------
|
//------------
|
||||||
ggPantAllDownButton.Update();
|
|
||||||
ggConverterButton.Update();
|
ggConverterButton.Update();
|
||||||
|
ggConverterLocalButton.Update();
|
||||||
ggConverterOffButton.Update();
|
ggConverterOffButton.Update();
|
||||||
ggTrainHeatingButton.Update();
|
ggTrainHeatingButton.Update();
|
||||||
ggSignallingButton.Update();
|
ggSignallingButton.Update();
|
||||||
@@ -6630,7 +6660,6 @@ void TTrain::SetLights()
|
|||||||
// clears state of all cabin controls
|
// clears state of all cabin controls
|
||||||
void TTrain::clear_cab_controls()
|
void TTrain::clear_cab_controls()
|
||||||
{
|
{
|
||||||
|
|
||||||
ggMainCtrl.Clear();
|
ggMainCtrl.Clear();
|
||||||
ggMainCtrlAct.Clear();
|
ggMainCtrlAct.Clear();
|
||||||
ggScndCtrl.Clear();
|
ggScndCtrl.Clear();
|
||||||
@@ -6670,7 +6699,10 @@ void TTrain::clear_cab_controls()
|
|||||||
ggConverterButton.Clear();
|
ggConverterButton.Clear();
|
||||||
ggPantFrontButton.Clear();
|
ggPantFrontButton.Clear();
|
||||||
ggPantRearButton.Clear();
|
ggPantRearButton.Clear();
|
||||||
|
ggPantSelectedButton.Clear();
|
||||||
ggPantFrontButtonOff.Clear();
|
ggPantFrontButtonOff.Clear();
|
||||||
|
ggPantRearButtonOff.Clear();
|
||||||
|
ggPantSelectedDownButton.Clear();
|
||||||
ggPantAllDownButton.Clear();
|
ggPantAllDownButton.Clear();
|
||||||
ggZbS.Clear();
|
ggZbS.Clear();
|
||||||
ggI1B.Clear();
|
ggI1B.Clear();
|
||||||
@@ -6787,6 +6819,16 @@ void TTrain::set_cab_controls() {
|
|||||||
( mvControlled->PantFrontUp ?
|
( mvControlled->PantFrontUp ?
|
||||||
0.0 :
|
0.0 :
|
||||||
1.0 ) );
|
1.0 ) );
|
||||||
|
// NOTE: currently we animate the selectable pantograph control for both pantographs
|
||||||
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
ggPantSelectedButton.PutValue(
|
||||||
|
( mvControlled->PantFrontUp ?
|
||||||
|
1.0 :
|
||||||
|
0.0 ) );
|
||||||
|
ggPantSelectedDownButton.PutValue(
|
||||||
|
( mvControlled->PantFrontUp ?
|
||||||
|
0.0 :
|
||||||
|
1.0 ) );
|
||||||
}
|
}
|
||||||
if( mvOccupied->PantSwitchType != "impulse" ) {
|
if( mvOccupied->PantSwitchType != "impulse" ) {
|
||||||
ggPantRearButton.PutValue(
|
ggPantRearButton.PutValue(
|
||||||
@@ -6797,6 +6839,16 @@ void TTrain::set_cab_controls() {
|
|||||||
( mvControlled->PantRearUp ?
|
( mvControlled->PantRearUp ?
|
||||||
0.0 :
|
0.0 :
|
||||||
1.0 ) );
|
1.0 ) );
|
||||||
|
// NOTE: currently we animate the selectable pantograph control for both pantographs
|
||||||
|
// TODO: implement actual selection control, and refactor handling this control setup in a separate method
|
||||||
|
ggPantSelectedButton.PutValue(
|
||||||
|
( mvControlled->PantRearUp ?
|
||||||
|
1.0 :
|
||||||
|
0.0 ) );
|
||||||
|
ggPantSelectedDownButton.PutValue(
|
||||||
|
( mvControlled->PantRearUp ?
|
||||||
|
0.0 :
|
||||||
|
1.0 ) );
|
||||||
}
|
}
|
||||||
// converter
|
// converter
|
||||||
if( mvOccupied->ConvSwitchType != "impulse" ) {
|
if( mvOccupied->ConvSwitchType != "impulse" ) {
|
||||||
@@ -7397,16 +7449,22 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
|||||||
ggPantFrontButtonOff.Load(Parser, DynamicObject->mdKabina);
|
ggPantFrontButtonOff.Load(Parser, DynamicObject->mdKabina);
|
||||||
}
|
}
|
||||||
else if( Label == "pantrearoff_sw:" ) {
|
else if( Label == "pantrearoff_sw:" ) {
|
||||||
// patyk przedni w dol
|
// rear pant down
|
||||||
ggPantRearButtonOff.Load( Parser, DynamicObject->mdKabina );
|
ggPantRearButtonOff.Load( Parser, DynamicObject->mdKabina );
|
||||||
}
|
}
|
||||||
else if( Label == "pantalloff_sw:" )
|
else if( Label == "pantalloff_sw:" ) {
|
||||||
{
|
// both pantographs down
|
||||||
// patyk przedni w dol
|
|
||||||
ggPantAllDownButton.Load(Parser, DynamicObject->mdKabina);
|
ggPantAllDownButton.Load(Parser, DynamicObject->mdKabina);
|
||||||
}
|
}
|
||||||
else if (Label == "trainheating_sw:")
|
else if( Label == "pantselected_sw:" ) {
|
||||||
{
|
// operate selected pantograph(s)
|
||||||
|
ggPantSelectedButton.Load( Parser, DynamicObject->mdKabina );
|
||||||
|
}
|
||||||
|
else if( Label == "pantselectedoff_sw:" ) {
|
||||||
|
// operate selected pantograph(s)
|
||||||
|
ggPantSelectedDownButton.Load( Parser, DynamicObject->mdKabina );
|
||||||
|
}
|
||||||
|
else if (Label == "trainheating_sw:") {
|
||||||
// grzanie skladu
|
// grzanie skladu
|
||||||
ggTrainHeatingButton.Load(Parser, DynamicObject->mdKabina);
|
ggTrainHeatingButton.Load(Parser, DynamicObject->mdKabina);
|
||||||
}
|
}
|
||||||
|
|||||||
2
Train.h
2
Train.h
@@ -285,6 +285,8 @@ public: // reszta może by?publiczna
|
|||||||
TGauge ggPantFrontButtonOff; // EZT
|
TGauge ggPantFrontButtonOff; // EZT
|
||||||
TGauge ggPantRearButtonOff;
|
TGauge ggPantRearButtonOff;
|
||||||
TGauge ggPantAllDownButton;
|
TGauge ggPantAllDownButton;
|
||||||
|
TGauge ggPantSelectedButton;
|
||||||
|
TGauge ggPantSelectedDownButton;
|
||||||
// Winger 020304 - wlacznik ogrzewania
|
// Winger 020304 - wlacznik ogrzewania
|
||||||
TGauge ggTrainHeatingButton;
|
TGauge ggTrainHeatingButton;
|
||||||
TGauge ggSignallingButton;
|
TGauge ggSignallingButton;
|
||||||
|
|||||||
@@ -1251,7 +1251,9 @@ void TWorld::Update_Environment() {
|
|||||||
|
|
||||||
void TWorld::ResourceSweep()
|
void TWorld::ResourceSweep()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
ResourceManager::Sweep( Timer::GetSimulationTime() );
|
ResourceManager::Sweep( Timer::GetSimulationTime() );
|
||||||
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
// rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana
|
// rendering kabiny gdy jest oddzielnym modelem i ma byc wyswietlana
|
||||||
@@ -1284,7 +1286,7 @@ TWorld::Render_Cab() {
|
|||||||
glMultMatrixd( dynamic->mMatrix.getArray() ); // ta macierz nie ma przesunięcia
|
glMultMatrixd( dynamic->mMatrix.getArray() ); // ta macierz nie ma przesunięcia
|
||||||
*/
|
*/
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
auto const originoffset = dynamic->GetPosition() - Global::pCameraPosition;
|
auto const originoffset = dynamic->GetPosition() - GfxRenderer.m_camera.position();
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
::glMultMatrixd( dynamic->mMatrix.getArray() );
|
::glMultMatrixd( dynamic->mMatrix.getArray() );
|
||||||
|
|
||||||
@@ -1657,7 +1659,7 @@ TWorld::Update_UI() {
|
|||||||
uitextline1 += " (slowmotion " + to_string( Global::iSlowMotion ) + ")";
|
uitextline1 += " (slowmotion " + to_string( Global::iSlowMotion ) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
uitextline2 = GfxRenderer.Info();
|
|
||||||
|
|
||||||
// dump last opengl error, if any
|
// dump last opengl error, if any
|
||||||
GLenum glerror = ::glGetError();
|
GLenum glerror = ::glGetError();
|
||||||
|
|||||||
@@ -357,25 +357,7 @@ opengl_dlgeometrybank::delete_list( geometry_handle const &Geometry ) {
|
|||||||
void
|
void
|
||||||
geometrybank_manager::update() {
|
geometrybank_manager::update() {
|
||||||
|
|
||||||
m_resourcetimestamp = std::chrono::steady_clock::now();
|
m_garbagecollector.sweep();
|
||||||
// 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 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// creates a new geometry bank. returns: handle to the bank or NULL
|
// creates a new geometry bank. returns: handle to the bank or NULL
|
||||||
@@ -418,7 +400,7 @@ geometrybank_manager::draw( geometry_handle const &Geometry, unsigned int const
|
|||||||
|
|
||||||
auto &bankrecord = bank( Geometry );
|
auto &bankrecord = bank( Geometry );
|
||||||
|
|
||||||
bankrecord.second = m_resourcetimestamp;
|
bankrecord.second = m_garbagecollector.timestamp();
|
||||||
bankrecord.first->draw( Geometry, Streams );
|
bankrecord.first->draw( Geometry, Streams );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
#include "GL/wglew.h"
|
#include "GL/wglew.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "ResourceManager.h"
|
||||||
|
|
||||||
struct basic_vertex {
|
struct basic_vertex {
|
||||||
|
|
||||||
@@ -276,9 +277,9 @@ public:
|
|||||||
template <typename Iterator_>
|
template <typename Iterator_>
|
||||||
void
|
void
|
||||||
draw( Iterator_ First, Iterator_ Last, unsigned int const Streams = basic_streams ) {
|
draw( Iterator_ First, Iterator_ Last, unsigned int const Streams = basic_streams ) {
|
||||||
while( First != Last ) {
|
while( First != Last ) {
|
||||||
draw( *First, Streams );
|
draw( *First, Streams );
|
||||||
++First; } }
|
++First; } }
|
||||||
// provides direct access to vertex data of specfied chunk
|
// provides direct access to vertex data of specfied chunk
|
||||||
vertex_array const &
|
vertex_array const &
|
||||||
vertices( geometry_handle const &Geometry ) const;
|
vertices( geometry_handle const &Geometry ) const;
|
||||||
@@ -291,12 +292,9 @@ private:
|
|||||||
|
|
||||||
typedef std::deque< geometrybanktimepoint_pair > geometrybanktimepointpair_sequence;
|
typedef std::deque< geometrybanktimepoint_pair > geometrybanktimepointpair_sequence;
|
||||||
|
|
||||||
// members:
|
// members:
|
||||||
std::chrono::nanoseconds const unusedresourcetimetolive { std::chrono::seconds { 60 } };
|
|
||||||
geometrybanktimepointpair_sequence::size_type const unusedresourcesweepsize { 300 };
|
|
||||||
geometrybanktimepointpair_sequence m_geometrybanks;
|
geometrybanktimepointpair_sequence m_geometrybanks;
|
||||||
geometrybanktimepointpair_sequence::size_type m_resourcesweepindex { 0 };
|
garbage_collector<geometrybanktimepointpair_sequence> m_garbagecollector { m_geometrybanks, 60, 120, "geometry buffer" };
|
||||||
std::chrono::steady_clock::time_point m_resourcetimestamp { std::chrono::steady_clock::now() };
|
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
inline
|
inline
|
||||||
|
|||||||
53
renderer.cpp
53
renderer.cpp
@@ -179,11 +179,17 @@ opengl_renderer::Render() {
|
|||||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||||
glViewport(0, 0, Global::shadowtune.map_size, Global::shadowtune.map_size);
|
glViewport(0, 0, Global::shadowtune.map_size, Global::shadowtune.map_size);
|
||||||
|
|
||||||
|
glm::mat4 coordmove(
|
||||||
|
0.5, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.5, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.5, 0.0,
|
||||||
|
0.5, 0.5, 0.5, 1.0
|
||||||
|
);
|
||||||
glm::mat4 depthproj = glm::ortho(-Global::shadowtune.width, Global::shadowtune.width,
|
glm::mat4 depthproj = glm::ortho(-Global::shadowtune.width, Global::shadowtune.width,
|
||||||
-Global::shadowtune.width, Global::shadowtune.width, 0.0f, Global::shadowtune.depth);
|
-Global::shadowtune.width, Global::shadowtune.width, 0.0f, Global::shadowtune.depth);
|
||||||
glm::vec3 playerpos = glm::vec3(World.Camera.Pos.x, World.Camera.Pos.y, World.Camera.Pos.z);
|
glm::vec3 playerpos = glm::vec3(World.Camera.Pos.x, World.Camera.Pos.y, World.Camera.Pos.z);
|
||||||
glm::vec3 shadoweye = playerpos - Global::daylight.direction * Global::shadowtune.distance;
|
glm::vec3 shadoweye = playerpos - Global::daylight.direction * Global::shadowtune.distance;
|
||||||
Global::SetCameraPosition(Math3D::vector3(0.0f, 0.0f, 0.0f));
|
m_camera.position() = shadoweye;
|
||||||
glm::mat4 depthcam = glm::lookAt(shadoweye,
|
glm::mat4 depthcam = glm::lookAt(shadoweye,
|
||||||
playerpos,
|
playerpos,
|
||||||
glm::vec3(0.0f, 1.0f, 0.0f));
|
glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
@@ -191,13 +197,15 @@ opengl_renderer::Render() {
|
|||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadMatrixf(glm::value_ptr(depthproj));
|
glLoadMatrixf(glm::value_ptr(depthproj));
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glMultMatrixf(glm::value_ptr(depthcam));
|
glMultMatrixd(glm::value_ptr(glm::mat4(glm::mat3(depthcam))));
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, depth_fbo);
|
||||||
glClear(GL_DEPTH_BUFFER_BIT);
|
glClear(GL_DEPTH_BUFFER_BIT);
|
||||||
|
glCullFace(GL_FRONT);
|
||||||
active_shader = &depth_shader; depth_shader.bind();
|
active_shader = &depth_shader; depth_shader.bind();
|
||||||
Render(&World.Ground);
|
Render(&World.Ground);
|
||||||
active_shader = nullptr; depth_shader.unbind();
|
active_shader = nullptr; depth_shader.unbind();
|
||||||
|
glCullFace(GL_BACK);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
glViewport(0, 0, Global::ScreenWidth, Global::ScreenHeight);
|
glViewport(0, 0, Global::ScreenWidth, Global::ScreenHeight);
|
||||||
@@ -210,19 +218,19 @@ opengl_renderer::Render() {
|
|||||||
glBindTexture(GL_TEXTURE_2D, depth_tex);
|
glBindTexture(GL_TEXTURE_2D, depth_tex);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
glm::dmat4 worldcamera;
|
glm::dmat4 worldcamera;
|
||||||
World.Camera.SetMatrix( worldcamera );
|
World.Camera.SetMatrix(worldcamera);
|
||||||
m_camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), worldcamera);
|
m_camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), worldcamera);
|
||||||
::glMultMatrixd(glm::value_ptr(worldcamera));
|
m_camera.position() = glm::make_vec3(Global::pCameraPosition.getArray());
|
||||||
|
glMultMatrixd(glm::value_ptr(glm::mat4(glm::mat3(worldcamera))));
|
||||||
shader.bind(); active_shader = &shader;
|
shader.bind(); active_shader = &shader;
|
||||||
|
shader.set_lightview(coordmove * depthproj * depthcam * glm::inverse(glm::mat4(worldcamera)));
|
||||||
glDebug("rendering environment");
|
glDebug("rendering environment");
|
||||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||||
Render( &World.Environment );
|
Render( &World.Environment );
|
||||||
glDebug("rendering world");
|
glDebug("rendering world");
|
||||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
|
|
||||||
Global::SetCameraPosition(Math3D::vector3(0.0f, 0.0f, 0.0f));
|
|
||||||
shader.set_lightview(depthproj * depthcam * glm::inverse(glm::mat4(worldcamera)));
|
|
||||||
Render( &World.Ground );
|
Render( &World.Ground );
|
||||||
|
|
||||||
glDebug("rendering cab");
|
glDebug("rendering cab");
|
||||||
@@ -251,7 +259,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bind( 0 );
|
Bind( NULL );
|
||||||
|
|
||||||
::glDisable( GL_LIGHTING );
|
::glDisable( GL_LIGHTING );
|
||||||
::glDisable( GL_DEPTH_TEST );
|
::glDisable( GL_DEPTH_TEST );
|
||||||
@@ -413,7 +421,7 @@ opengl_renderer::Bind( texture_handle const Texture ) {
|
|||||||
m_textures.bind( Texture );
|
m_textures.bind( Texture );
|
||||||
}
|
}
|
||||||
|
|
||||||
opengl_texture &
|
opengl_texture const &
|
||||||
opengl_renderer::Texture( texture_handle const Texture ) {
|
opengl_renderer::Texture( texture_handle const Texture ) {
|
||||||
|
|
||||||
return m_textures.texture( Texture );
|
return m_textures.texture( Texture );
|
||||||
@@ -442,7 +450,7 @@ opengl_renderer::Render( TGround *Ground ) {
|
|||||||
node->RenderHidden();
|
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 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 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 ));
|
int const segmentcount = 2 * static_cast<int>(std::ceil( m_drawrange * Global::fDistanceFactor / 1000.0f ));
|
||||||
@@ -515,7 +523,7 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
|||||||
if( subcell->iNodeCount ) {
|
if( subcell->iNodeCount ) {
|
||||||
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
||||||
m_drawqueue.emplace_back(
|
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 );
|
subcell );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -570,7 +578,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
{ // obiekty renderowane niezależnie od odległości
|
{ // obiekty renderowane niezależnie od odległości
|
||||||
case TP_SUBMODEL:
|
case TP_SUBMODEL:
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
auto const originoffset = Node->pCenter - Global::pCameraPosition;
|
auto const originoffset = Node->pCenter - m_camera.position();
|
||||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||||
TSubModel::fSquareDist = 0;
|
TSubModel::fSquareDist = 0;
|
||||||
Render( Node->smTerrain );
|
Render( Node->smTerrain );
|
||||||
@@ -578,13 +586,13 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
return true;
|
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 ) )
|
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
auto const originoffset = Node->m_rootposition - m_camera.position();
|
||||||
active_shader->set_mv(glm::translate(OpenGLMatrices.data(GL_MODELVIEW), glm::vec3(originoffset.x, originoffset.y, originoffset.z)));
|
active_shader->set_mv(glm::translate(OpenGLMatrices.data(GL_MODELVIEW), glm::vec3(originoffset.x, originoffset.y, originoffset.z)));
|
||||||
|
|
||||||
switch (Node->iType) {
|
switch (Node->iType) {
|
||||||
@@ -596,7 +604,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case TP_MODEL: {
|
case TP_MODEL: {
|
||||||
Node->Model->Render( Node->pCenter - Global::pCameraPosition );
|
Node->Model->Render( Node->pCenter - m_camera.position() );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,7 +680,7 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
|||||||
|
|
||||||
// setup
|
// setup
|
||||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
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 );
|
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
||||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
@@ -1013,13 +1021,13 @@ opengl_renderer::Render_Alpha( TSubRect *Groundsubcell ) {
|
|||||||
bool
|
bool
|
||||||
opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
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 ) )
|
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
auto const originoffset = Node->m_rootposition - m_camera.position();
|
||||||
active_shader->set_mv(glm::translate(OpenGLMatrices.data(GL_MODELVIEW), glm::vec3(originoffset.x, originoffset.y, originoffset.z)));
|
active_shader->set_mv(glm::translate(OpenGLMatrices.data(GL_MODELVIEW), glm::vec3(originoffset.x, originoffset.y, originoffset.z)));
|
||||||
|
|
||||||
switch (Node->iType)
|
switch (Node->iType)
|
||||||
@@ -1062,7 +1070,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case TP_MODEL: {
|
case TP_MODEL: {
|
||||||
Node->Model->RenderAlpha( Node->pCenter - Global::pCameraPosition );
|
Node->Model->RenderAlpha( Node->pCenter - m_camera.position() );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1135,7 +1143,7 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
|||||||
|
|
||||||
// setup
|
// setup
|
||||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
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 );
|
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
||||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
@@ -1407,6 +1415,7 @@ opengl_renderer::Update ( double const Deltatime ) {
|
|||||||
|
|
||||||
// TODO: add garbage collection and other less frequent works here
|
// TODO: add garbage collection and other less frequent works here
|
||||||
m_geometry.update();
|
m_geometry.update();
|
||||||
|
m_textures.update();
|
||||||
|
|
||||||
if( true == DebugModeFlag ) {
|
if( true == DebugModeFlag ) {
|
||||||
m_debuginfo = m_textures.info();
|
m_debuginfo = m_textures.info();
|
||||||
@@ -1441,14 +1450,14 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
|
|||||||
// all lights past this one are bound to be off
|
// all lights past this one are bound to be off
|
||||||
break;
|
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.
|
// 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
|
// but there could still be weaker lights which are closer, so keep looking
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// if the light passed tests so far, it's good enough
|
// if the light passed tests so far, it's good enough
|
||||||
|
|
||||||
Math3D::vector3 pos = scenelight.position - Global::pCameraPosition;
|
Math3D::vector3 pos = scenelight.position - m_camera.position();
|
||||||
|
|
||||||
auto const luminance = Global::fLuminance; // TODO: adjust this based on location, e.g. for tunnels
|
auto const luminance = Global::fLuminance; // TODO: adjust this based on location, e.g. for tunnels
|
||||||
glm::vec3 position(pos.x, pos.y, pos.z);
|
glm::vec3 position(pos.x, pos.y, pos.z);
|
||||||
|
|||||||
11
renderer.h
11
renderer.h
@@ -50,10 +50,17 @@ public:
|
|||||||
visible( bounding_area const &Area ) const;
|
visible( bounding_area const &Area ) const;
|
||||||
bool
|
bool
|
||||||
visible( TDynamicObject const *Dynamic ) const;
|
visible( TDynamicObject const *Dynamic ) const;
|
||||||
|
inline
|
||||||
|
glm::dvec3 const &
|
||||||
|
position() const { return m_position; }
|
||||||
|
inline
|
||||||
|
glm::dvec3 &
|
||||||
|
position() { return m_position; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// members:
|
// members:
|
||||||
cFrustum m_frustum;
|
cFrustum m_frustum;
|
||||||
|
glm::dvec3 m_position;
|
||||||
};
|
};
|
||||||
|
|
||||||
// bare-bones render controller, in lack of anything better yet
|
// bare-bones render controller, in lack of anything better yet
|
||||||
@@ -64,6 +71,7 @@ public:
|
|||||||
gl_program_mvp depth_shader;
|
gl_program_mvp depth_shader;
|
||||||
gl_program_mvp *active_shader = nullptr;
|
gl_program_mvp *active_shader = nullptr;
|
||||||
GLuint depth_tex, depth_fbo;
|
GLuint depth_tex, depth_fbo;
|
||||||
|
opengl_camera m_camera;
|
||||||
|
|
||||||
// types
|
// types
|
||||||
|
|
||||||
@@ -122,7 +130,7 @@ public:
|
|||||||
GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true );
|
GetTextureId( std::string Filename, std::string const &Dir, int const Filter = -1, bool const Loadnow = true );
|
||||||
void
|
void
|
||||||
Bind( texture_handle const Texture );
|
Bind( texture_handle const Texture );
|
||||||
opengl_texture &
|
opengl_texture const &
|
||||||
Texture( texture_handle const Texture );
|
Texture( texture_handle const Texture );
|
||||||
|
|
||||||
// members
|
// members
|
||||||
@@ -170,7 +178,6 @@ private:
|
|||||||
// members
|
// members
|
||||||
geometrybank_manager m_geometry;
|
geometrybank_manager m_geometry;
|
||||||
texture_manager m_textures;
|
texture_manager m_textures;
|
||||||
opengl_camera m_camera;
|
|
||||||
rendermode renderpass { rendermode::color };
|
rendermode renderpass { rendermode::color };
|
||||||
float m_drawrange { 2500.0f }; // current drawing range
|
float m_drawrange { 2500.0f }; // current drawing range
|
||||||
float m_drawtime { 1000.0f / 30.0f * 20.0f }; // start with presumed 'neutral' average of 30 fps
|
float m_drawtime { 1000.0f / 30.0f * 20.0f }; // start with presumed 'neutral' average of 30 fps
|
||||||
|
|||||||
@@ -39,50 +39,15 @@ uniform float specular;
|
|||||||
uniform light_s lights[8];
|
uniform light_s lights[8];
|
||||||
uniform uint lights_count;
|
uniform uint lights_count;
|
||||||
|
|
||||||
vec2 poissonDisk[16] = vec2[](
|
|
||||||
vec2( -0.94201624, -0.39906216 ),
|
|
||||||
vec2( 0.94558609, -0.76890725 ),
|
|
||||||
vec2( -0.094184101, -0.92938870 ),
|
|
||||||
vec2( 0.34495938, 0.29387760 ),
|
|
||||||
vec2( -0.91588581, 0.45771432 ),
|
|
||||||
vec2( -0.81544232, -0.87912464 ),
|
|
||||||
vec2( -0.38277543, 0.27676845 ),
|
|
||||||
vec2( 0.97484398, 0.75648379 ),
|
|
||||||
vec2( 0.44323325, -0.97511554 ),
|
|
||||||
vec2( 0.53742981, -0.47373420 ),
|
|
||||||
vec2( -0.26496911, -0.41893023 ),
|
|
||||||
vec2( 0.79197514, 0.19090188 ),
|
|
||||||
vec2( -0.24188840, 0.99706507 ),
|
|
||||||
vec2( -0.81409955, 0.91437590 ),
|
|
||||||
vec2( 0.19984126, 0.78641367 ),
|
|
||||||
vec2( 0.14383161, -0.14100790 )
|
|
||||||
);
|
|
||||||
|
|
||||||
float random(vec3 seed, int i)
|
|
||||||
{
|
|
||||||
vec4 seed4 = vec4(seed,i);
|
|
||||||
float dot_product = dot(seed4, vec4(12.9898,78.233,45.164,94.673));
|
|
||||||
return fract(sin(dot_product) * 43758.5453);
|
|
||||||
}
|
|
||||||
|
|
||||||
float calc_shadow()
|
float calc_shadow()
|
||||||
{
|
{
|
||||||
vec3 coords = f_light_pos.xyz;// / f_light_pos.w;
|
vec3 coords = f_light_pos.xyz;
|
||||||
coords = coords * 0.5 + 0.5;
|
float bias = clamp(0.0025*tan(acos(clamp(dot(f_normal, -lights[0].dir), 0.0, 1.0))), 0, 0.01);
|
||||||
float bias = 0.005;
|
|
||||||
|
|
||||||
//PCF
|
//sampler PCF
|
||||||
//float shadow = texture(shadowmap, vec3(coords.xy, coords.z - bias));
|
//float shadow = texture(shadowmap, vec3(coords.xy, coords.z - bias));
|
||||||
|
|
||||||
//PCF + stratified poisson sampling
|
|
||||||
//float shadow = 1.0;
|
|
||||||
//for (int i=0;i<4;i++)
|
|
||||||
//{
|
|
||||||
// int index = int(16.0*random(gl_FragCoord.xyy, i))%16;
|
|
||||||
// shadow -= 0.25*(1.0-texture(shadowmap, vec3(coords.xy + poissonDisk[index]/5000.0, coords.z - bias)));
|
|
||||||
//}
|
|
||||||
|
|
||||||
//PCF + PCF
|
//sampler PCF + PCF
|
||||||
float shadow = 0.0;
|
float shadow = 0.0;
|
||||||
vec2 texel = 1.0 / textureSize(shadowmap, 0);
|
vec2 texel = 1.0 / textureSize(shadowmap, 0);
|
||||||
for (float y = -1.5; y <= 1.5; y += 1.0)
|
for (float y = -1.5; y <= 1.5; y += 1.0)
|
||||||
@@ -159,8 +124,10 @@ void main()
|
|||||||
part = calc_point_light(light);
|
part = calc_point_light(light);
|
||||||
else if (light.type == LIGHT_DIR)
|
else if (light.type == LIGHT_DIR)
|
||||||
part = calc_dir_light(light);
|
part = calc_dir_light(light);
|
||||||
|
|
||||||
result += light.color * part * shadow;
|
if (i == 0U)
|
||||||
|
part *= shadow;
|
||||||
|
result += light.color * part;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 tex_color = texture(tex, f_coord);
|
vec4 tex_color = texture(tex, f_coord);
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
in vec3 f_pos;
|
in vec2 f_coord;
|
||||||
|
|
||||||
|
uniform sampler2D tex;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
gl_FragDepth = gl_FragCoord.z + (1.0 - texture(tex, f_coord).w);
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,9 @@
|
|||||||
#version 330
|
#version 330
|
||||||
|
|
||||||
layout (location = 0) in vec3 v_vert;
|
layout (location = 0) in vec3 v_vert;
|
||||||
|
layout (location = 2) in vec2 v_coord;
|
||||||
|
|
||||||
out vec3 f_pos;
|
out vec2 f_coord;
|
||||||
|
|
||||||
uniform mat4 modelview;
|
uniform mat4 modelview;
|
||||||
uniform mat4 projection;
|
uniform mat4 projection;
|
||||||
@@ -10,4 +11,5 @@ uniform mat4 projection;
|
|||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = (projection * modelview) * vec4(v_vert, 1.0f);
|
gl_Position = (projection * modelview) * vec4(v_vert, 1.0f);
|
||||||
|
f_coord = v_coord;
|
||||||
}
|
}
|
||||||
1
stdafx.h
1
stdafx.h
@@ -76,6 +76,7 @@
|
|||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/matrix_access.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include <glm/gtc/epsilon.hpp>
|
#include <glm/gtc/epsilon.hpp>
|
||||||
#include <glm/gtx/rotate_vector.hpp>
|
#include <glm/gtx/rotate_vector.hpp>
|
||||||
|
|||||||
Reference in New Issue
Block a user