diff --git a/model/AnimModel.cpp b/model/AnimModel.cpp index cafb3a93e..52a879ac2 100644 --- a/model/AnimModel.cpp +++ b/model/AnimModel.cpp @@ -505,6 +505,8 @@ bool anim_type_shared_by_instances( TAnimType a ) { // instanced path (one shared submodel tree across all instances) cannot serve. bool submodel_tree_blocks_instancing( TSubModel const *Sub ) { if( Sub == nullptr ) { return false; } + // a text display shows the text of its instance, a tree shared by all instances can't do that + if( Sub->eType == TP_TEXT ) { return true; } if( anim_type_unsafe_for_instancing( Sub->b_Anim ) ) { return true; } if( ( ( Sub->iFlags & 0x4000 ) != 0 ) && ( false == anim_type_shared_by_instances( Sub->b_Anim ) ) ) { return true; } if( submodel_tree_blocks_instancing( Sub->Child ) ) { return true; } diff --git a/model/Model3d.cpp b/model/Model3d.cpp index 66fc08c94..44f5f6255 100644 --- a/model/Model3d.cpp +++ b/model/Model3d.cpp @@ -898,8 +898,7 @@ std::vector const &TSubModel::text_letters(std::string const &Text) { // the sequence is prepared once for each text the display shows. the texts of the model instances don't change, // so drawing a display afterwards costs a single lookup, however many instances and passes take turns - auto const prepared{m_textlayouts.find(Text)}; - if (prepared != m_textlayouts.end()) + if (auto const prepared{m_textlayouts.find(Text)}; prepared != m_textlayouts.end()) { return prepared->second; } diff --git a/model/Model3d.h b/model/Model3d.h index 27565c206..a9ef8af12 100644 --- a/model/Model3d.h +++ b/model/Model3d.h @@ -15,6 +15,8 @@ http://mozilla.org/MPL/2.0/. #include "model/material.h" #include "gl/query.h" +#include + #define EU07_USE_GEOMETRYINDEXING // Ra: specjalne typy submodeli, poza tym GL_TRIANGLES itp. @@ -159,7 +161,12 @@ public: // chwilowo // text display (TP_TEXT) data, filled on first use std::unordered_map m_letters; // sub-models of the available characters, by unicode code point bool m_lettersready { false }; // whether the character lookup was built yet - std::unordered_map> m_textlayouts; // sub-models of consecutive characters, for each text shown + // transparent hasher, so the text layouts can be looked up with any string type without a temporary std::string + struct text_hash { + using is_transparent = void; + std::size_t operator()( std::string_view const Text ) const noexcept { return std::hash{}( Text ); } + }; + std::unordered_map, text_hash, std::equal_to<>> m_textlayouts; // sub-models of consecutive characters, for each text shown TSubModel *Parent{ nullptr }; // nadrzędny, np. do wymnażania macierzy int iVisible { 1 }; // roboczy stan widoczności float fVisible { 1.f }; // visibility level diff --git a/rendering/opengl33renderer.cpp b/rendering/opengl33renderer.cpp index 33346fad2..c24f750c8 100644 --- a/rendering/opengl33renderer.cpp +++ b/rendering/opengl33renderer.cpp @@ -4152,6 +4152,23 @@ bool opengl33_renderer::Render(TModel3d *Model, material_data const *Material, f return result; } +// opaque characters of a text display, laid out in a row the same way as the translucent ones +void opengl33_renderer::Render_text(TSubModel *Submodel) +{ + if (TSubModel::pasText == nullptr) + { + return; + } + ::glPushMatrix(); + for (auto *p : Submodel->text_letters(*TSubModel::pasText)) + { + Render(p); + if (p->fMatrix) + ::glMultMatrixf(p->fMatrix->readArray()); // move on to the place of the next character + } + ::glPopMatrix(); +} + void opengl33_renderer::Render(TSubModel *Submodel) { glDebug("Render TSubModel"); @@ -4302,9 +4319,17 @@ void opengl33_renderer::Render(TSubModel *Submodel) } } } - if (Submodel->Child != nullptr) - if (Submodel->iAlpha & Submodel->iFlags & 0x001F0000) + if (Submodel->Child != nullptr && (TSubModel::iAlpha & Submodel->iFlags & 0x001F0000)) + { + if (Submodel->eType == TP_TEXT) + { + Render_text(Submodel); + } + else + { Render(Submodel->Child); + } + } if (Submodel->iFlags & 0xC000) { diff --git a/rendering/opengl33renderer.h b/rendering/opengl33renderer.h index b472849bc..1b4897386 100644 --- a/rendering/opengl33renderer.h +++ b/rendering/opengl33renderer.h @@ -314,6 +314,7 @@ class opengl33_renderer : public gfx_renderer { bool Render(TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle); bool Render(TModel3d *Model, material_data const *Material, float const Squaredistance); void Render(TSubModel *Submodel); + void Render_text(TSubModel *Submodel); // opaque characters of a text display void Render(TTrack *Track); void Render(scene::basic_cell::path_sequence::const_iterator First, scene::basic_cell::path_sequence::const_iterator Last); // renders the per-track sleeper instances (TTrack::m_sleeper_local_transforms) via GPU instancing. diff --git a/rendering/openglrenderer.cpp b/rendering/openglrenderer.cpp index ef54f32c9..180dba771 100644 --- a/rendering/openglrenderer.cpp +++ b/rendering/openglrenderer.cpp @@ -2794,6 +2794,21 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, float c return result; } +// opaque characters of a text display, laid out in a row the same way as the translucent ones +void +opengl_renderer::Render_text( TSubModel *Submodel ) { + + if( TSubModel::pasText == nullptr ) { return; } + + ::glPushMatrix(); + for( auto *p : Submodel->text_letters( *TSubModel::pasText ) ) { + Render( p ); + if( p->fMatrix ) + ::glMultMatrixf( p->fMatrix->readArray() ); // move on to the place of the next character + } + ::glPopMatrix(); +} + void opengl_renderer::Render( TSubModel *Submodel ) { @@ -3112,9 +3127,15 @@ opengl_renderer::Render( TSubModel *Submodel ) { } } } - if( Submodel->Child != nullptr ) - if( Submodel->iAlpha & Submodel->iFlags & 0x001F0000 ) + if( Submodel->Child != nullptr + && ( TSubModel::iAlpha & Submodel->iFlags & 0x001F0000 ) ) { + if( Submodel->eType == TP_TEXT ) { + Render_text( Submodel ); + } + else { Render( Submodel->Child ); + } + } if( Submodel->iFlags & 0xC000 ) ::glPopMatrix(); diff --git a/rendering/openglrenderer.h b/rendering/openglrenderer.h index 9779388c7..3a3538a6c 100644 --- a/rendering/openglrenderer.h +++ b/rendering/openglrenderer.h @@ -237,6 +237,9 @@ private: Render( TModel3d *Model, material_data const *Material, float const Squaredistance ); void Render( TSubModel *Submodel ); + // opaque characters of a text display + void + Render_text( TSubModel *Submodel ); void Render( TTrack *Track ); void