17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 02:49:19 +02:00

Merge branch 'master' into feat/modern-editor

This commit is contained in:
2026-10-08 17:44:58 +02:00
41 changed files with 479 additions and 319 deletions

View File

@@ -22,30 +22,14 @@ cFrustum::calculate() {
void
cFrustum::calculate( glm::mat4 const &Projection, glm::mat4 const &Modelview ) {
float const *proj = glm::value_ptr( Projection );
float const *modl = glm::value_ptr( Modelview );
// multiply the matrices to retrieve clipping planes (column-major, same layout as the old float[16] form)
auto const clipmatrix { Projection * Modelview };
float clip[ 16 ];
// multiply the matrices to retrieve clipping planes
clip[ 0 ] = modl[ 0 ] * proj[ 0 ] + modl[ 1 ] * proj[ 4 ] + modl[ 2 ] * proj[ 8 ] + modl[ 3 ] * proj[ 12 ];
clip[ 1 ] = modl[ 0 ] * proj[ 1 ] + modl[ 1 ] * proj[ 5 ] + modl[ 2 ] * proj[ 9 ] + modl[ 3 ] * proj[ 13 ];
clip[ 2 ] = modl[ 0 ] * proj[ 2 ] + modl[ 1 ] * proj[ 6 ] + modl[ 2 ] * proj[ 10 ] + modl[ 3 ] * proj[ 14 ];
clip[ 3 ] = modl[ 0 ] * proj[ 3 ] + modl[ 1 ] * proj[ 7 ] + modl[ 2 ] * proj[ 11 ] + modl[ 3 ] * proj[ 15 ];
clip[ 4 ] = modl[ 4 ] * proj[ 0 ] + modl[ 5 ] * proj[ 4 ] + modl[ 6 ] * proj[ 8 ] + modl[ 7 ] * proj[ 12 ];
clip[ 5 ] = modl[ 4 ] * proj[ 1 ] + modl[ 5 ] * proj[ 5 ] + modl[ 6 ] * proj[ 9 ] + modl[ 7 ] * proj[ 13 ];
clip[ 6 ] = modl[ 4 ] * proj[ 2 ] + modl[ 5 ] * proj[ 6 ] + modl[ 6 ] * proj[ 10 ] + modl[ 7 ] * proj[ 14 ];
clip[ 7 ] = modl[ 4 ] * proj[ 3 ] + modl[ 5 ] * proj[ 7 ] + modl[ 6 ] * proj[ 11 ] + modl[ 7 ] * proj[ 15 ];
clip[ 8 ] = modl[ 8 ] * proj[ 0 ] + modl[ 9 ] * proj[ 4 ] + modl[ 10 ] * proj[ 8 ] + modl[ 11 ] * proj[ 12 ];
clip[ 9 ] = modl[ 8 ] * proj[ 1 ] + modl[ 9 ] * proj[ 5 ] + modl[ 10 ] * proj[ 9 ] + modl[ 11 ] * proj[ 13 ];
clip[ 10 ] = modl[ 8 ] * proj[ 2 ] + modl[ 9 ] * proj[ 6 ] + modl[ 10 ] * proj[ 10 ] + modl[ 11 ] * proj[ 14 ];
clip[ 11 ] = modl[ 8 ] * proj[ 3 ] + modl[ 9 ] * proj[ 7 ] + modl[ 10 ] * proj[ 11 ] + modl[ 11 ] * proj[ 15 ];
clip[ 12 ] = modl[ 12 ] * proj[ 0 ] + modl[ 13 ] * proj[ 4 ] + modl[ 14 ] * proj[ 8 ] + modl[ 15 ] * proj[ 12 ];
clip[ 13 ] = modl[ 12 ] * proj[ 1 ] + modl[ 13 ] * proj[ 5 ] + modl[ 14 ] * proj[ 9 ] + modl[ 15 ] * proj[ 13 ];
clip[ 14 ] = modl[ 12 ] * proj[ 2 ] + modl[ 13 ] * proj[ 6 ] + modl[ 14 ] * proj[ 10 ] + modl[ 15 ] * proj[ 14 ];
clip[ 15 ] = modl[ 12 ] * proj[ 3 ] + modl[ 13 ] * proj[ 7 ] + modl[ 14 ] * proj[ 11 ] + modl[ 15 ] * proj[ 15 ];
for( int column = 0; column < 4; ++column ) {
for( int row = 0; row < 4; ++row ) {
clip[ column * 4 + row ] = clipmatrix[ column ][ row ];
}
}
// get the sides of the frustum.
m_frustum[ side_RIGHT ][ plane_A ] = clip[ 3 ] - clip[ 0 ];

View File

@@ -18,7 +18,7 @@ public:
int index{ -1 }; // 0: front lights, 1: rear lights
glm::dvec3 position; // position of the light in 3d scene
glm::vec3 direction; // direction of the light in 3d scene
glm::vec3 color{ 255.0f / 255.0f, 241.0f / 255.0f, 224.0f / 255.0f }; // color of the light, default is halogen light
glm::vec3 color{ 1.0f, 241.0f / 255.0f, 224.0f / 255.0f }; // color of the light, default is halogen light
float intensity{ 0.0f }; // (combined) intensity of the light(s)
int count{ 0 }; // number (or pattern) of active light(s)
glm::vec3 state{ 0.f }; // state of individual lights

View File

@@ -29,6 +29,23 @@ http://mozilla.org/MPL/2.0/.
int constexpr EU07_PICKBUFFERSIZE{ 1024 }; // size of (square) textures bound with the pick framebuffer
int constexpr EU07_REFLECTIONFIDELITYOFFSET { 250 }; // artificial increase of range for reflection pass detail reduction
namespace {
// returns material assigned to the submodel, resolving replacable skins. null_handle if no skin set is bound
material_handle
submodel_material( TSubModel const *Submodel ) {
if( Submodel->m_material >= 0 ) {
return Submodel->m_material;
}
return (
TSubModel::ReplacableSkinId != nullptr ?
TSubModel::ReplacableSkinId[ -Submodel->m_material ] :
null_handle );
}
} // namespace
void GLAPIENTRY
ErrorCallback( GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam ) {
/*
@@ -1975,7 +1992,7 @@ bool opengl33_renderer::Render(world_environment *Environment)
auto const fogfactor{std::clamp(Global.fFogEnd / 2000.f, 0.f, 1.f)}; // stronger fog reduces opacity of the celestial bodies
float const duskfactor = 1.0f - std::clamp(std::abs(Environment->m_sun.getAngle()), 0.0f, 12.0f) / 12.0f;
glm::vec3 suncolor = glm::mix(glm::vec3(255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f), glm::vec3(235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f), duskfactor);
glm::vec3 suncolor = glm::mix(glm::vec3(1.0f, 242.0f / 255.0f, 231.0f / 255.0f), glm::vec3(235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f), duskfactor);
// sun
{
@@ -2381,8 +2398,7 @@ opengl_material &opengl33_renderer::Material(material_handle const Material)
opengl_material const & opengl33_renderer::Material( TSubModel const * Submodel ) const {
auto const material { Submodel->m_material >= 0 ? Submodel->m_material : Submodel->ReplacableSkinId[ -Submodel->m_material ] };
return m_materials.material( material );
return m_materials.material( submodel_material( Submodel ) );
}
texture_handle opengl33_renderer::Fetch_Texture(std::string const &Filename, bool const Loadnow, GLint format_hint)
@@ -4008,7 +4024,7 @@ void opengl33_renderer::Render(TSubModel *Submodel)
// textures...
if (Submodel->m_material < 0)
{ // zmienialne skóry
Bind_Material(Submodel->ReplacableSkinId[-Submodel->m_material], Submodel);
Bind_Material(submodel_material(Submodel), Submodel);
}
else
{
@@ -4045,7 +4061,7 @@ void opengl33_renderer::Render(TSubModel *Submodel)
if (Submodel->m_material < 0)
{ // zmienialne skóry
Bind_Material_Shadow(Submodel->ReplacableSkinId[-Submodel->m_material]);
Bind_Material_Shadow(submodel_material(Submodel));
}
else
{
@@ -4964,6 +4980,21 @@ bool opengl33_renderer::Render_Alpha(TModel3d *Model, material_data const *Mater
return result;
}
// characters of a text display, laid out in a row. the text can be encoded in utf-8 or in windows-1250
void opengl33_renderer::Render_Alpha_text(TSubModel *Submodel)
{
if (TSubModel::pasText == nullptr)
{
return;
}
for (auto *p : Submodel->text_letters(*TSubModel::pasText))
{ // translucent only, for the time being
Render_Alpha(p);
if (p->fMatrix)
::glMultMatrixf(p->fMatrix->readArray()); // move on to the place of the next character
}
}
void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
{
// renderowanie przezroczystych przez DL
@@ -5004,7 +5035,7 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
// textures...
if (Submodel->m_material < 0)
{ // zmienialne skóry
Bind_Material(Submodel->ReplacableSkinId[-Submodel->m_material], Submodel);
Bind_Material(submodel_material(Submodel), Submodel);
}
else
{
@@ -5036,7 +5067,7 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
if (Submodel->m_material < 0)
{ // zmienialne skóry
Bind_Material_Shadow(Submodel->ReplacableSkinId[-Submodel->m_material]);
Bind_Material_Shadow(submodel_material(Submodel));
}
else
{
@@ -5192,29 +5223,7 @@ void opengl33_renderer::Render_Alpha(TSubModel *Submodel)
{
if (Submodel->eType == TP_TEXT)
{ // tekst renderujemy w specjalny sposób, zamiast submodeli z łańcucha Child
int i, j = (int)Submodel->pasText->size();
TSubModel *p;
if (!Submodel->smLetter)
{ // jeśli nie ma tablicy, to ją stworzyć; miejsce nieodpowiednie, ale tymczasowo może być
Submodel->smLetter = new TSubModel *[256]; // tablica wskaźników submodeli dla wyświetlania tekstu
memset(Submodel->smLetter, 0, 256 * sizeof(TSubModel *)); // wypełnianie zerami
p = Submodel->Child;
while (p)
{
Submodel->smLetter[p->pName[0]] = p;
p = p->Next; // kolejny znak
}
}
for (i = 1; i <= j; ++i)
{
p = Submodel->smLetter[(*(Submodel->pasText))[i]]; // znak do wyświetlenia
if (p)
{ // na razie tylko jako przezroczyste
Render_Alpha(p);
if (p->fMatrix)
::glMultMatrixf(p->fMatrix->readArray()); // przesuwanie widoku
}
}
Render_Alpha_text(Submodel);
}
else if (Submodel->iAlpha & Submodel->iFlags & 0x002F0000)
Render_Alpha(Submodel->Child);

View File

@@ -322,6 +322,7 @@ class opengl33_renderer : public gfx_renderer {
bool Render_Alpha(TModel3d *Model, material_data const *Material, float const Squaredistance, glm::dvec3 const &Position, glm::vec3 const &Angle);
bool Render_Alpha(TModel3d *Model, material_data const *Material, float const Squaredistance);
void Render_Alpha(TSubModel *Submodel);
void Render_Alpha_text(TSubModel *Submodel); // characters of a text display
void Update_Lights(light_array &Lights);
glm::vec3 pick_color(std::size_t const Index);
std::size_t pick_index(glm::ivec3 const &Color);

View File

@@ -31,6 +31,23 @@ int constexpr EU07_PICKBUFFERSIZE { 1024 }; // size of (square) textures bound w
int constexpr EU07_ENVIRONMENTBUFFERSIZE { 256 }; // size of (square) environmental cube map texture
int constexpr EU07_REFLECTIONFIDELITYOFFSET { 250 }; // artificial increase of range for reflection pass detail reduction
namespace {
// returns material assigned to the submodel, resolving replacable skins. null_handle if no skin set is bound
material_handle
submodel_material( TSubModel const *Submodel ) {
if( Submodel->m_material >= 0 ) {
return Submodel->m_material;
}
return (
TSubModel::ReplacableSkinId != nullptr ?
TSubModel::ReplacableSkinId[ -Submodel->m_material ] :
null_handle );
}
} // namespace
float const EU07_OPACITYDEFAULT { 0.5f };
bool
@@ -1571,7 +1588,7 @@ opengl_renderer::Render( world_environment *Environment ) {
auto const fogfactor { std::clamp( Global.fFogEnd / 2000.f, 0.f, 1.f ) }; // closer/denser fog reduces opacity of the celestial bodies
float const duskfactor = 1.0f - std::clamp( std::abs( Environment->m_sun.getAngle() ), 0.0f, 12.0f ) / 12.0f;
glm::vec3 suncolor = glm::mix(
glm::vec3( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
glm::vec3( 1.0f, 242.0f / 255.0f, 231.0f / 255.0f ),
glm::vec3( 235.0f / 255.0f, 140.0f / 255.0f, 36.0f / 255.0f ),
duskfactor );
// sun
@@ -1790,8 +1807,7 @@ opengl_renderer::Material( material_handle const Material ) const {
opengl_material const &
opengl_renderer::Material( TSubModel const * Submodel ) const {
auto const material { Submodel->m_material >= 0 ? Submodel->m_material : Submodel->ReplacableSkinId[ -Submodel->m_material ] };
return m_materials.material( material );
return m_materials.material( submodel_material( Submodel ) );
}
// shader methods
@@ -2768,10 +2784,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
}
#endif
// material configuration:
auto const material{ (
Submodel->m_material < 0 ?
Submodel->ReplacableSkinId[ -Submodel->m_material ] : // zmienialne skóry
Submodel->m_material ) }; // również 0
auto const material{ submodel_material( Submodel ) }; // zmienialne skóry, również 0
// textures...
Bind_Material( material );
// ...colors and opacity...
@@ -2879,7 +2892,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
// material configuration:
// textures...
if( Submodel->m_material < 0 ) { // zmienialne skóry
Bind_Material( TSubModel::ReplacableSkinId[ -Submodel->m_material ], Submodel );
Bind_Material( submodel_material( Submodel ), Submodel );
}
else {
// również 0
@@ -2897,7 +2910,7 @@ opengl_renderer::Render( TSubModel *Submodel ) {
::glColor3fv( glm::value_ptr( pick_color( m_pickcontrolsitems.size() ) ) );
// textures...
if( Submodel->m_material < 0 ) { // zmienialne skóry
Bind_Material( TSubModel::ReplacableSkinId[ -Submodel->m_material ], Submodel );
Bind_Material( submodel_material( Submodel ), Submodel );
}
else {
// również 0
@@ -2971,10 +2984,10 @@ opengl_renderer::Render( TSubModel *Submodel ) {
auto const unitstate = m_unitstate;
switch_units( m_unitstate.diffuse, false, false );
auto const *lightcolor {
glm::vec3 const lightcolor {
Submodel->DiffuseOverride.r < 0.f ? // -1 indicates no override
glm::value_ptr( Submodel->f4Diffuse ) :
glm::value_ptr( Submodel->DiffuseOverride ) };
glm::vec3( Submodel->f4Diffuse ) :
Submodel->DiffuseOverride };
// main draw call
if( Global.Overcast > 1.f ) {
@@ -2987,9 +3000,9 @@ opengl_renderer::Render( TSubModel *Submodel ) {
::glPointSize( pointsize * fogfactor );
::glColor4f(
lightcolor[ 0 ],
lightcolor[ 1 ],
lightcolor[ 2 ],
lightcolor.r,
lightcolor.g,
lightcolor.b,
Submodel->fVisible * std::min( 1.f, lightlevel ) * 0.5f );
::glDepthMask( GL_FALSE );
m_geometry.draw( Submodel->m_geometry.handle );
@@ -2997,9 +3010,9 @@ opengl_renderer::Render( TSubModel *Submodel ) {
}
::glPointSize( pointsize );
::glColor4f(
lightcolor[ 0 ],
lightcolor[ 1 ],
lightcolor[ 2 ],
lightcolor.r,
lightcolor.g,
lightcolor.b,
Submodel->fVisible * std::min( 1.f, lightlevel ) );
m_geometry.draw( Submodel->m_geometry.handle );
@@ -3800,6 +3813,19 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, f
return result;
}
// characters of a text display, laid out in a row. the text can be encoded in utf-8 or in windows-1250
void
opengl_renderer::Render_Alpha_text( TSubModel *Submodel ) {
if( TSubModel::pasText == nullptr ) { return; }
for( auto *p : Submodel->text_letters( *TSubModel::pasText ) ) { // translucent only, for the time being
Render_Alpha( p );
if( p->fMatrix )
::glMultMatrixf( p->fMatrix->readArray() ); // move on to the place of the next character
}
}
void
opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
// renderowanie przezroczystych przez DL
@@ -3845,10 +3871,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
#endif
// material configuration:
// textures...
auto const material { (
Submodel->m_material < 0 ?
Submodel->ReplacableSkinId[ -Submodel->m_material ] : // zmienialne skóry
Submodel->m_material ) }; // również 0
auto const material { submodel_material( Submodel ) }; // zmienialne skóry, również 0
// textures...
Bind_Material( material );
// ...colors and opacity...
@@ -3923,7 +3946,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
// material configuration:
// textures...
if( Submodel->m_material < 0 ) { // zmienialne skóry
Bind_Material( TSubModel::ReplacableSkinId[ -Submodel->m_material ], Submodel );
Bind_Material( submodel_material( Submodel ), Submodel );
}
else {
// również 0
@@ -3986,14 +4009,14 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
auto const unitstate = m_unitstate;
switch_units( unitstate.diffuse, false, false );
auto const *lightcolor {
glm::vec3 const lightcolor {
Submodel->DiffuseOverride.r < 0.f ? // -1 indicates no override
glm::value_ptr( Submodel->f4Diffuse ) :
glm::value_ptr( Submodel->DiffuseOverride ) };
glm::vec3( Submodel->f4Diffuse ) :
Submodel->DiffuseOverride };
::glColor4f(
lightcolor[ 0 ],
lightcolor[ 1 ],
lightcolor[ 2 ],
lightcolor.r,
lightcolor.g,
lightcolor.b,
Submodel->fVisible * glarelevel );
// main draw call
@@ -4018,25 +4041,7 @@ opengl_renderer::Render_Alpha( TSubModel *Submodel ) {
if( Submodel->Child != nullptr ) {
if( Submodel->eType == TP_TEXT ) { // tekst renderujemy w specjalny sposób, zamiast submodeli z łańcucha Child
int i, j = (int)Submodel->pasText->size();
TSubModel *p;
if( !Submodel->smLetter ) { // jeśli nie ma tablicy, to ją stworzyć; miejsce nieodpowiednie, ale tymczasowo może być
Submodel->smLetter = new TSubModel *[ 256 ]; // tablica wskaźników submodeli dla wyświetlania tekstu
std::memset(Submodel->smLetter, 0, 256 * sizeof( TSubModel * )); // wypełnianie zerami
p = Submodel->Child;
while( p ) {
Submodel->smLetter[ p->pName[ 0 ] ] = p;
p = p->Next; // kolejny znak
}
}
for( i = 1; i <= j; ++i ) {
p = Submodel->smLetter[ ( *( Submodel->pasText) )[ i ] ]; // znak do wyświetlenia
if( p ) { // na razie tylko jako przezroczyste
Render_Alpha( p );
if( p->fMatrix )
::glMultMatrixf( p->fMatrix->readArray() ); // przesuwanie widoku
}
}
Render_Alpha_text( Submodel );
}
else if( Submodel->iAlpha & Submodel->iFlags & 0x002F0000 )
Render_Alpha( Submodel->Child );

View File

@@ -270,6 +270,9 @@ private:
Render_Alpha( TModel3d *Model, material_data const *Material, float const Squaredistance );
void
Render_Alpha( TSubModel *Submodel );
// characters of a text display
void
Render_Alpha_text( TSubModel *Submodel );
void
Update_Lights( light_array &Lights );
bool

View File

@@ -31,7 +31,7 @@ basic_precipitation::init() {
void
basic_precipitation::update() {
auto const timedelta { static_cast<float>( ( DebugModeFlag ? Timer::GetDeltaTime() : Timer::GetDeltaTime() ) ) };
auto const timedelta { static_cast<float>( Timer::GetDeltaTime() ) };
if( timedelta == 0.0 ) { return; }