16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 16:49:18 +02:00

refactoring: selectable gfx renderer groundwork

This commit is contained in:
tmj-fstate
2019-10-12 18:38:01 +02:00
parent c312251580
commit 936e537a7a
24 changed files with 245 additions and 171 deletions

View File

@@ -918,7 +918,7 @@ TAnimModel::export_as_text_( std::ostream &Output ) const {
// texture // texture
auto texturefile { ( auto texturefile { (
m_materialdata.replacable_skins[ 1 ] != null_handle ? m_materialdata.replacable_skins[ 1 ] != null_handle ?
GfxRenderer.Material( m_materialdata.replacable_skins[ 1 ] ).name : GfxRenderer->Material( m_materialdata.replacable_skins[ 1 ] ).name :
"none" ) }; "none" ) };
if( texturefile.find( szTexturePath ) == 0 ) { if( texturefile.find( szTexturePath ) == 0 ) {
// don't include 'textures/' in the path // don't include 'textures/' in the path

View File

@@ -173,7 +173,7 @@ material_data::assign( std::string const &Replacableskin ) {
int skinindex = 0; int skinindex = 0;
std::string texturename; nameparser >> texturename; std::string texturename; nameparser >> texturename;
while( ( texturename != "" ) && ( skinindex < 4 ) ) { while( ( texturename != "" ) && ( skinindex < 4 ) ) {
replacable_skins[ skinindex + 1 ] = GfxRenderer.Fetch_Material( texturename ); replacable_skins[ skinindex + 1 ] = GfxRenderer->Fetch_Material( texturename );
++skinindex; ++skinindex;
texturename = ""; nameparser >> texturename; texturename = ""; nameparser >> texturename;
} }
@@ -188,33 +188,33 @@ material_data::assign( std::string const &Replacableskin ) {
auto const material { TextureTest( ToLower( Replacableskin + "," + std::to_string( skinindex + 1 ) ) ) }; auto const material { TextureTest( ToLower( Replacableskin + "," + std::to_string( skinindex + 1 ) ) ) };
if( true == material.empty() ) { break; } if( true == material.empty() ) { break; }
replacable_skins[ skinindex + 1 ] = GfxRenderer.Fetch_Material( material ); replacable_skins[ skinindex + 1 ] = GfxRenderer->Fetch_Material( material );
++skinindex; ++skinindex;
} while( skinindex < 4 ); } while( skinindex < 4 );
multi_textures = skinindex; multi_textures = skinindex;
if( multi_textures == 0 ) { if( multi_textures == 0 ) {
// zestaw nie zadziałał, próbujemy normanie // zestaw nie zadziałał, próbujemy normanie
replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( Replacableskin ); replacable_skins[ 1 ] = GfxRenderer->Fetch_Material( Replacableskin );
} }
} }
if( replacable_skins[ 1 ] == null_handle ) { if( replacable_skins[ 1 ] == null_handle ) {
// last ditch attempt, check for single replacable skin texture // last ditch attempt, check for single replacable skin texture
replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( Replacableskin ); replacable_skins[ 1 ] = GfxRenderer->Fetch_Material( Replacableskin );
} }
textures_alpha = ( textures_alpha = (
GfxRenderer.Material( replacable_skins[ 1 ] ).has_alpha ? GfxRenderer->Material( replacable_skins[ 1 ] ).has_alpha ?
0x31310031 : // tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych 0x31310031 : // tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
0x30300030 ); // wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych 0x30300030 ); // wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych
if( GfxRenderer.Material( replacable_skins[ 2 ] ).has_alpha ) { if( GfxRenderer->Material( replacable_skins[ 2 ] ).has_alpha ) {
// tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych // tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
textures_alpha |= 0x02020002; textures_alpha |= 0x02020002;
} }
if( GfxRenderer.Material( replacable_skins[ 3 ] ).has_alpha ) { if( GfxRenderer->Material( replacable_skins[ 3 ] ).has_alpha ) {
// tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych // tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
textures_alpha |= 0x04040004; textures_alpha |= 0x04040004;
} }
if( GfxRenderer.Material( replacable_skins[ 4 ] ).has_alpha ) { if( GfxRenderer->Material( replacable_skins[ 4 ] ).has_alpha ) {
// tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych // tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
textures_alpha |= 0x08080008; textures_alpha |= 0x08080008;
} }
@@ -6327,7 +6327,7 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer) {
signrequest += "&" + DestinationSign.parameters; signrequest += "&" + DestinationSign.parameters;
} }
DestinationSign.destination = GfxRenderer.Fetch_Material( signrequest ); DestinationSign.destination = GfxRenderer->Fetch_Material( signrequest );
} }
material_handle TDynamicObject::DestinationFind( std::string Destination ) { material_handle TDynamicObject::DestinationFind( std::string Destination ) {
@@ -6348,7 +6348,7 @@ material_handle TDynamicObject::DestinationFind( std::string Destination ) {
for( auto const &destination : destinations ) { for( auto const &destination : destinations ) {
auto material = TextureTest( ToLower( destination ) ); auto material = TextureTest( ToLower( destination ) );
if( false == material.empty() ) { if( false == material.empty() ) {
destinationhandle = GfxRenderer.Fetch_Material( material ); destinationhandle = GfxRenderer->Fetch_Material( material );
break; break;
} }
} }

View File

@@ -371,14 +371,14 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
material.insert( 0, Global.asCurrentTexturePath ); material.insert( 0, Global.asCurrentTexturePath );
} }
*/ */
m_material = GfxRenderer.Fetch_Material( material ); m_material = GfxRenderer->Fetch_Material( material );
// renderowanie w cyklu przezroczystych tylko jeśli: // renderowanie w cyklu przezroczystych tylko jeśli:
// 1. Opacity=0 (przejściowo <1, czy tam <100) oraz // 1. Opacity=0 (przejściowo <1, czy tam <100) oraz
// 2. tekstura ma przezroczystość // 2. tekstura ma przezroczystość
iFlags |= iFlags |=
( ( ( Opacity < 1.0 ) ( ( ( Opacity < 1.0 )
&& ( ( m_material != null_handle ) && ( ( m_material != null_handle )
&& ( GfxRenderer.Material( m_material ).has_alpha ) ) ) ? && ( GfxRenderer->Material( m_material ).has_alpha ) ) ) ?
0x20 : 0x20 :
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta 0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
}; };
@@ -646,7 +646,7 @@ int TSubModel::TriangleAdd(TModel3d *m, material_handle tex, int tri)
s = new TSubModel(); s = new TSubModel();
m->AddTo(this, s); m->AddTo(this, s);
} }
s->Name_Material(GfxRenderer.Material(tex).name); s->Name_Material(GfxRenderer->Material(tex).name);
s->m_material = tex; s->m_material = tex;
s->eType = GL_TRIANGLES; s->eType = GL_TRIANGLES;
} }
@@ -1076,7 +1076,7 @@ void TSubModel::serialize_geometry( std::ostream &Output ) const {
Child->serialize_geometry( Output ); Child->serialize_geometry( Output );
} }
if( m_geometry != null_handle ) { if( m_geometry != null_handle ) {
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) { for( auto const &vertex : GfxRenderer->Vertices( m_geometry ) ) {
vertex.serialize( Output ); vertex.serialize( Output );
} }
} }
@@ -1102,7 +1102,7 @@ TSubModel::create_geometry( std::size_t &Dataoffset, gfx::geometrybank_handle co
eType < TP_ROTATOR ? eType < TP_ROTATOR ?
eType : eType :
GL_POINTS ); GL_POINTS );
m_geometry = GfxRenderer.Insert( Vertices, Bank, type ); m_geometry = GfxRenderer->Insert( Vertices, Bank, type );
} }
if( m_geometry != NULL ) { if( m_geometry != NULL ) {
@@ -1112,7 +1112,7 @@ TSubModel::create_geometry( std::size_t &Dataoffset, gfx::geometrybank_handle co
// since we're comparing squared radii, we need to square it back for correct results // since we're comparing squared radii, we need to square it back for correct results
m_boundingradius *= m_boundingradius; m_boundingradius *= m_boundingradius;
auto const submodeloffset { offset( std::numeric_limits<float>::max() ) }; auto const submodeloffset { offset( std::numeric_limits<float>::max() ) };
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) { for( auto const &vertex : GfxRenderer->Vertices( m_geometry ) ) {
squaredradius = glm::length2( submodeloffset + vertex.position ); squaredradius = glm::length2( submodeloffset + vertex.position );
if( squaredradius > m_boundingradius ) { if( squaredradius > m_boundingradius ) {
m_boundingradius = squaredradius; m_boundingradius = squaredradius;
@@ -1214,7 +1214,7 @@ float TSubModel::MaxY( float4x4 const &m ) {
// binary and text models invoke this function at different stages, either after or before geometry data was sent to the geometry manager // binary and text models invoke this function at different stages, either after or before geometry data was sent to the geometry manager
if( m_geometry != null_handle ) { if( m_geometry != null_handle ) {
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) { for( auto const &vertex : GfxRenderer->Vertices( m_geometry ) ) {
maxy = std::max( maxy = std::max(
maxy, maxy,
m[ 0 ][ 1 ] * vertex.position.x m[ 0 ][ 1 ] * vertex.position.x
@@ -1327,7 +1327,7 @@ TSubModel::offset( float const Geometrytestoffsetthreshold ) const {
// TODO: do proper bounding area calculation for submodel when loading mesh and grab the centre point from it here // TODO: do proper bounding area calculation for submodel when loading mesh and grab the centre point from it here
auto const &vertices { ( auto const &vertices { (
m_geometry != null_handle ? m_geometry != null_handle ?
GfxRenderer.Vertices( m_geometry ) : GfxRenderer->Vertices( m_geometry ) :
Vertices ) }; Vertices ) };
if( false == vertices.empty() ) { if( false == vertices.empty() ) {
// transformation matrix for the submodel can still contain rotation and/or scaling, // transformation matrix for the submodel can still contain rotation and/or scaling,
@@ -1596,7 +1596,7 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
{ {
Root = nullptr; Root = nullptr;
if( m_geometrybank == null_handle ) { if( m_geometrybank == null_handle ) {
m_geometrybank = GfxRenderer.Create_Bank(); m_geometrybank = GfxRenderer->Create_Bank();
} }
std::streampos end = s.tellg() + (std::streampos)size; std::streampos end = s.tellg() + (std::streampos)size;
@@ -1681,7 +1681,7 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
break; break;
} }
} }
submodel.m_geometry = GfxRenderer.Insert( vertices, m_geometrybank, type ); submodel.m_geometry = GfxRenderer->Insert( vertices, m_geometrybank, type );
} }
} }
@@ -1782,12 +1782,12 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
m_materialname = Global.asCurrentTexturePath + m_materialname; m_materialname = Global.asCurrentTexturePath + m_materialname;
} }
*/ */
m_material = GfxRenderer.Fetch_Material( m_materialname ); m_material = GfxRenderer->Fetch_Material( m_materialname );
if( ( iFlags & 0x30 ) == 0 ) { if( ( iFlags & 0x30 ) == 0 ) {
// texture-alpha based fallback if for some reason we don't have opacity flag set yet // texture-alpha based fallback if for some reason we don't have opacity flag set yet
iFlags |= ( iFlags |= (
( ( m_material != null_handle ) ( ( m_material != null_handle )
&& ( GfxRenderer.Material( m_material ).has_alpha ) ) ? && ( GfxRenderer->Material( m_material ).has_alpha ) ) ?
0x20 : 0x20 :
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta 0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
} }
@@ -1920,7 +1920,7 @@ void TModel3d::Init()
iFlags |= Root->FlagsCheck() | 0x8000; // flagi całego modelu iFlags |= Root->FlagsCheck() | 0x8000; // flagi całego modelu
if (iNumVerts) { if (iNumVerts) {
if( m_geometrybank == null_handle ) { if( m_geometrybank == null_handle ) {
m_geometrybank = GfxRenderer.Create_Bank(); m_geometrybank = GfxRenderer->Create_Bank();
} }
std::size_t dataoffset = 0; std::size_t dataoffset = 0;
Root->create_geometry( dataoffset, m_geometrybank ); Root->create_geometry( dataoffset, m_geometrybank );

View File

@@ -527,7 +527,7 @@ bool TSegment::RenderLoft( gfx::vertex_array &Output, Math3D::vector3 const &Ori
void TSegment::Render() void TSegment::Render()
{ {
Math3D::vector3 pt; Math3D::vector3 pt;
GfxRenderer.Bind_Material( null_handle ); GfxRenderer->Bind_Material( null_handle );
if (bCurve) if (bCurve)
{ {

111
Track.cpp
View File

@@ -462,7 +462,7 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin)
m_material1 = ( m_material1 = (
str == "none" ? str == "none" ?
null_handle : null_handle :
GfxRenderer.Fetch_Material( str ) ); GfxRenderer->Fetch_Material( str ) );
parser->getTokens(); parser->getTokens();
*parser >> fTexLength; // tex tile length *parser >> fTexLength; // tex tile length
if (fTexLength < 0.01) if (fTexLength < 0.01)
@@ -472,7 +472,7 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin)
m_material2 = ( m_material2 = (
str == "none" ? str == "none" ?
null_handle : null_handle :
GfxRenderer.Fetch_Material( str ) ); GfxRenderer->Fetch_Material( str ) );
parser->getTokens(3); parser->getTokens(3);
*parser *parser
>> fTexHeight1 >> fTexHeight1
@@ -584,17 +584,14 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin)
else if (iCategoryFlag & 2) else if (iCategoryFlag & 2)
if (m_material1 && fTexLength) if (m_material1 && fTexLength)
{ // dla drogi trzeba ustalić proporcje boków nawierzchni { // dla drogi trzeba ustalić proporcje boków nawierzchni
float w, h; auto const &texture1 { GfxRenderer->Texture( GfxRenderer->Material( m_material1 ).texture1 ) };
GfxRenderer.Bind_Material(m_material1); if( texture1.height() > 0 ) {
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); fTexRatio1 = static_cast<float>( texture1.width() ) / static_cast<float>( texture1.height() ); // proporcja boków
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); }
if (h != 0.0) auto const &texture2 { GfxRenderer->Texture( GfxRenderer->Material( m_material2 ).texture1 ) };
fTexRatio1 = w / h; // proporcja boków if( texture2.height() > 0 ) {
GfxRenderer.Bind_Material(m_material2); fTexRatio2 = static_cast<float>( texture2.width() ) / static_cast<float>( texture2.height() ); // proporcja boków
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); }
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
if (h != 0.0)
fTexRatio2 = w / h; // proporcja boków
} }
break; break;
} }
@@ -883,7 +880,7 @@ void TTrack::Load(cParser *parser, glm::dvec3 const &pOrigin)
// switch trackbed texture // switch trackbed texture
auto const trackbedtexture { parser->getToken<std::string>() }; auto const trackbedtexture { parser->getToken<std::string>() };
if( eType == tt_Switch ) { if( eType == tt_Switch ) {
SwitchExtension->m_material3 = GfxRenderer.Fetch_Material( trackbedtexture ); SwitchExtension->m_material3 = GfxRenderer->Fetch_Material( trackbedtexture );
} }
} }
else if( str == "railprofile" ) { else if( str == "railprofile" ) {
@@ -1138,11 +1135,11 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
gfx::vertex_array vertices; gfx::vertex_array vertices;
Segment->RenderLoft(vertices, m_origin, bpts1, iTrapezoid > 0, texturelength); Segment->RenderLoft(vertices, m_origin, bpts1, iTrapezoid > 0, texturelength);
if( ( Bank != 0 ) && ( true == Geometry2.empty() ) ) { if( ( Bank != 0 ) && ( true == Geometry2.empty() ) ) {
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
} }
if( ( Bank == 0 ) && ( false == Geometry2.empty() ) ) { if( ( Bank == 0 ) && ( false == Geometry2.empty() ) ) {
// special variant, replace existing data for a turntable track // special variant, replace existing data for a turntable track
GfxRenderer.Replace( vertices, Geometry2[ 0 ] ); GfxRenderer->Replace( vertices, Geometry2[ 0 ] );
} }
} }
if (m_material1) if (m_material1)
@@ -1152,18 +1149,18 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
gfx::vertex_array vertices; gfx::vertex_array vertices;
if( ( Bank != 0 ) && ( true == Geometry1.empty() ) ) { if( ( Bank != 0 ) && ( true == Geometry1.empty() ) ) {
Segment->RenderLoft( vertices, m_origin, rpts1, iTrapezoid > 0, texturelength ); Segment->RenderLoft( vertices, m_origin, rpts1, iTrapezoid > 0, texturelength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); // reuse the scratchpad vertices.clear(); // reuse the scratchpad
Segment->RenderLoft( vertices, m_origin, rpts2, iTrapezoid > 0, texturelength ); Segment->RenderLoft( vertices, m_origin, rpts2, iTrapezoid > 0, texturelength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
} }
if( ( Bank == 0 ) && ( false == Geometry1.empty() ) ) { if( ( Bank == 0 ) && ( false == Geometry1.empty() ) ) {
// special variant, replace existing data for a turntable track // special variant, replace existing data for a turntable track
Segment->RenderLoft( vertices, m_origin, rpts1, iTrapezoid > 0, texturelength ); Segment->RenderLoft( vertices, m_origin, rpts1, iTrapezoid > 0, texturelength );
GfxRenderer.Replace( vertices, Geometry1[ 0 ] ); GfxRenderer->Replace( vertices, Geometry1[ 0 ] );
vertices.clear(); // reuse the scratchpad vertices.clear(); // reuse the scratchpad
Segment->RenderLoft( vertices, m_origin, rpts2, iTrapezoid > 0, texturelength ); Segment->RenderLoft( vertices, m_origin, rpts2, iTrapezoid > 0, texturelength );
GfxRenderer.Replace( vertices, Geometry1[ 1 ] ); GfxRenderer->Replace( vertices, Geometry1[ 1 ] );
} }
} }
break; break;
@@ -1188,21 +1185,21 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
// composed from two parts: transition from blade to regular rail, and regular rail // composed from two parts: transition from blade to regular rail, and regular rail
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts3, true, texturelength, 1.0, 0, bladelength / 2, { SwitchExtension->fOffset2, SwitchExtension->fOffset2 / 2 } ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts3, true, texturelength, 1.0, 0, bladelength / 2, { SwitchExtension->fOffset2, SwitchExtension->fOffset2 / 2 } );
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength / 2, bladelength, { SwitchExtension->fOffset2 / 2, 0.f } ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength / 2, bladelength, { SwitchExtension->fOffset2 / 2, 0.f } );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
// fixed parts // fixed parts
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
if( jointlength > 0 ) { if( jointlength > 0 ) {
// part of the diverging rail touched by wheels of vehicle going straight // part of the diverging rail touched by wheels of vehicle going straight
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, 0, jointlength ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, 0, jointlength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
// other rail, full length // other rail, full length
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
if( m_material2 ) { if( m_material2 ) {
@@ -1211,15 +1208,15 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
// composed from two parts: transition from blade to regular rail, and regular rail // composed from two parts: transition from blade to regular rail, and regular rail
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts4, true, texturelength, 1.0, 0, bladelength / 2, { -fMaxOffset + SwitchExtension->fOffset1, ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2 } ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts4, true, texturelength, 1.0, 0, bladelength / 2, { -fMaxOffset + SwitchExtension->fOffset1, ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2 } );
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength / 2, bladelength, { ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2, 0.f } ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength / 2, bladelength, { ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2, 0.f } );
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
// fixed parts // fixed parts
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength );
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
// diverging rail, potentially minus part touched by wheels of vehicle going straight // diverging rail, potentially minus part touched by wheels of vehicle going straight
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, jointlength ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, jointlength );
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
} }
@@ -1232,22 +1229,22 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
// composed from two parts: transition from blade to regular rail, and regular rail // composed from two parts: transition from blade to regular rail, and regular rail
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts4, true, texturelength, 1.0, 0, bladelength / 2, { -SwitchExtension->fOffset2, -SwitchExtension->fOffset2 / 2 } ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts4, true, texturelength, 1.0, 0, bladelength / 2, { -SwitchExtension->fOffset2, -SwitchExtension->fOffset2 / 2 } );
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength / 2, bladelength, { -SwitchExtension->fOffset2 / 2, 0.f } ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength / 2, bladelength, { -SwitchExtension->fOffset2 / 2, 0.f } );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
// fixed parts // fixed parts
// prawa szyna za iglicą // prawa szyna za iglicą
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
if( jointlength > 0 ) { if( jointlength > 0 ) {
// part of the diverging rail touched by wheels of vehicle going straight // part of the diverging rail touched by wheels of vehicle going straight
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, 0, jointlength ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, 0, jointlength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
// other rail, full length // other rail, full length
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength );
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
if( m_material2 ) { if( m_material2 ) {
@@ -1256,16 +1253,16 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
// composed from two parts: transition from blade to regular rail, and regular rail // composed from two parts: transition from blade to regular rail, and regular rail
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts3, true, texturelength, 1.0, 0, bladelength / 2, { fMaxOffset - SwitchExtension->fOffset1, ( fMaxOffset - SwitchExtension->fOffset1 ) / 2 } ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts3, true, texturelength, 1.0, 0, bladelength / 2, { fMaxOffset - SwitchExtension->fOffset1, ( fMaxOffset - SwitchExtension->fOffset1 ) / 2 } );
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength / 2, bladelength, { ( fMaxOffset - SwitchExtension->fOffset1 ) / 2, 0.f } ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength / 2, bladelength, { ( fMaxOffset - SwitchExtension->fOffset1 ) / 2, 0.f } );
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
// fixed parts // fixed parts
// lewa szyna za iglicą // lewa szyna za iglicą
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength );
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
// diverging rail, potentially minus part touched by wheels of vehicle going straight // diverging rail, potentially minus part touched by wheels of vehicle going straight
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, jointlength ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, jointlength );
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
} }
@@ -1274,7 +1271,7 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
if( true == Global.CreateSwitchTrackbeds ) { if( true == Global.CreateSwitchTrackbeds ) {
gfx::vertex_array vertices; gfx::vertex_array vertices;
create_switch_trackbed( vertices ); create_switch_trackbed( vertices );
SwitchExtension->Geometry3 = GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ); SwitchExtension->Geometry3 = GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP );
vertices.clear(); vertices.clear();
} }
@@ -1297,7 +1294,7 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
auto const texturelength { texture_length( m_material1 ) }; auto const texturelength { texture_length( m_material1 ) };
gfx::vertex_array vertices; gfx::vertex_array vertices;
Segment->RenderLoft(vertices, m_origin, bpts1, iTrapezoid > 0, texturelength); Segment->RenderLoft(vertices, m_origin, bpts1, iTrapezoid > 0, texturelength);
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
} }
if (m_material2) if (m_material2)
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?) { // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?)
@@ -1310,13 +1307,13 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) { if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) {
// tylko jeśli jest z prawej // tylko jeśli jest z prawej
Segment->RenderLoft( vertices, m_origin, rpts1, iTrapezoid > 0, texturelength ); Segment->RenderLoft( vertices, m_origin, rpts1, iTrapezoid > 0, texturelength );
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) { if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
// tylko jeśli jest z lewej // tylko jeśli jest z lewej
Segment->RenderLoft( vertices, m_origin, rpts2, iTrapezoid > 0, texturelength ); Segment->RenderLoft( vertices, m_origin, rpts2, iTrapezoid > 0, texturelength );
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
} }
@@ -1393,22 +1390,22 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) { if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
SwitchExtension->Segments[ 2 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render ); SwitchExtension->Segments[ 2 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render );
if( true == render ) { if( true == render ) {
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
SwitchExtension->Segments[ 3 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render ); SwitchExtension->Segments[ 3 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render );
if( true == render ) { if( true == render ) {
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
SwitchExtension->Segments[ 4 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render ); SwitchExtension->Segments[ 4 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render );
if( true == render ) { if( true == render ) {
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
SwitchExtension->Segments[ 5 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render ); SwitchExtension->Segments[ 5 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render );
if( true == render ) { if( true == render ) {
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
} }
@@ -1418,17 +1415,17 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) { if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
SwitchExtension->Segments[ 2 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render ); // z P2 do P4 SwitchExtension->Segments[ 2 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render ); // z P2 do P4
if( true == render ) { if( true == render ) {
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render ); // z P4 do P3=P1 (odwrócony) SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render ); // z P4 do P3=P1 (odwrócony)
if( true == render ) { if( true == render ) {
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render ); // z P1 do P2 SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, true, texturelength, 1.0, 0, 0, {}, &b, render ); // z P1 do P2
if( true == render ) { if( true == render ) {
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
} }
@@ -1483,7 +1480,7 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
cosa0 * u + sina0 * v + 0.5, cosa0 * u + sina0 * v + 0.5,
-sina0 * u + cosa0 * v + 0.5 } ); -sina0 * u + cosa0 * v + 0.5 } );
} }
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_FAN ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_FAN ) );
} }
break; break;
} // tt_cross } // tt_cross
@@ -1502,7 +1499,7 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
{ // tworzenie trójkątów nawierzchni szosy { // tworzenie trójkątów nawierzchni szosy
gfx::vertex_array vertices; gfx::vertex_array vertices;
Segment->RenderLoft(vertices, m_origin, bpts1, iTrapezoid > 0, fTexLength); Segment->RenderLoft(vertices, m_origin, bpts1, iTrapezoid > 0, fTexLength);
Geometry1.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry1.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
} }
if (m_material2) if (m_material2)
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?) { // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?)
@@ -1510,10 +1507,10 @@ void TTrack::create_geometry( gfx::geometrybank_handle const &Bank ) {
create_road_side_profile( rpts1, rpts2, bpts1 ); create_road_side_profile( rpts1, rpts2, bpts1 );
gfx::vertex_array vertices; gfx::vertex_array vertices;
Segment->RenderLoft( vertices, m_origin, rpts1, iTrapezoid > 0, fTexLength ); Segment->RenderLoft( vertices, m_origin, rpts1, iTrapezoid > 0, fTexLength );
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
Segment->RenderLoft( vertices, m_origin, rpts2, iTrapezoid > 0, fTexLength ); Segment->RenderLoft( vertices, m_origin, rpts2, iTrapezoid > 0, fTexLength );
Geometry2.emplace_back( GfxRenderer.Insert( vertices, Bank, GL_TRIANGLE_STRIP ) ); Geometry2.emplace_back( GfxRenderer->Insert( vertices, Bank, GL_TRIANGLE_STRIP ) );
vertices.clear(); vertices.clear();
} }
} }
@@ -1791,7 +1788,7 @@ TTrack * TTrack::RaAnimate()
// composed from two parts: transition from blade to regular rail, and regular rail // composed from two parts: transition from blade to regular rail, and regular rail
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts3, true, texturelength, 1.0, 0, bladelength / 2, { SwitchExtension->fOffset2, SwitchExtension->fOffset2 / 2 } ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts3, true, texturelength, 1.0, 0, bladelength / 2, { SwitchExtension->fOffset2, SwitchExtension->fOffset2 / 2 } );
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength / 2, bladelength, { SwitchExtension->fOffset2 / 2, 0.f } ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength / 2, bladelength, { SwitchExtension->fOffset2 / 2, 0.f } );
GfxRenderer.Replace( vertices, Geometry1[ 0 ] ); GfxRenderer->Replace( vertices, Geometry1[ 0 ] );
vertices.clear(); vertices.clear();
} }
if( m_material2 ) { if( m_material2 ) {
@@ -1800,7 +1797,7 @@ TTrack * TTrack::RaAnimate()
// composed from two parts: transition from blade to regular rail, and regular rail // composed from two parts: transition from blade to regular rail, and regular rail
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts4, true, texturelength, 1.0, 0, bladelength / 2, { -fMaxOffset + SwitchExtension->fOffset1, ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2 } ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts4, true, texturelength, 1.0, 0, bladelength / 2, { -fMaxOffset + SwitchExtension->fOffset1, ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2 } );
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength / 2, bladelength, { ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2, 0.f } ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength / 2, bladelength, { ( -fMaxOffset + SwitchExtension->fOffset1 ) / 2, 0.f } );
GfxRenderer.Replace( vertices, Geometry2[ 0 ] ); GfxRenderer->Replace( vertices, Geometry2[ 0 ] );
vertices.clear(); vertices.clear();
} }
} }
@@ -1811,7 +1808,7 @@ TTrack * TTrack::RaAnimate()
// composed from two parts: transition from blade to regular rail, and regular rail // composed from two parts: transition from blade to regular rail, and regular rail
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts4, true, texturelength, 1.0, 0, bladelength / 2, { -SwitchExtension->fOffset2, -SwitchExtension->fOffset2 / 2 } ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts4, true, texturelength, 1.0, 0, bladelength / 2, { -SwitchExtension->fOffset2, -SwitchExtension->fOffset2 / 2 } );
SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength / 2, bladelength, { -SwitchExtension->fOffset2 / 2, 0.f } ); SwitchExtension->Segments[ 0 ]->RenderLoft( vertices, m_origin, rpts2, false, texturelength, 1.0, bladelength / 2, bladelength, { -SwitchExtension->fOffset2 / 2, 0.f } );
GfxRenderer.Replace( vertices, Geometry1[ 0 ] ); GfxRenderer->Replace( vertices, Geometry1[ 0 ] );
vertices.clear(); vertices.clear();
} }
if( m_material2 ) { if( m_material2 ) {
@@ -1820,7 +1817,7 @@ TTrack * TTrack::RaAnimate()
// composed from two parts: transition from blade to regular rail, and regular rail // composed from two parts: transition from blade to regular rail, and regular rail
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts3, true, texturelength, 1.0, 0, bladelength / 2, { fMaxOffset - SwitchExtension->fOffset1, ( fMaxOffset - SwitchExtension->fOffset1 ) / 2 } ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts3, true, texturelength, 1.0, 0, bladelength / 2, { fMaxOffset - SwitchExtension->fOffset1, ( fMaxOffset - SwitchExtension->fOffset1 ) / 2 } );
SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength / 2, bladelength, { ( fMaxOffset - SwitchExtension->fOffset1 ) / 2, 0.f } ); SwitchExtension->Segments[ 1 ]->RenderLoft( vertices, m_origin, rpts1, false, texturelength, 1.0, bladelength / 2, bladelength, { ( fMaxOffset - SwitchExtension->fOffset1 ) / 2, 0.f } );
GfxRenderer.Replace( vertices, Geometry2[ 0 ] ); GfxRenderer->Replace( vertices, Geometry2[ 0 ] );
vertices.clear(); vertices.clear();
} }
} }
@@ -2071,7 +2068,7 @@ TTrack::export_as_text_( std::ostream &Output ) const {
// texture parameters are supplied only if the path is set as visible // texture parameters are supplied only if the path is set as visible
auto texturefile { ( auto texturefile { (
m_material1 != null_handle ? m_material1 != null_handle ?
GfxRenderer.Material( m_material1 ).name : GfxRenderer->Material( m_material1 ).name :
"none" ) }; "none" ) };
if( texturefile.find( szTexturePath ) == 0 ) { if( texturefile.find( szTexturePath ) == 0 ) {
// don't include 'textures/' in the path // don't include 'textures/' in the path
@@ -2083,7 +2080,7 @@ TTrack::export_as_text_( std::ostream &Output ) const {
texturefile = ( texturefile = (
m_material2 != null_handle ? m_material2 != null_handle ?
GfxRenderer.Material( m_material2 ).name : GfxRenderer->Material( m_material2 ).name :
"none" ); "none" );
if( texturefile.find( szTexturePath ) == 0 ) { if( texturefile.find( szTexturePath ) == 0 ) {
// don't include 'textures/' in the path // don't include 'textures/' in the path
@@ -2157,7 +2154,7 @@ TTrack::export_as_text_( std::ostream &Output ) const {
} }
if( ( eType == tt_Switch ) if( ( eType == tt_Switch )
&& ( SwitchExtension->m_material3 != null_handle ) ) { && ( SwitchExtension->m_material3 != null_handle ) ) {
auto texturefile { GfxRenderer.Material( m_material2 ).name }; auto texturefile { GfxRenderer->Material( m_material2 ).name };
if( texturefile.find( szTexturePath ) == 0 ) { if( texturefile.find( szTexturePath ) == 0 ) {
// don't include 'textures/' in the path // don't include 'textures/' in the path
texturefile.erase( 0, std::string{ szTexturePath }.size() ); texturefile.erase( 0, std::string{ szTexturePath }.size() );
@@ -2277,7 +2274,7 @@ TTrack::texture_length( material_handle const Material ) {
if( Material == null_handle ) { if( Material == null_handle ) {
return fTexLength; return fTexLength;
} }
auto const texturelength { GfxRenderer.Material( Material ).size.y }; auto const texturelength { GfxRenderer->Material( Material ).size.y };
return ( return (
texturelength < 0.f ? texturelength < 0.f ?
fTexLength : fTexLength :

View File

@@ -168,7 +168,7 @@ TTraction::endpoints() const {
std::size_t std::size_t
TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) { TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
if( m_geometry != null_handle ) { if( m_geometry != null_handle ) {
return GfxRenderer.Vertices( m_geometry ).size() / 2; return GfxRenderer->Vertices( m_geometry ).size() / 2;
} }
gfx::vertex_array vertices; gfx::vertex_array vertices;
@@ -341,7 +341,7 @@ TTraction::create_geometry( gfx::geometrybank_handle const &Bank ) {
} }
auto const elementcount = vertices.size() / 2; auto const elementcount = vertices.size() / 2;
m_geometry = GfxRenderer.Insert( vertices, Bank, GL_LINES ); m_geometry = GfxRenderer->Insert( vertices, Bank, GL_LINES );
return elementcount; return elementcount;
} }

View File

@@ -3451,7 +3451,7 @@ void TTrain::OnCommand_motoroverloadrelayreset( TTrain *Train, command_data cons
void TTrain::OnCommand_lightspresetactivatenext( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_lightspresetactivatenext( TTrain *Train, command_data const &Command ) {
if( Train->mvOccupied->LightsPosNo == 0 ) { if( Train->mvOccupied->LightsPosNo == 0 ) {
// lights are controlled by preset selector // no preset selector
return; return;
} }
if( Command.action != GLFW_PRESS ) { if( Command.action != GLFW_PRESS ) {
@@ -3462,23 +3462,30 @@ void TTrain::OnCommand_lightspresetactivatenext( TTrain *Train, command_data con
if( ( Train->mvOccupied->LightsPos < Train->mvOccupied->LightsPosNo ) if( ( Train->mvOccupied->LightsPos < Train->mvOccupied->LightsPosNo )
|| ( true == Train->mvOccupied->LightsWrap ) ) { || ( true == Train->mvOccupied->LightsWrap ) ) {
// active light preset is stored as value in range 1-LigthPosNo // active light preset is stored as value in range 1-LigthPosNo
auto const restartcycle { Train->mvOccupied->LightsPos == Train->mvOccupied->LightsPosNo };
Train->mvOccupied->LightsPos = ( Train->mvOccupied->LightsPos = (
Train->mvOccupied->LightsPos < Train->mvOccupied->LightsPosNo ? false == restartcycle ?
Train->mvOccupied->LightsPos + 1 : Train->mvOccupied->LightsPos + 1 :
1 ); // wrap mode 1 ); // wrap mode
Train->SetLights(); Train->SetLights();
// visual feedback // visual feedback
if( Train->ggLightsButton.SubModel != nullptr ) { if( Train->ggLightsButton.SubModel != nullptr ) {
// HACK: skip submodel animation when restarting cycle, since it plays in the 'wrong' direction
if( false == restartcycle ) {
Train->ggLightsButton.UpdateValue( Train->mvOccupied->LightsPos - 1, Train->dsbSwitch ); Train->ggLightsButton.UpdateValue( Train->mvOccupied->LightsPos - 1, Train->dsbSwitch );
} }
else {
Train->ggLightsButton.PutValue( Train->mvOccupied->LightsPos - 1 );
}
}
} }
} }
void TTrain::OnCommand_lightspresetactivateprevious( TTrain *Train, command_data const &Command ) { void TTrain::OnCommand_lightspresetactivateprevious( TTrain *Train, command_data const &Command ) {
if( Train->mvOccupied->LightsPosNo == 0 ) { if( Train->mvOccupied->LightsPosNo == 0 ) {
// lights are controlled by preset selector // no preset selector
return; return;
} }
if( Command.action != GLFW_PRESS ) { if( Command.action != GLFW_PRESS ) {
@@ -3489,16 +3496,23 @@ void TTrain::OnCommand_lightspresetactivateprevious( TTrain *Train, command_data
if( ( Train->mvOccupied->LightsPos > 1 ) if( ( Train->mvOccupied->LightsPos > 1 )
|| ( true == Train->mvOccupied->LightsWrap ) ) { || ( true == Train->mvOccupied->LightsWrap ) ) {
// active light preset is stored as value in range 1-LigthPosNo // active light preset is stored as value in range 1-LigthPosNo
auto const restartcycle { Train->mvOccupied->LightsPos == 1 };
Train->mvOccupied->LightsPos = ( Train->mvOccupied->LightsPos = (
Train->mvOccupied->LightsPos > 1 ? false == restartcycle ?
Train->mvOccupied->LightsPos - 1 : Train->mvOccupied->LightsPos - 1 :
Train->mvOccupied->LightsPosNo ); // wrap mode Train->mvOccupied->LightsPosNo ); // wrap mode
Train->SetLights(); Train->SetLights();
// visual feedback // visual feedback
if( Train->ggLightsButton.SubModel != nullptr ) { if( Train->ggLightsButton.SubModel != nullptr ) {
// HACK: skip submodel animation when restarting cycle, since it plays in the 'wrong' direction
if( false == restartcycle ) {
Train->ggLightsButton.UpdateValue( Train->mvOccupied->LightsPos - 1, Train->dsbSwitch ); Train->ggLightsButton.UpdateValue( Train->mvOccupied->LightsPos - 1, Train->dsbSwitch );
} }
else {
Train->ggLightsButton.PutValue( Train->mvOccupied->LightsPos - 1 );
}
}
} }
} }
@@ -6600,7 +6614,7 @@ bool TTrain::Update( double const Deltatime )
&& ( false == FreeFlyModeFlag ) ) { // don't bother if we're outside && ( false == FreeFlyModeFlag ) ) { // don't bother if we're outside
fScreenTimer = 0.f; fScreenTimer = 0.f;
for( auto const &screen : m_screens ) { for( auto const &screen : m_screens ) {
Application.request( { screen.first, GetTrainState(), GfxRenderer.Texture( screen.second ).id } ); Application.request( { screen.first, GetTrainState(), GfxRenderer->Texture( screen.second ).id } );
} }
} }
// sounds // sounds
@@ -7407,7 +7421,7 @@ bool TTrain::InitializeCab(int NewCabNo, std::string const &asFileName)
( substr_path(renderername).empty() ? // supply vehicle folder as path if none is provided ( substr_path(renderername).empty() ? // supply vehicle folder as path if none is provided
DynamicObject->asBaseDir + renderername : DynamicObject->asBaseDir + renderername :
renderername ), renderername ),
GfxRenderer.Material( material ).texture1 ); GfxRenderer->Material( material ).texture1 );
} }
// btLampkaUnknown.Init("unknown",mdKabina,false); // btLampkaUnknown.Init("unknown",mdKabina,false);
} while (token != ""); } while (token != "");

View File

@@ -150,7 +150,7 @@ eu07_application::run() {
while( ( false == glfwWindowShouldClose( m_windows.front() ) ) while( ( false == glfwWindowShouldClose( m_windows.front() ) )
&& ( false == m_modestack.empty() ) && ( false == m_modestack.empty() )
&& ( true == m_modes[ m_modestack.top() ]->update() ) && ( true == m_modes[ m_modestack.top() ]->update() )
&& ( true == GfxRenderer.Render() ) ) { && ( true == GfxRenderer->Render() ) ) {
glfwPollEvents(); glfwPollEvents();
m_modes[ m_modestack.top() ]->on_event_poll(); m_modes[ m_modestack.top() ]->on_event_poll();
} }
@@ -512,7 +512,9 @@ eu07_application::init_gfx() {
return -1; return -1;
} }
if( ( false == GfxRenderer.Init( m_windows.front() ) ) GfxRenderer = std::make_unique<opengl_renderer>();
if( ( false == GfxRenderer->Init( m_windows.front() ) )
|| ( false == ui_layer::init( m_windows.front() ) ) ) { || ( false == ui_layer::init( m_windows.front() ) ) ) {
return -1; return -1;
} }

View File

@@ -238,7 +238,7 @@ driver_mode::update() {
// NOTE: particle system runs on simulation time, but needs actual camera position to determine how to update each particle source // NOTE: particle system runs on simulation time, but needs actual camera position to determine how to update each particle source
simulation::Particles.update(); simulation::Particles.update();
GfxRenderer.Update( deltarealtime ); GfxRenderer->Update( deltarealtime );
simulation::is_ready = true; simulation::is_ready = true;

View File

@@ -323,7 +323,7 @@ drivermouse_input::button( int const Button, int const Action ) {
// left mouse button launches on_click event associated with to the node // left mouse button launches on_click event associated with to the node
if( Button == GLFW_MOUSE_BUTTON_LEFT ) { if( Button == GLFW_MOUSE_BUTTON_LEFT ) {
if( Action == GLFW_PRESS ) { if( Action == GLFW_PRESS ) {
auto const *node { GfxRenderer.Update_Pick_Node() }; auto const *node { GfxRenderer->Update_Pick_Node() };
if( ( node == nullptr ) if( ( node == nullptr )
|| ( typeid( *node ) != typeid( TAnimModel ) ) ) { || ( typeid( *node ) != typeid( TAnimModel ) ) ) {
return; return;
@@ -369,7 +369,7 @@ drivermouse_input::button( int const Button, int const Action ) {
} }
else { else {
// if not release then it's press // if not release then it's press
auto const lookup = m_buttonbindings.find( simulation::Train->GetLabel( GfxRenderer.Update_Pick_Control() ) ); auto const lookup = m_buttonbindings.find( simulation::Train->GetLabel( GfxRenderer->Update_Pick_Control() ) );
if( lookup != m_buttonbindings.end() ) { if( lookup != m_buttonbindings.end() ) {
// if the recognized element under the cursor has a command associated with the pressed button, notify the recipient // if the recognized element under the cursor has a command associated with the pressed button, notify the recipient
mousecommand = ( mousecommand = (

View File

@@ -171,16 +171,16 @@ driver_ui::update() {
if( ( train != nullptr ) && ( false == FreeFlyModeFlag ) ) { if( ( train != nullptr ) && ( false == FreeFlyModeFlag ) ) {
if( false == DebugModeFlag ) { if( false == DebugModeFlag ) {
// in regular mode show control functions, for defined controls // in regular mode show control functions, for defined controls
set_tooltip( locale::label_cab_control( train->GetLabel( GfxRenderer.Pick_Control() ) ) ); set_tooltip( locale::label_cab_control( train->GetLabel( GfxRenderer->Pick_Control() ) ) );
} }
else { else {
// in debug mode show names of submodels, to help with cab setup and/or debugging // in debug mode show names of submodels, to help with cab setup and/or debugging
auto const cabcontrol = GfxRenderer.Pick_Control(); auto const cabcontrol = GfxRenderer->Pick_Control();
set_tooltip( ( cabcontrol ? cabcontrol->pName : "" ) ); set_tooltip( ( cabcontrol ? cabcontrol->pName : "" ) );
} }
} }
if( ( true == Global.ControlPicking ) && ( true == FreeFlyModeFlag ) && ( true == DebugModeFlag ) ) { if( ( true == Global.ControlPicking ) && ( true == FreeFlyModeFlag ) && ( true == DebugModeFlag ) ) {
auto const scenerynode = GfxRenderer.Pick_Node(); auto const scenerynode = GfxRenderer->Pick_Node();
set_tooltip( set_tooltip(
( scenerynode ? ( scenerynode ?
scenerynode->name() : scenerynode->name() :

View File

@@ -1084,9 +1084,9 @@ debug_panel::update_section_renderer( std::vector<text_line> &Output ) {
auto textline = auto textline =
"FoV: " + to_string( Global.FieldOfView / Global.ZoomFactor, 1 ) "FoV: " + to_string( Global.FieldOfView / Global.ZoomFactor, 1 )
+ ", Draw range x " + to_string( Global.fDistanceFactor, 1 ) + ", Draw range x " + to_string( Global.fDistanceFactor, 1 )
// + "; sectors: " + std::to_string( GfxRenderer.m_drawcount ) // + "; sectors: " + std::to_string( GfxRenderer->m_drawcount )
// + ", FPS: " + to_string( Timer::GetFPS(), 2 ); // + ", FPS: " + to_string( Timer::GetFPS(), 2 );
+ ", FPS: " + std::to_string( static_cast<int>(std::round(GfxRenderer.Framerate())) ); + ", FPS: " + std::to_string( static_cast<int>(std::round(GfxRenderer->Framerate())) );
if( Global.iSlowMotion ) { if( Global.iSlowMotion ) {
textline += " (slowmotion " + to_string( Global.iSlowMotion ) + ")"; textline += " (slowmotion " + to_string( Global.iSlowMotion ) + ")";
} }
@@ -1108,8 +1108,8 @@ debug_panel::update_section_renderer( std::vector<text_line> &Output ) {
Output.emplace_back( textline, Global.UITextColor ); Output.emplace_back( textline, Global.UITextColor );
// renderer stats // renderer stats
Output.emplace_back( GfxRenderer.info_times(), Global.UITextColor ); Output.emplace_back( GfxRenderer->info_times(), Global.UITextColor );
Output.emplace_back( GfxRenderer.info_stats(), Global.UITextColor ); Output.emplace_back( GfxRenderer->info_stats(), Global.UITextColor );
} }
bool bool

View File

@@ -80,7 +80,7 @@ editor_mode::update() {
simulation::Region->update_sounds(); simulation::Region->update_sounds();
audio::renderer.update( deltarealtime ); audio::renderer.update( deltarealtime );
GfxRenderer.Update( deltarealtime ); GfxRenderer->Update( deltarealtime );
simulation::is_ready = true; simulation::is_ready = true;
@@ -203,7 +203,7 @@ editor_mode::on_cursor_pos( double const Horizontal, double const Vertical ) {
m_editor.translate( m_node, translation ); m_editor.translate( m_node, translation );
} }
else { else {
auto const mouseworldposition { Camera.Pos + GfxRenderer.Mouse_Position() }; auto const mouseworldposition { Camera.Pos + GfxRenderer->Mouse_Position() };
m_editor.translate( m_node, mouseworldposition, mode_snap() ); m_editor.translate( m_node, mouseworldposition, mode_snap() );
} }
} }
@@ -229,7 +229,7 @@ editor_mode::on_mouse_button( int const Button, int const Action, int const Mods
if( Action == GLFW_PRESS ) { if( Action == GLFW_PRESS ) {
// left button press // left button press
m_node = GfxRenderer.Update_Pick_Node(); m_node = GfxRenderer->Update_Pick_Node();
if( m_node ) { if( m_node ) {
Application.set_cursor( GLFW_CURSOR_DISABLED ); Application.set_cursor( GLFW_CURSOR_DISABLED );
} }

View File

@@ -29,7 +29,7 @@ editor_ui::update() {
if( ( true == Global.ControlPicking ) if( ( true == Global.ControlPicking )
&& ( true == DebugModeFlag ) ) { && ( true == DebugModeFlag ) ) {
auto const scenerynode = GfxRenderer.Pick_Node(); auto const scenerynode = GfxRenderer->Pick_Node();
set_tooltip( set_tooltip(
( scenerynode ? ( scenerynode ?
scenerynode->name() : scenerynode->name() :

View File

@@ -36,12 +36,26 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
auto const &camera { Global.pCamera }; auto const &camera { Global.pCamera };
if( node == nullptr ) { if( node == nullptr ) {
auto const mouseposition { camera.Pos + GfxRenderer.Mouse_Position() }; auto const mouseposition { camera.Pos + GfxRenderer->Mouse_Position() };
textline = "mouse location: [" + to_string( mouseposition.x, 2 ) + ", " + to_string( mouseposition.y, 2 ) + ", " + to_string( mouseposition.z, 2 ) + "]"; textline = "mouse location: [" + to_string( mouseposition.x, 2 ) + ", " + to_string( mouseposition.y, 2 ) + ", " + to_string( mouseposition.z, 2 ) + "]";
text_lines.emplace_back( textline, Global.UITextColor ); text_lines.emplace_back( textline, Global.UITextColor );
return; return;
} }
/*
// TODO: bind receiver in the constructor
if( ( m_itemproperties != nullptr )
&& ( m_itemproperties->node != nullptr ) ) {
// fetch node data; skip properties which were changed until they're retrieved by the observer
auto const *node { m_itemproperties->node };
if( m_itemproperties->name.second == false ) {
m_itemproperties->name.first = ( node->name().empty() ? "(none)" : node->name() );
}
if( m_itemproperties->location.second == false ) {
m_itemproperties->location.first = node->location();
}
}
*/
textline = textline =
"name: " + ( node->name().empty() ? "(none)" : node->name() ) "name: " + ( node->name().empty() ? "(none)" : node->name() )
+ "\nlocation: [" + to_string( node->location().x, 2 ) + ", " + to_string( node->location().y, 2 ) + ", " + to_string( node->location().z, 2 ) + "]" + "\nlocation: [" + to_string( node->location().x, 2 ) + ", " + to_string( node->location().y, 2 ) + ", " + to_string( node->location().z, 2 ) + "]"
@@ -83,7 +97,7 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
// texture // texture
auto texturefile { ( auto texturefile { (
( subnode->Material()->replacable_skins[ 1 ] != null_handle ) ? ( subnode->Material()->replacable_skins[ 1 ] != null_handle ) ?
GfxRenderer.Material( subnode->Material()->replacable_skins[ 1 ] ).name : GfxRenderer->Material( subnode->Material()->replacable_skins[ 1 ] ).name :
"(none)" ) }; "(none)" ) };
if( texturefile.find( szTexturePath ) == 0 ) { if( texturefile.find( szTexturePath ) == 0 ) {
// don't include 'textures/' in the path // don't include 'textures/' in the path
@@ -106,14 +120,14 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
// textures // textures
auto texturefile { ( auto texturefile { (
( subnode->m_material1 != null_handle ) ? ( subnode->m_material1 != null_handle ) ?
GfxRenderer.Material( subnode->m_material1 ).name : GfxRenderer->Material( subnode->m_material1 ).name :
"(none)" ) }; "(none)" ) };
if( texturefile.find( szTexturePath ) == 0 ) { if( texturefile.find( szTexturePath ) == 0 ) {
texturefile.erase( 0, std::string{ szTexturePath }.size() ); texturefile.erase( 0, std::string{ szTexturePath }.size() );
} }
auto texturefile2{ ( auto texturefile2{ (
( subnode->m_material2 != null_handle ) ? ( subnode->m_material2 != null_handle ) ?
GfxRenderer.Material( subnode->m_material2 ).name : GfxRenderer->Material( subnode->m_material2 ).name :
"(none)" ) }; "(none)" ) };
if( texturefile2.find( szTexturePath ) == 0 ) { if( texturefile2.find( szTexturePath ) == 0 ) {
texturefile2.erase( 0, std::string{ szTexturePath }.size() ); texturefile2.erase( 0, std::string{ szTexturePath }.size() );

View File

@@ -25,7 +25,7 @@ opengl_material::deserialize( cParser &Input, bool const Loadnow ) {
has_alpha = ( has_alpha = (
texture1 != null_handle ? texture1 != null_handle ?
GfxRenderer.Texture( texture1 ).has_alpha : GfxRenderer->Texture( texture1 ).has_alpha :
false ); false );
return result; return result;
@@ -63,7 +63,7 @@ opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool c
auto const value { deserialize_random_set( Input ) }; auto const value { deserialize_random_set( Input ) };
if( ( texture1 == null_handle ) if( ( texture1 == null_handle )
|| ( Priority > priority1 ) ) { || ( Priority > priority1 ) ) {
texture1 = GfxRenderer.Fetch_Texture( value, Loadnow ); texture1 = GfxRenderer->Fetch_Texture( value, Loadnow );
priority1 = Priority; priority1 = Priority;
} }
} }
@@ -72,7 +72,7 @@ opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool c
auto const value { deserialize_random_set( Input ) }; auto const value { deserialize_random_set( Input ) };
if( ( texture2 == null_handle ) if( ( texture2 == null_handle )
|| ( Priority > priority2 ) ) { || ( Priority > priority2 ) ) {
texture2 = GfxRenderer.Fetch_Texture( value, Loadnow ); texture2 = GfxRenderer->Fetch_Texture( value, Loadnow );
priority2 = Priority; priority2 = Priority;
} }
} }
@@ -168,11 +168,11 @@ material_manager::create( std::string const &Filename, bool const Loadnow ) {
// if there's no .mat file, this can be either autogenerated texture, // if there's no .mat file, this can be either autogenerated texture,
// or legacy method of referring just to diffuse texture directly. // or legacy method of referring just to diffuse texture directly.
// wrap basic material around it in either case // wrap basic material around it in either case
material.texture1 = GfxRenderer.Fetch_Texture( Filename, Loadnow ); material.texture1 = GfxRenderer->Fetch_Texture( Filename, Loadnow );
if( material.texture1 != null_handle ) { if( material.texture1 != null_handle ) {
// use texture path and name to tell the newly created materials apart // use texture path and name to tell the newly created materials apart
material.name = GfxRenderer.Texture( material.texture1 ).name; material.name = GfxRenderer->Texture( material.texture1 ).name;
material.has_alpha = GfxRenderer.Texture( material.texture1 ).has_alpha; material.has_alpha = GfxRenderer->Texture( material.texture1 ).has_alpha;
} }
} }

View File

@@ -98,11 +98,11 @@ basic_precipitation::init() {
"_medium" ) }; "_medium" ) };
if( Global.Weather == "rain:" ) { if( Global.Weather == "rain:" ) {
m_moverateweathertypefactor = 2.f; m_moverateweathertypefactor = 2.f;
m_texture = GfxRenderer.Fetch_Texture( "fx/rain" + densitysuffix ); m_texture = GfxRenderer->Fetch_Texture( "fx/rain" + densitysuffix );
} }
else if( Global.Weather == "snow:" ) { else if( Global.Weather == "snow:" ) {
m_moverateweathertypefactor = 1.25f; m_moverateweathertypefactor = 1.25f;
m_texture = GfxRenderer.Fetch_Texture( "fx/snow" + densitysuffix ); m_texture = GfxRenderer->Fetch_Texture( "fx/snow" + densitysuffix );
} }
return true; return true;
@@ -163,7 +163,7 @@ basic_precipitation::update() {
void void
basic_precipitation::render() { basic_precipitation::render() {
GfxRenderer.Bind_Texture( m_texture ); GfxRenderer->Bind_Texture( m_texture );
// cache entry state // cache entry state
::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT ); ::glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );

View File

@@ -24,7 +24,7 @@ http://mozilla.org/MPL/2.0/.
#include "Logs.h" #include "Logs.h"
#include "utilities.h" #include "utilities.h"
opengl_renderer GfxRenderer; std::unique_ptr<gfx_renderer> GfxRenderer;
int const EU07_PICKBUFFERSIZE { 1024 }; // size of (square) textures bound with the pick framebuffer int const EU07_PICKBUFFERSIZE { 1024 }; // size of (square) textures bound with the pick framebuffer
int const EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental cube map texture int const EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental cube map texture
@@ -1610,7 +1610,7 @@ opengl_renderer::Render( world_environment *Environment ) {
::glRotatef( -std::fmod( (float)Global.fTimeAngleDeg, 360.f ), 0.f, 1.f, 0.f ); // obrót dobowy osi OX ::glRotatef( -std::fmod( (float)Global.fTimeAngleDeg, 360.f ), 0.f, 1.f, 0.f ); // obrót dobowy osi OX
::glPointSize( 2.f ); ::glPointSize( 2.f );
// render // render
GfxRenderer.Render( Environment->m_stars.m_stars, nullptr, 1.0 ); Render( Environment->m_stars.m_stars, nullptr, 1.0 );
// post-render cleanup // post-render cleanup
::glPointSize( 3.f ); ::glPointSize( 3.f );
::glPopMatrix(); ::glPopMatrix();
@@ -4202,12 +4202,14 @@ opengl_renderer::Init_caps() {
#ifdef EU07_USEIMGUIIMPLOPENGL2 #ifdef EU07_USEIMGUIIMPLOPENGL2
if( !GLEW_VERSION_1_5 ) { if( !GLEW_VERSION_1_5 ) {
ErrorLog( "Requires openGL >= 1.5" ); ErrorLog( "Requires openGL >= 1.5" );
return false;
}
#else #else
if( !GLEW_VERSION_3_0 ) { if( !GLEW_VERSION_3_0 ) {
ErrorLog( "Requires openGL >= 3.0" ); ErrorLog( "Requires openGL >= 3.0" );
#endif
return false; return false;
} }
#endif
WriteLog( "Supported extensions: " + std::string((char *)glGetString( GL_EXTENSIONS )) ); WriteLog( "Supported extensions: " + std::string((char *)glGetString( GL_EXTENSIONS )) );

View File

@@ -29,6 +29,52 @@ http://mozilla.org/MPL/2.0/.
//#define EU07_USEIMGUIIMPLOPENGL2 //#define EU07_USEIMGUIIMPLOPENGL2
//#define EU07_DISABLECABREFLECTIONS //#define EU07_DISABLECABREFLECTIONS
class gfx_renderer {
public:
// types
// constructors
// destructor
virtual ~gfx_renderer() {}
// methods
virtual auto Init( GLFWwindow *Window ) -> bool = 0;
// main draw call. returns false on error
virtual auto Render() -> bool = 0;
virtual auto Framerate() -> float = 0;
// geometry methods
// NOTE: hands-on geometry management is exposed as a temporary measure; ultimately all visualization data should be generated/handled automatically by the renderer itself
// creates a new geometry bank. returns: handle to the bank or NULL
virtual auto Create_Bank() -> gfx::geometrybank_handle = 0;
// creates a new geometry chunk of specified type from supplied vertex data, in specified bank. returns: handle to the chunk or NULL
virtual auto Insert( gfx::vertex_array &Vertices, gfx::geometrybank_handle const &Geometry, int const Type ) -> gfx::geometry_handle = 0;
// replaces data of specified chunk with the supplied vertex data, starting from specified offset
virtual auto Replace( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry, std::size_t const Offset = 0 ) -> bool = 0;
// adds supplied vertex data at the end of specified chunk
virtual auto Append( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry ) -> bool = 0;
// provides direct access to vertex data of specfied chunk
virtual auto Vertices( gfx::geometry_handle const &Geometry ) const ->gfx::vertex_array const & = 0;
// material methods
virtual auto Fetch_Material( std::string const &Filename, bool const Loadnow = true ) -> material_handle = 0;
virtual void Bind_Material( material_handle const Material ) = 0;
virtual auto Material( material_handle const Material ) const -> opengl_material const & = 0;
// texture methods
virtual auto Fetch_Texture( std::string const &Filename, bool const Loadnow = true ) -> texture_handle = 0;
virtual void Bind_Texture( texture_handle const Texture ) = 0;
virtual auto Texture( texture_handle const Texture ) const -> opengl_texture const & = 0;
// utility methods
virtual auto Pick_Control() const -> TSubModel const * = 0;
virtual auto Pick_Node() const -> scene::basic_node const * = 0;
virtual auto Mouse_Position() const -> glm::dvec3 = 0;
// maintenance methods
virtual void Update( double const Deltatime ) = 0;
virtual auto Update_Pick_Control() -> TSubModel * = 0;
virtual auto Update_Pick_Node() -> scene::basic_node * = 0;
virtual auto Update_Mouse_Position() -> glm::dvec3 = 0;
// debug methods
virtual auto info_times() const -> std::string const & = 0;
virtual auto info_stats() const -> std::string const & = 0;
};
struct opengl_light : public basic_light { struct opengl_light : public basic_light {
GLuint id { (GLuint)-1 }; GLuint id { (GLuint)-1 };
@@ -158,7 +204,7 @@ private:
// bare-bones render controller, in lack of anything better yet // bare-bones render controller, in lack of anything better yet
class opengl_renderer { class opengl_renderer : public gfx_renderer {
public: public:
// types // types
@@ -168,68 +214,65 @@ public:
~opengl_renderer() { gluDeleteQuadric( m_quadric ); } ~opengl_renderer() { gluDeleteQuadric( m_quadric ); }
// methods // methods
bool bool
Init( GLFWwindow *Window ); Init( GLFWwindow *Window ) override;
// main draw call. returns false on error // main draw call. returns false on error
bool bool
Render(); Render() override;
inline inline
float float
Framerate() { return m_framerate; } Framerate() override { return m_framerate; }
// geometry methods // geometry methods
// NOTE: hands-on geometry management is exposed as a temporary measure; ultimately all visualization data should be generated/handled automatically by the renderer itself // NOTE: hands-on geometry management is exposed as a temporary measure; ultimately all visualization data should be generated/handled automatically by the renderer itself
// creates a new geometry bank. returns: handle to the bank or NULL // creates a new geometry bank. returns: handle to the bank or NULL
gfx::geometrybank_handle gfx::geometrybank_handle
Create_Bank(); Create_Bank() override;
// creates a new geometry chunk of specified type from supplied vertex data, in specified bank. returns: handle to the chunk or NULL // creates a new geometry chunk of specified type from supplied vertex data, in specified bank. returns: handle to the chunk or NULL
gfx::geometry_handle gfx::geometry_handle
Insert( gfx::vertex_array &Vertices, gfx::geometrybank_handle const &Geometry, int const Type ); Insert( gfx::vertex_array &Vertices, gfx::geometrybank_handle const &Geometry, int const Type ) override;
// replaces data of specified chunk with the supplied vertex data, starting from specified offset // replaces data of specified chunk with the supplied vertex data, starting from specified offset
bool bool
Replace( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry, std::size_t const Offset = 0 ); Replace( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry, std::size_t const Offset = 0 ) override;
// adds supplied vertex data at the end of specified chunk // adds supplied vertex data at the end of specified chunk
bool bool
Append( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry ); Append( gfx::vertex_array &Vertices, gfx::geometry_handle const &Geometry ) override;
// provides direct access to vertex data of specfied chunk // provides direct access to vertex data of specfied chunk
gfx::vertex_array const & gfx::vertex_array const &
Vertices( gfx::geometry_handle const &Geometry ) const; Vertices( gfx::geometry_handle const &Geometry ) const override;
// material methods // material methods
material_handle material_handle
Fetch_Material( std::string const &Filename, bool const Loadnow = true ); Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override;
void void
Bind_Material( material_handle const Material ); Bind_Material( material_handle const Material ) override;
opengl_material const & opengl_material const &
Material( material_handle const Material ) const; Material( material_handle const Material ) const override;
// texture methods // texture methods
texture_handle texture_handle
Fetch_Texture( std::string const &Filename, bool const Loadnow = true ); Fetch_Texture( std::string const &Filename, bool const Loadnow = true ) override;
void void
Bind_Texture( texture_handle const Texture ); Bind_Texture( texture_handle const Texture );
opengl_texture const & opengl_texture const &
Texture( texture_handle const Texture ) const; Texture( texture_handle const Texture ) const override;
// light methods
void
Disable_Lights();
// utility methods // utility methods
TSubModel const * TSubModel const *
Pick_Control() const { return m_pickcontrolitem; } Pick_Control() const override { return m_pickcontrolitem; }
scene::basic_node const * scene::basic_node const *
Pick_Node() const { return m_picksceneryitem; } Pick_Node() const override { return m_picksceneryitem; }
glm::dvec3 glm::dvec3
Mouse_Position() const { return m_worldmousecoordinates; } Mouse_Position() const override { return m_worldmousecoordinates; }
// maintenance methods // maintenance methods
void void
Update( double const Deltatime ); Update( double const Deltatime ) override;
TSubModel * TSubModel *
Update_Pick_Control(); Update_Pick_Control() override;
scene::basic_node * scene::basic_node *
Update_Pick_Node(); Update_Pick_Node() override;
glm::dvec3 glm::dvec3
Update_Mouse_Position(); Update_Mouse_Position() override;
// debug methods // debug methods
std::string const & std::string const &
info_times() const; info_times() const override;
std::string const & std::string const &
info_stats() const; info_stats() const override;
// members // members
GLenum static const sunlight { GL_LIGHT0 }; GLenum static const sunlight { GL_LIGHT0 };
@@ -286,8 +329,8 @@ private:
typedef std::vector<opengl_light> opengllight_array; typedef std::vector<opengl_light> opengllight_array;
// methods // methods
bool void
Init_caps(); Disable_Lights();
void void
setup_pass( renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false ); setup_pass( renderpass_config &Config, rendermode const Mode, float const Znear = 0.f, float const Zfar = 1.f, bool const Ignoredebug = false );
void void
@@ -365,6 +408,8 @@ private:
Render_Alpha( TSubModel *Submodel ); Render_Alpha( TSubModel *Submodel );
void void
Update_Lights( light_array &Lights ); Update_Lights( light_array &Lights );
bool
Init_caps();
glm::vec3 glm::vec3
pick_color( std::size_t const Index ); pick_color( std::size_t const Index );
std::size_t std::size_t
@@ -459,6 +504,6 @@ private:
#endif #endif
}; };
extern opengl_renderer GfxRenderer; extern std::unique_ptr<gfx_renderer> GfxRenderer;
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------

View File

@@ -67,7 +67,7 @@ scenarioloader_mode::enter() {
Application.set_title( Global.AppName + " (" + Global.SceneryFile + ")" ); Application.set_title( Global.AppName + " (" + Global.SceneryFile + ")" );
m_userinterface->set_progress(); m_userinterface->set_progress();
m_userinterface->set_progress( "Loading scenery / Wczytywanie scenerii" ); m_userinterface->set_progress( "Loading scenery / Wczytywanie scenerii" );
GfxRenderer.Render(); GfxRenderer->Render();
} }
// maintenance method, called when the mode is deactivated // maintenance method, called when the mode is deactivated

View File

@@ -898,7 +898,7 @@ basic_section::create_geometry() {
// since sections can be empty, we're doing lazy initialization of the geometry bank, when something may actually use it // since sections can be empty, we're doing lazy initialization of the geometry bank, when something may actually use it
if( m_geometrybank == null_handle ) { if( m_geometrybank == null_handle ) {
m_geometrybank = GfxRenderer.Create_Bank(); m_geometrybank = GfxRenderer->Create_Bank();
} }
for( auto &shape : m_shapes ) { for( auto &shape : m_shapes ) {
@@ -1182,7 +1182,7 @@ basic_region::insert( shape_node Shape, scratch_data &Scratchpad, bool const Tra
if( Global.CreateSwitchTrackbeds ) { if( Global.CreateSwitchTrackbeds ) {
auto const materialname{ GfxRenderer.Material( Shape.data().material ).name }; auto const materialname{ GfxRenderer->Material( Shape.data().material ).name };
for( auto const &switchtrackbedtexture : switchtrackbedtextures ) { for( auto const &switchtrackbedtexture : switchtrackbedtextures ) {
if( materialname.find( switchtrackbedtexture ) != std::string::npos ) { if( materialname.find( switchtrackbedtexture ) != std::string::npos ) {
// geometry with blacklisted texture, part of old switch trackbed; ignore it // geometry with blacklisted texture, part of old switch trackbed; ignore it

View File

@@ -74,7 +74,7 @@ shape_node::shapenode_data::serialize( std::ostream &Output ) const {
sn_utils::s_str( sn_utils::s_str(
Output, Output,
( material != null_handle ? ( material != null_handle ?
GfxRenderer.Material( material ).name : GfxRenderer->Material( material ).name :
"" ) ); "" ) );
lighting.serialize( Output ); lighting.serialize( Output );
// geometry // geometry
@@ -104,7 +104,7 @@ shape_node::shapenode_data::deserialize( std::istream &Input ) {
translucent = sn_utils::d_bool( Input ); translucent = sn_utils::d_bool( Input );
auto const materialname { sn_utils::d_str( Input ) }; auto const materialname { sn_utils::d_str( Input ) };
if( false == materialname.empty() ) { if( false == materialname.empty() ) {
material = GfxRenderer.Fetch_Material( materialname ); material = GfxRenderer->Fetch_Material( materialname );
} }
lighting.deserialize( Input ); lighting.deserialize( Input );
// geometry // geometry
@@ -193,17 +193,17 @@ shape_node::import( cParser &Input, scene::node_data const &Nodedata ) {
} }
// assigned material // assigned material
m_data.material = GfxRenderer.Fetch_Material( token ); m_data.material = GfxRenderer->Fetch_Material( token );
// determine way to proceed from the assigned diffuse texture // determine way to proceed from the assigned diffuse texture
// TBT, TODO: add methods to material manager to access these simpler // TBT, TODO: add methods to material manager to access these simpler
auto const texturehandle = ( auto const texturehandle = (
m_data.material != null_handle ? m_data.material != null_handle ?
GfxRenderer.Material( m_data.material ).texture1 : GfxRenderer->Material( m_data.material ).texture1 :
null_handle ); null_handle );
auto const &texture = ( auto const &texture = (
texturehandle ? texturehandle ?
GfxRenderer.Texture( texturehandle ) : GfxRenderer->Texture( texturehandle ) :
opengl_texture() ); // dirty workaround for lack of better api opengl_texture() ); // dirty workaround for lack of better api
bool const clamps = ( bool const clamps = (
texturehandle ? texturehandle ?
@@ -345,7 +345,7 @@ shape_node::convert( TSubModel const *Submodel ) {
m_data.lighting.diffuse = Submodel->f4Diffuse; m_data.lighting.diffuse = Submodel->f4Diffuse;
m_data.lighting.specular = Submodel->f4Specular; m_data.lighting.specular = Submodel->f4Specular;
m_data.material = Submodel->m_material; m_data.material = Submodel->m_material;
m_data.translucent = ( true == GfxRenderer.Material( m_data.material ).has_alpha ); m_data.translucent = ( true == GfxRenderer->Material( m_data.material ).has_alpha );
// NOTE: we set unlimited view range typical for terrain, because we don't expect to convert any other 3d models // NOTE: we set unlimited view range typical for terrain, because we don't expect to convert any other 3d models
m_data.rangesquared_max = std::numeric_limits<double>::max(); m_data.rangesquared_max = std::numeric_limits<double>::max();
@@ -354,7 +354,7 @@ shape_node::convert( TSubModel const *Submodel ) {
int vertexcount { 0 }; int vertexcount { 0 };
std::vector<world_vertex> importedvertices; std::vector<world_vertex> importedvertices;
world_vertex vertex, vertex1, vertex2; world_vertex vertex, vertex1, vertex2;
for( auto const &sourcevertex : GfxRenderer.Vertices( Submodel->m_geometry ) ) { for( auto const &sourcevertex : GfxRenderer->Vertices( Submodel->m_geometry ) ) {
vertex.position = sourcevertex.position; vertex.position = sourcevertex.position;
vertex.normal = sourcevertex.normal; vertex.normal = sourcevertex.normal;
vertex.texture = sourcevertex.texture; vertex.texture = sourcevertex.texture;
@@ -429,7 +429,7 @@ shape_node::create_geometry( gfx::geometrybank_handle const &Bank ) {
vertex.normal, vertex.normal,
vertex.texture ); vertex.texture );
} }
m_data.geometry = GfxRenderer.Insert( vertices, Bank, GL_TRIANGLES ); m_data.geometry = GfxRenderer->Insert( vertices, Bank, GL_TRIANGLES );
std::vector<world_vertex>().swap( m_data.vertices ); // hipster shrink_to_fit std::vector<world_vertex>().swap( m_data.vertices ); // hipster shrink_to_fit
} }
@@ -658,7 +658,7 @@ lines_node::create_geometry( gfx::geometrybank_handle const &Bank ) {
vertex.normal, vertex.normal,
vertex.texture ); vertex.texture );
} }
m_data.geometry = GfxRenderer.Insert( vertices, Bank, GL_LINES ); m_data.geometry = GfxRenderer->Insert( vertices, Bank, GL_LINES );
std::vector<world_vertex>().swap( m_data.vertices ); // hipster shrink_to_fit std::vector<world_vertex>().swap( m_data.vertices ); // hipster shrink_to_fit
} }

View File

@@ -119,7 +119,7 @@ state_serializer::deserialize( cParser &Input, scene::scratch_data &Scratchpad )
timelast = timenow; timelast = timenow;
glfwPollEvents(); glfwPollEvents();
Application.set_progress( Input.getProgress(), Input.getFullProgress() ); Application.set_progress( Input.getProgress(), Input.getFullProgress() );
GfxRenderer.Render(); GfxRenderer->Render();
} }
token = Input.getToken<std::string>(); token = Input.getToken<std::string>();

View File

@@ -265,14 +265,14 @@ void
ui_layer::set_background( std::string const &Filename ) { ui_layer::set_background( std::string const &Filename ) {
if( false == Filename.empty() ) { if( false == Filename.empty() ) {
m_background = GfxRenderer.Fetch_Texture( Filename ); m_background = GfxRenderer->Fetch_Texture( Filename );
} }
else { else {
m_background = null_handle; m_background = null_handle;
} }
if( m_background != null_handle ) { if( m_background != null_handle ) {
auto const &texture = GfxRenderer.Texture( m_background ); auto const &texture = GfxRenderer->Texture( m_background );
m_progressbottom = ( texture.width() != texture.height() ); m_progressbottom = ( texture.width() != texture.height() );
} }
else { else {
@@ -354,9 +354,9 @@ ui_layer::render_background() {
if( m_background == 0 ) return; if( m_background == 0 ) return;
// NOTE: we limit/expect the background to come with 4:3 ratio. // NOTE: we limit/expect the background to come with 4:3 ratio.
// TODO, TBD: if we expose texture width or ratio from texture object, this limitation could be lifted // TODO, TBD: if we expose texture width or ratio from texture object, this limitation could be lifted
GfxRenderer.Bind_Texture( m_background ); GfxRenderer->Bind_Texture( m_background );
auto const height { 768.0f }; auto const height { 768.0f };
auto const &texture = GfxRenderer.Texture( m_background ); auto const &texture = GfxRenderer->Texture( m_background );
float const width = ( float const width = (
texture.width() == texture.height() ? texture.width() == texture.height() ?
1024.0f : // legacy mode, square texture displayed as 4:3 image 1024.0f : // legacy mode, square texture displayed as 4:3 image
@@ -376,7 +376,7 @@ ui_layer::render_texture() {
if( m_texture != 0 ) { if( m_texture != 0 ) {
::glColor4fv( glm::value_ptr( colors::white ) ); ::glColor4fv( glm::value_ptr( colors::white ) );
GfxRenderer.Bind_Texture( null_handle ); GfxRenderer->Bind_Texture( null_handle );
::glBindTexture( GL_TEXTURE_2D, m_texture ); ::glBindTexture( GL_TEXTURE_2D, m_texture );
auto const size = 512.f; auto const size = 512.f;