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

Merge branch 'master' into fix/sonar-reliability-security

This commit is contained in:
jerrrrycho
2026-10-11 13:34:33 +02:00
committed by GitHub
162 changed files with 4212 additions and 4590 deletions

View File

@@ -14,39 +14,43 @@ namespace flip_s3tc
struct dxt1_block
{
uint16_t c0, c1;
uint8_t dcba,
hgfe,
lkji,
ponm;
uint16_t c0;
uint16_t c1;
uint8_t dcba;
uint8_t hgfe;
uint8_t lkji;
uint8_t ponm;
};
struct dxt23_block
{
uint16_t adacabaa,
ahagafae,
alakajai,
apaoanam;
uint16_t c0, c1;
uint8_t dcba,
hgfe,
lkji,
ponm;
uint16_t adacabaa;
uint16_t ahagafae;
uint16_t alakajai;
uint16_t apaoanam;
uint16_t c0;
uint16_t c1;
uint8_t dcba;
uint8_t hgfe;
uint8_t lkji;
uint8_t ponm;
};
struct dxt45_block
{
uint8_t a0, a1;
uint8_t a0;
uint8_t a1;
struct
{
uint8_t alpha[3];
} ahagafaeadacabaa,
apaoanamalakajai;
uint16_t c0, c1;
uint8_t dcba,
hgfe,
lkji,
ponm;
uint16_t c0;
uint16_t c1;
uint8_t dcba;
uint8_t hgfe;
uint8_t lkji;
uint8_t ponm;
};
#pragma pack(pop)
@@ -123,16 +127,16 @@ void flip_dxt45_block(struct dxt45_block *block)
*/
void flip_dxt1_image(void *data, int width, int height)
{
int x, y;
struct dxt1_block temp1, temp2;
struct dxt1_block *blocks = (struct dxt1_block *)data;
struct dxt1_block temp1;
struct dxt1_block temp2;
auto blocks = (struct dxt1_block *)data;
width = (width + 3) / 4;
height = (height + 3) / 4;
for (y = 0; y < height / 2; ++y)
for (int y = 0; y < height / 2; ++y)
{
for (x = 0; x < width; ++x)
for (int x = 0; x < width; ++x)
{
temp1 = blocks[y * width + x];
temp2 = blocks[(height - y - 1) * width + x];
@@ -152,16 +156,16 @@ void flip_dxt1_image(void *data, int width, int height)
*/
void flip_dxt23_image(void *data, int width, int height)
{
int x, y;
struct dxt23_block temp1, temp2;
struct dxt23_block *blocks = (struct dxt23_block *)data;
struct dxt23_block temp1;
struct dxt23_block temp2;
auto blocks = (struct dxt23_block *)data;
width = (width + 3) / 4;
height = (height + 3) / 4;
for (y = 0; y < height / 2; ++y)
for (int y = 0; y < height / 2; ++y)
{
for (x = 0; x < width; ++x)
for (int x = 0; x < width; ++x)
{
temp1 = blocks[y * width + x];
temp2 = blocks[(height - y - 1) * width + x];
@@ -181,16 +185,16 @@ void flip_dxt23_image(void *data, int width, int height)
*/
void flip_dxt45_image(void *data, int width, int height)
{
int x, y;
struct dxt45_block temp1, temp2;
struct dxt45_block *blocks = (struct dxt45_block *)data;
struct dxt45_block temp1;
struct dxt45_block temp2;
auto blocks = (struct dxt45_block *)data;
width = (width + 3) / 4;
height = (height + 3) / 4;
for (y = 0; y < height / 2; ++y)
for (int y = 0; y < height / 2; ++y)
{
for (x = 0; x < width; ++x)
for (int x = 0; x < width; ++x)
{
temp1 = blocks[y * width + x];
temp2 = blocks[(height - y - 1) * width + x];

View File

@@ -24,7 +24,7 @@ cFrustum::calculate( glm::mat4 const &Projection, glm::mat4 const &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 ];
std::array<float, 16> clip{};
for( int column = 0; column < 4; ++column ) {
for( int row = 0; row < 4; ++row ) {
clip[ column * 4 + row ] = clipmatrix[ column ][ row ];
@@ -73,16 +73,11 @@ bool
cFrustum::point_inside( float const X, float const Y, float const Z ) const {
// cycle through the sides of the frustum, checking if the point is behind them
for( int idx = 0; idx < 6; ++idx ) {
if( m_frustum[ idx ][ plane_A ] * X
+ m_frustum[ idx ][ plane_B ] * Y
+ m_frustum[ idx ][ plane_C ] * Z
+ m_frustum[ idx ][ plane_D ] <= 0 )
return false;
}
// the point is in front of each frustum plane, i.e. inside of the frustum
return true;
return std::ranges::all_of( m_frustum, [&]( auto const &frustumplane ) {
return frustumplane[ plane_A ] * X
+ frustumplane[ plane_B ] * Y
+ frustumplane[ plane_C ] * Z
+ frustumplane[ plane_D ] > 0; } );
}
float
@@ -90,12 +85,12 @@ cFrustum::sphere_inside( float const X, float const Y, float const Z, float cons
float distance;
// go through all the sides of the frustum. bail out as soon as possible
for( int idx = 0; idx < 6; ++idx ) {
for (auto &frustumplane : m_frustum) {
distance =
m_frustum[ idx ][ plane_A ] * X
+ m_frustum[ idx ][ plane_B ] * Y
+ m_frustum[ idx ][ plane_C ] * Z
+ m_frustum[ idx ][ plane_D ];
frustumplane[ plane_A ] * X
+ frustumplane[ plane_B ] * Y
+ frustumplane[ plane_C ] * Z
+ frustumplane[ plane_D ];
if( distance <= -Radius )
return 0.0f;
}
@@ -105,52 +100,50 @@ cFrustum::sphere_inside( float const X, float const Y, float const Z, float cons
bool
cFrustum::cube_inside( float const X, float const Y, float const Z, float const Size ) const {
for( int idx = 0; idx < 6; ++idx ) {
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
// the cube is inside unless all of its corners lie behind one of the frustum planes
return std::ranges::all_of( m_frustum, [&]( auto const &frustumplane ) {
if( frustumplane[ plane_A ] * ( X - Size )
+ frustumplane[ plane_B ] * ( Y - Size )
+ frustumplane[ plane_C ] * ( Z - Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X + Size )
+ frustumplane[ plane_B ] * ( Y - Size )
+ frustumplane[ plane_C ] * ( Z - Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X - Size )
+ frustumplane[ plane_B ] * ( Y + Size )
+ frustumplane[ plane_C ] * ( Z - Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X + Size )
+ frustumplane[ plane_B ] * ( Y + Size )
+ frustumplane[ plane_C ] * ( Z - Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X - Size )
+ frustumplane[ plane_B ] * ( Y - Size )
+ frustumplane[ plane_C ] * ( Z + Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X + Size )
+ frustumplane[ plane_B ] * ( Y - Size )
+ frustumplane[ plane_C ] * ( Z + Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X - Size )
+ frustumplane[ plane_B ] * ( Y + Size )
+ frustumplane[ plane_C ] * ( Z + Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X + Size )
+ frustumplane[ plane_B ] * ( Y + Size )
+ frustumplane[ plane_C ] * ( Z + Size )
+ frustumplane[ plane_D ] > 0 )
return true;
return false;
}
return true;
return false; } );
}
void cFrustum::normalize_plane( cFrustum::side const Side ) {

View File

@@ -29,12 +29,7 @@ light_array::insert( TDynamicObject const *Owner ) {
void
light_array::remove( TDynamicObject const *Owner ) {
data.erase(
std::remove_if(
data.begin(),
data.end(),
[=]( light_record const &light ){ return light.owner == Owner; } ),
data.end() );
std::erase_if( data, [=]( light_record const &light ){ return light.owner == Owner; } );
}
// updates records in the collection
@@ -75,13 +70,13 @@ light_array::update() {
light.intensity = std::max(0.0f, std::log((float)light.count + 1.0f));
if (light.owner->DimHeadlights && !light.owner->HighBeamLights && isEnabled) // tylko przyciemnione
light.intensity *= light.owner->MoverParameters->dimMultiplier;
light.intensity *= static_cast<float>(light.owner->MoverParameters->dimMultiplier);
else if (!light.owner->DimHeadlights && !light.owner->HighBeamLights && isEnabled) // normalne
light.intensity *= light.owner->MoverParameters->normMultiplier;
light.intensity *= static_cast<float>(light.owner->MoverParameters->normMultiplier);
else if (light.owner->DimHeadlights && light.owner->HighBeamLights && isEnabled) // przyciemnione dlugie
light.intensity *= light.owner->MoverParameters->highDimMultiplier;
light.intensity *= static_cast<float>(light.owner->MoverParameters->highDimMultiplier);
else if (!light.owner->DimHeadlights && light.owner->HighBeamLights && isEnabled) // dlugie zwykle
light.intensity *= light.owner->MoverParameters->highMultiplier;
light.intensity *= static_cast<float>(light.owner->MoverParameters->highMultiplier);
else if (!isEnabled)
{
light.intensity = 0.0f;

View File

@@ -36,7 +36,7 @@ public:
update();
// types
typedef std::vector<light_record> lightrecord_array;
using lightrecord_array = std::vector<light_record>;
// members
lightrecord_array data;

View File

@@ -3,7 +3,7 @@
std::unique_ptr<gfx_renderer> null_renderer::create_func()
{
return std::unique_ptr<null_renderer>(new null_renderer());
return std::make_unique<null_renderer>();
}
bool null_renderer::renderer_register = gfx_renderer_factory::get_instance()->register_backend("null", null_renderer::create_func);

View File

@@ -17,22 +17,22 @@ public:
// constructors:
null_geometrybank() = default;
// destructor
~null_geometrybank() {};
~null_geometrybank() = default;
private:
// methods:
// create() subclass details
void
create_( gfx::geometry_handle const &Geometry ) override {}
create_( gfx::geometry_handle const &Geometry ) override { /* null implementation, nothing to do */ }
// replace() subclass details
void
replace_( gfx::geometry_handle const &Geometry ) override {}
replace_( gfx::geometry_handle const &Geometry ) override { /* null implementation, nothing to do */ }
// draw() subclass details
auto
draw_( gfx::geometry_handle const &Geometry, gfx::stream_units const &Units, unsigned int const Streams ) -> std::size_t override { return 0; }
// release() subclass details
void
release_() override {}
release_() override { /* null implementation, nothing to do */ }
};
// bare-bones render controller, in lack of anything better yet
@@ -43,7 +43,7 @@ public:
// constructors
null_renderer() = default;
// destructor
~null_renderer() { }
~null_renderer() = default;
// methods
bool
Init( GLFWwindow *Window ) override { return true; }
@@ -51,14 +51,14 @@ public:
bool
Render() override { return true; }
void
SwapBuffers() override {}
SwapBuffers() override { /* null implementation, nothing to do */ }
inline
float
Framerate() override { return 10.0f; }
bool AddViewport(const global_settings::extraviewport_config &conf) override { return false; }
bool Debug_Ui_State(std::optional<bool>) override { return false; }
void Shutdown() override {}
void Shutdown() override { /* null implementation, nothing to do */ }
// 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
@@ -100,10 +100,10 @@ public:
Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override {
m_materials.push_back(std::make_shared<opengl_material>());
m_materials.back()->name = Filename;
return m_materials.size();
return static_cast<material_handle>(m_materials.size());
}
void
Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) override {}
Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) override { /* null implementation, nothing to do */ }
IMaterial const *
Material( material_handle const Material ) const override { return m_materials.at(Material - 1).get(); }
// shader methods
@@ -112,18 +112,18 @@ public:
texture_handle
Fetch_Texture( std::string const &Filename, bool const Loadnow = true, GLint format_hint = GL_SRGB_ALPHA ) override { throw std::runtime_error("not impl"); }
void
Bind_Texture( texture_handle const Texture ) override {}
Bind_Texture( texture_handle const Texture ) override { /* null implementation, nothing to do */ }
void
Bind_Texture( std::size_t const Unit, texture_handle const Texture ) override {}
Bind_Texture( std::size_t const Unit, texture_handle const Texture ) override { /* null implementation, nothing to do */ }
opengl_texture &
Texture( texture_handle const Texture ) override { throw std::runtime_error("not impl"); }
opengl_texture const &
Texture( texture_handle const Texture ) const override { throw std::runtime_error("not impl"); }
// utility methods
void
Pick_Control_Callback( std::function<void( TSubModel const *, const glm::vec2 )> Callback ) override {}
Pick_Control_Callback( std::function<void( TSubModel const *, const glm::vec2 )> Callback ) override { /* null implementation, nothing to do */ }
void
Pick_Node_Callback( std::function<void( scene::basic_node * )> Callback ) override {}
Pick_Node_Callback( std::function<void( scene::basic_node * )> Callback ) override { /* null implementation, nothing to do */ }
TSubModel const *
Pick_Control() const override { return nullptr; }
scene::basic_node const *
@@ -132,11 +132,11 @@ public:
Mouse_Position() const override { return glm::dvec3(); }
// maintenance methods
void
Update( double const Deltatime ) override {}
Update( double const Deltatime ) override { /* null implementation, nothing to do */ }
void
Update_Pick_Control() override {}
Update_Pick_Control() override { /* null implementation, nothing to do */ }
void
Update_Pick_Node() override {}
Update_Pick_Node() override { /* null implementation, nothing to do */ }
glm::dvec3
Update_Mouse_Position() override { return glm::dvec3(); }
// debug methods
@@ -144,13 +144,13 @@ public:
info_times() const override { return empty_str; }
std::string const &
info_stats() const override { return empty_str; }
void MakeScreenshot() override {}
void MakeScreenshot() override { /* null implementation, nothing to do */ }
static std::unique_ptr<gfx_renderer> create_func();
static bool renderer_register;
virtual imgui_renderer *GetImguiRenderer()
imgui_renderer *GetImguiRenderer() override
{
return nullptr;
}

View File

@@ -16,7 +16,7 @@ void opengl33_light::apply_intensity(float const Factor) {
factor = Factor;
}
void opengl33_light::apply_angle() {}
void opengl33_light::apply_angle() const { /* nothing to do */ }
//---------------------------------------------------------------------------

View File

@@ -18,7 +18,7 @@ struct opengl33_light : public basic_light {
float factor;
void apply_intensity(float const Factor = 1.0f);
void apply_angle();
void apply_angle() const;
opengl33_light &operator=(basic_light const &Right) {
basic_light::operator=(Right);

View File

@@ -49,19 +49,19 @@ opengl33_particles::update( opengl_camera const &Camera ) {
// build billboard data for particles from visible sources
auto const camerarotation { glm::mat3( Camera.modelview() ) };
particle_vertex vertex;
for( auto const &source : sources ) {
for( auto const &[sourcekey, sourcedata] : sources ) {
auto const particlecolor {
glm::clamp(
source.second.color()
sourcedata.color()
* ( glm::vec3 { Global.DayLight.ambient }
+ 0.35f * glm::vec3{ Global.DayLight.diffuse } ) * simulation::Environment.light_intensity(),
glm::vec3{ 0.f }, glm::vec3{ 1.f } ) };
auto const &particles { source.second.sequence() };
auto const &particles { sourcedata.sequence() };
// TODO: put sanity cap on the overall amount of particles that can be drawn
auto const sizestep { 256.0 * billboard_vertices.size() };
m_particlevertices.reserve(
sizestep * std::ceil( m_particlevertices.size() + ( particles.size() * billboard_vertices.size() ) / sizestep ) );
static_cast<std::size_t>( sizestep * std::ceil( static_cast<double>(m_particlevertices.size()) + ( static_cast<double>(particles.size() * billboard_vertices.size()) ) / sizestep ) ) );
for( auto const &particle : particles ) {
// TODO: particle color support
vertex.color[ 0 ] = particlecolor.r;
@@ -72,9 +72,9 @@ opengl33_particles::update( opengl_camera const &Camera ) {
auto const offset { glm::vec3{ particle.position - Camera.position() } };
auto const rotation { glm::angleAxis( particle.rotation, glm::vec3{ 0.f, 0.f, 1.f } ) };
for( auto const &billboardvertex : billboard_vertices ) {
vertex.position = offset + ( rotation * billboardvertex.first * particle.size ) * camerarotation;
vertex.texture = billboardvertex.second;
for( auto const &[billboardoffset, billboardtexture] : billboard_vertices ) {
vertex.position = offset + ( rotation * billboardoffset * particle.size ) * camerarotation;
vertex.texture = billboardtexture;
m_particlevertices.emplace_back( vertex );
}
@@ -113,14 +113,14 @@ opengl33_particles::render() {
m_vao->setup_attrib(*m_buffer, 1, 4, GL_FLOAT, sizeof(particle_vertex), 12);
m_vao->setup_attrib(*m_buffer, 2, 2, GL_FLOAT, sizeof(particle_vertex), 28);
m_buffer->unbind(gl::buffer::ARRAY_BUFFER);
m_vao->unbind();
gl::buffer::unbind(gl::buffer::ARRAY_BUFFER);
gl::vao::unbind();
}
if (!m_shader) {
gl::shader vert("smoke.vert");
gl::shader frag("smoke.frag");
gl::program *prog = new gl::program({vert, frag});
auto prog = new gl::program({vert, frag});
m_shader = std::unique_ptr<gl::program>(prog);
}
@@ -128,11 +128,11 @@ opengl33_particles::render() {
m_shader->bind();
m_vao->bind();
glDrawArrays(GL_TRIANGLES, 0, m_particlevertices.size());
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(m_particlevertices.size()));
m_shader->unbind();
m_vao->unbind();
m_buffer->unbind(gl::buffer::ARRAY_BUFFER);
gl::program::unbind();
gl::vao::unbind();
gl::buffer::unbind(gl::buffer::ARRAY_BUFFER);
return m_particlevertices.size() / 6;
}

View File

@@ -36,7 +36,7 @@ opengl33_precipitation::create( int const Tesselation ) {
std::uint16_t index = 0;
// auto const radius { 25.f }; // cylinder radius
std::vector<float> radii { 25.f, 10.f, 5.f, 1.f };
std::vector radii { 25.f, 10.f, 5.f, 1.f };
for( auto radius : radii ) {
for( int i = 0; i <= latitudes; ++i ) {
@@ -121,7 +121,7 @@ opengl33_precipitation::update() {
m_indexbuffer->upload(gl::buffer::ELEMENT_ARRAY_BUFFER, m_indices.data(), 0, m_indices.size() * sizeof( unsigned short ));
m_vao->setup_ebo(*m_indexbuffer);
m_vao->unbind();
gl::vao::unbind();
// NOTE: vertex and index source data is superfluous past this point, but, eh
}
@@ -155,5 +155,5 @@ opengl33_precipitation::render() {
::glDrawElements( GL_TRIANGLES, static_cast<GLsizei>( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast<void const*>( 0 ) );
m_vao->unbind();
gl::vao::unbind();
}

View File

@@ -44,15 +44,13 @@ void opengl33_skydome::update() {
m_indexbuffer->upload(gl::buffer::ELEMENT_ARRAY_BUFFER, skydome.indices().data(), 0, skydome.indices().size() * sizeof( unsigned short ));
m_vao->setup_ebo(*m_indexbuffer);
m_vao->unbind();
gl::vao::unbind();
}
// ship the current dynamic data to the gpu
if( true == skydome.is_dirty() ) {
if( m_coloursbuffer ) {
// the colour buffer was already initialized, so on this run we update its content
m_coloursbuffer->upload( gl::buffer::ARRAY_BUFFER, skydome.colors().data(), 0, skydome.colors().size() * sizeof( glm::vec3 ) );
skydome.is_dirty() = false;
}
if (true == skydome.is_dirty() && m_coloursbuffer) {
// the colour buffer was already initialized, so on this run we update its content
m_coloursbuffer->upload( gl::buffer::ARRAY_BUFFER, skydome.colors().data(), 0, skydome.colors().size() * sizeof( glm::vec3 ) );
skydome.is_dirty() = false;
}
}

View File

@@ -19,7 +19,7 @@ public:
// constructors
opengl33_skydome() = default;
// destructor
~opengl33_skydome() {;}
~opengl33_skydome() = default;
// methods
// updates data stores on the opengl end. NOTE: unbinds buffers
void update();

View File

@@ -38,7 +38,7 @@ opengl_camera::visible( TDynamicObject const *Dynamic ) const {
// sphere test is faster than AABB, so we'll use it here
// we're giving vehicles some extra padding, to allow for things like shared bogeys extending past the main body
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), Dynamic->radius() * 1.25 ) > 0.0f );
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), static_cast<float>(Dynamic->radius() * 1.25) ) > 0.0f );
}
// debug helper, draws shape of frustum in world space

View File

@@ -24,7 +24,7 @@ public:
update_frustum() { update_frustum( m_projection, m_modelview ); }
inline
void
update_frustum(glm::mat4 frustumtest_proj) {
update_frustum(glm::mat4 const &frustumtest_proj) {
update_frustum(frustumtest_proj, m_modelview); }
void
update_frustum( glm::mat4 const &Projection, glm::mat4 const &Modelview );

View File

@@ -90,23 +90,23 @@ opengl_vbogeometrybank::draw_( gfx::geometry_handle const &Geometry, gfx::stream
}
::glDrawRangeElementsBaseVertex(
chunk.type,
0, chunkrecord.vertex_count,
chunkrecord.index_count, GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
chunkrecord.vertex_offset );
0, static_cast<GLuint>(chunkrecord.vertex_count),
static_cast<GLsizei>(chunkrecord.index_count), GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
static_cast<GLint>(chunkrecord.vertex_offset) );
}
else {
bind_streams( Units, Streams, chunkrecord.vertex_offset );
::glDrawRangeElements(
chunk.type,
0, chunkrecord.vertex_count,
chunkrecord.index_count, GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ) );
0, static_cast<GLuint>(chunkrecord.vertex_count),
static_cast<GLsizei>(chunkrecord.index_count), GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ) );
}
}
else {
if( m_activestreams != Streams ) {
bind_streams( Units, Streams );
}
::glDrawArrays( chunk.type, chunkrecord.vertex_offset, chunkrecord.vertex_count );
::glDrawArrays( chunk.type, static_cast<GLint>(chunkrecord.vertex_offset), static_cast<GLsizei>(chunkrecord.vertex_count) );
}
// ...post-render cleanup
/*
@@ -139,9 +139,8 @@ opengl_vbogeometrybank::setup_buffer() {
// may be better to initiate upload earlier (during update phase) and trust this effort won't go to waste
if( true == m_chunks.empty() ) { return; }
std::size_t
vertexcount{ 0 },
indexcount{ 0 };
std::size_t vertexcount{ 0 };
std::size_t indexcount{ 0 };
auto chunkiterator = m_chunks.cbegin();
for( auto &chunkrecord : m_chunkrecords ) {
// fill records for all chunks, based on the chunk data
@@ -195,7 +194,7 @@ opengl_vbogeometrybank::setup_buffer() {
}
void
opengl_vbogeometrybank::bind_buffer() {
opengl_vbogeometrybank::bind_buffer() const {
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );

View File

@@ -58,7 +58,7 @@ private:
void
setup_buffer();
void
bind_buffer();
bind_buffer() const;
void
delete_buffer();
static
@@ -87,7 +87,7 @@ public:
opengl_dlgeometrybank() = default;
// destructor:
~opengl_dlgeometrybank() {
for( auto &chunkrecord : m_chunkrecords ) {
for( auto const &chunkrecord : m_chunkrecords ) {
::glDeleteLists( chunkrecord.list, 1 ); } }
private:

View File

@@ -90,7 +90,7 @@ private:
};
enum stack_mode { gl_modelview = 0, gl_projection = 1, gl_texture = 2 };
typedef std::vector<opengl_stack> openglstack_array;
using openglstack_array = std::vector<opengl_stack>;
public:
// constructors:

View File

@@ -47,19 +47,19 @@ opengl_particles::update( opengl_camera const &Camera ) {
// build billboard data for particles from visible sources
auto const camerarotation { glm::mat3( Camera.modelview() ) };
particle_vertex vertex;
for( auto const &source : sources ) {
for( auto const &[sourcekey, sourcedata] : sources ) {
auto const particlecolor {
glm::clamp(
source.second.color()
sourcedata.color()
* ( glm::vec3 { Global.DayLight.ambient } + 0.35f * glm::vec3{ Global.DayLight.diffuse } )
* 255.f,
glm::vec3{ 0.f }, glm::vec3{ 255.f } ) };
auto const &particles { source.second.sequence() };
auto const &particles { sourcedata.sequence() };
// TODO: put sanity cap on the overall amount of particles that can be drawn
auto const sizestep { 256.0 * billboard_vertices.size() };
m_particlevertices.reserve(
sizestep * std::ceil( m_particlevertices.size() + ( particles.size() * billboard_vertices.size() ) / sizestep ) );
static_cast<std::size_t>( sizestep * std::ceil( static_cast<double>(m_particlevertices.size()) + ( static_cast<double>(particles.size() * billboard_vertices.size()) ) / sizestep ) ) );
for( auto const &particle : particles ) {
// TODO: particle color support
vertex.color[ 0 ] = static_cast<std::uint_fast8_t>( particlecolor.r );
@@ -70,9 +70,9 @@ opengl_particles::update( opengl_camera const &Camera ) {
auto const offset { glm::vec3{ particle.position - Camera.position() } };
auto const rotation { glm::angleAxis( particle.rotation, glm::vec3{ 0.f, 0.f, 1.f } ) };
for( auto const &billboardvertex : billboard_vertices ) {
vertex.position = offset + ( rotation * billboardvertex.first * particle.size ) * camerarotation;
vertex.texture = billboardvertex.second;
for( auto const &[billboardoffset, billboardtexture] : billboard_vertices ) {
vertex.position = offset + ( rotation * billboardoffset * particle.size ) * camerarotation;
vertex.texture = billboardtexture;
m_particlevertices.emplace_back( vertex );
}
@@ -147,7 +147,7 @@ opengl_particles::render( GLint const Textureunit ) {
::glTexCoordPointer( 2, GL_FLOAT, sizeof( particle_vertex ), reinterpret_cast<void const *>( sizeof( float ) * 3 + sizeof( std::uint8_t ) * 4 ) );
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
// ...draw...
::glDrawArrays( GL_QUADS, 0, m_particlevertices.size() );
::glDrawArrays( GL_QUADS, 0, static_cast<GLsizei>(m_particlevertices.size()) );
// ...and cleanup
::glPopClientAttrib();
::glBindBuffer( GL_ARRAY_BUFFER, 0 );

View File

@@ -39,7 +39,7 @@ opengl_precipitation::create( int const Tesselation ) {
std::uint16_t index = 0;
// auto const radius { 25.f }; // cylinder radius
std::vector<float> radii { 25.f, 10.f, 5.f, 1.f };
std::vector radii { 25.f, 10.f, 5.f, 1.f };
for( auto radius : radii ) {
for( int i = 0; i <= latitudes; ++i ) {

View File

@@ -54,20 +54,18 @@ void opengl_skydome::update() {
}
// ship the current dynamic data to the gpu
// TODO: ship the data if it changed since the last update
if( true == skydome.is_dirty() ) {
if( ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 ) ) {
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
auto &colors{ skydome.colors() };
/*
float twilightfactor = std::clamp( -simulation::Environment.sun().getAngle(), 0.0f, 18.0f ) / 18.0f;
auto gamma = std::lerp( glm::vec3( 0.45f ), glm::vec3( 1.0f ), twilightfactor );
for( auto & color : colors ) {
color = glm::pow( color, gamma );
}
*/
::glBufferSubData( GL_ARRAY_BUFFER, 0, colors.size() * sizeof( glm::vec3 ), colors.data() );
skydome.is_dirty() = false;
if (true == skydome.is_dirty() && ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 )) {
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
auto &colors{ skydome.colors() };
/*
float twilightfactor = std::clamp( -simulation::Environment.sun().getAngle(), 0.0f, 18.0f ) / 18.0f;
auto gamma = std::lerp( glm::vec3( 0.45f ), glm::vec3( 1.0f ), twilightfactor );
for( auto & color : colors ) {
color = glm::pow( color, gamma );
}
*/
::glBufferSubData( GL_ARRAY_BUFFER, 0, colors.size() * sizeof( glm::vec3 ), colors.data() );
skydome.is_dirty() = false;
}
// cleanup
::glPopClientAttrib();

View File

@@ -56,7 +56,7 @@ smoke_source::particle_emitter::deserialize( cParser &Input ) {
}
void
smoke_source::particle_emitter::initialize( smoke_particle &Particle ) {
smoke_source::particle_emitter::initialize( smoke_particle &Particle ) const {
auto const polarangle { glm::radians( LocalRandom( inclination[ value_limit::min ], inclination[ value_limit::max ] ) ) }; // theta
auto const azimuthalangle { glm::radians( LocalRandom( -180, 180 ) ) }; // phi
@@ -69,9 +69,9 @@ smoke_source::particle_emitter::initialize( smoke_particle &Particle ) {
Particle.velocity = launchvector * launchvelocity;
Particle.rotation = glm::radians( LocalRandom( 0, 360 ) );
Particle.size = LocalRandom( size[ value_limit::min ], size[ value_limit::max ] );
Particle.opacity = LocalRandom( opacity[ value_limit::min ], opacity[ value_limit::max ] ) / Global.SmokeFidelity;
Particle.rotation = static_cast<float>(glm::radians( LocalRandom( 0, 360 ) ));
Particle.size = static_cast<float>(LocalRandom( size[ value_limit::min ], size[ value_limit::max ] ));
Particle.opacity = static_cast<float>(LocalRandom( opacity[ value_limit::min ], opacity[ value_limit::max ] ) / Global.SmokeFidelity);
Particle.age = 0;
}
@@ -81,7 +81,7 @@ smoke_source::deserialize( cParser &Input ) {
if( false == Input.ok() ) { return false; }
while( true == deserialize_mapping( Input ) ) {
; // all work done by while()
// all work done by while()
}
return true;
@@ -166,8 +166,8 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
( ( false == Global.Smoke ) || ( true == Onlydespawn ) ) ?
0.f :
std::min<float>(
m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
m_max_particles ) );
static_cast<float>(m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity )),
static_cast<float>(m_max_particles) ) );
// consider special spawn rate cases
if( m_ownertype == owner_type::vehicle ) {
@@ -183,7 +183,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
0.f :
std::min<float>(
// m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
m_spawncount +(m_spawnrate * Timedelta * Global.SmokeFidelity * (((m_owner.vehicle->MoverParameters->enrot) / 4 ) * 0.01)), m_max_particles);
static_cast<float>(m_spawncount +(m_spawnrate * Timedelta * Global.SmokeFidelity * (((m_owner.vehicle->MoverParameters->enrot) / 4 ) * 0.01))), static_cast<float>(m_max_particles));
}
else
{
@@ -195,7 +195,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
0.f :
std::min<float>(
// m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) *0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005))), m_max_particles);
static_cast<float>(m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) *0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005)))), static_cast<float>(m_max_particles));
}
else
{
@@ -205,7 +205,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
0.f :
std::min<float>(
// m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) * (sqrt(m_owner.vehicle->MoverParameters->Im) * 0.01) * 0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005))), m_max_particles);
static_cast<float>(m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) * (sqrt(m_owner.vehicle->MoverParameters->Im) * 0.01) * 0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005)))), static_cast<float>(m_max_particles));
}
}
}
@@ -254,10 +254,8 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
// if we still have pending requests after filling entire container replace older particles
if( m_spawncount >= 1.f ) {
// sort all particles from most to least transparent, oldest to youngest if it's a tie
std::sort(
std::begin( m_particles ),
std::end( m_particles ),
[]( smoke_particle const &Left, smoke_particle const &Right ) {
std::ranges::sort(
m_particles, []( smoke_particle const &Left, smoke_particle const &Right ) {
return ( Left.opacity != Right.opacity ?
Left.opacity < Right.opacity :
Left.age > Right.age ); } );
@@ -283,7 +281,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
// determine bounding area from calculated bounding box
if( false == m_particles.empty() ) {
m_area.center = glm::mix(boundingbox[value_limit::min], boundingbox[value_limit::max], 0.5);
m_area.radius = 0.5 * ( glm::length( boundingbox[ value_limit::max ] - boundingbox[ value_limit::min ] ) );
m_area.radius = static_cast<float>(0.5 * ( glm::length( boundingbox[ value_limit::max ] - boundingbox[ value_limit::min ] ) ));
}
else {
m_area.center = location();
@@ -331,10 +329,9 @@ smoke_source::initialize( smoke_particle &Particle ) {
Particle.position = location();
if( m_ownertype == owner_type::vehicle ) {
Particle.opacity *= m_owner.vehicle->MoverParameters->dizel_fill;
auto const enginerevolutionsfactor { 1.5f }; // high engine revolutions increase initial particle velocity
switch( m_owner.vehicle->MoverParameters->EngineType ) {
case TEngineType::DieselElectric: {
Particle.opacity *= static_cast<float>(m_owner.vehicle->MoverParameters->dizel_fill);
if (m_owner.vehicle->MoverParameters->EngineType == TEngineType::DieselElectric)
{
if (m_owner.vehicle->MoverParameters->dizel_spinup == true)
{
Particle.velocity *= 0.38*(((m_owner.vehicle->MoverParameters->enrot)/2)*0.5); // / m_owner.vehicle->MoverParameters->dizel_fill *0.01)) ;
@@ -347,11 +344,6 @@ smoke_source::initialize( smoke_particle &Particle ) {
//Particle.velocity *= m_owner.vehicle->GetVelocity(); // / m_owner.vehicle->MoverParameters->dizel_fill *0.01)) ;
}
break;
}
default: {
break;
}
}
}
}
@@ -368,28 +360,23 @@ smoke_source::update( smoke_particle &Particle, bounding_box &Boundingbox, doubl
// crude smoke dispersion simulation
// http://www.auburn.edu/academic/forestry_wildlife/fire/smoke_guide/smoke_dispersion.htm
switch (m_ownertype)
if (m_ownertype == owner_type::vehicle)
{
case owner_type::vehicle:
Particle.velocity.y += static_cast<float>(( 0.025 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 90 ) * Timedelta); // decelerate faster in cold weather
Particle.velocity.y -= static_cast<float>(( (0.05 * (pow(m_owner.vehicle->GetVelocity()*1,0.4))) * Particle.velocity.y ) * Global.Overcast * Timedelta); // decelerate faster with high air humidity and/or precipitation
}
else
{
Particle.velocity.y += ( 0.025 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 90 ) * Timedelta; // decelerate faster in cold weather
Particle.velocity.y -= ( (0.05 * (pow(m_owner.vehicle->GetVelocity()*1,0.4))) * Particle.velocity.y ) * Global.Overcast * Timedelta; // decelerate faster with high air humidity and/or precipitation
break;
}
default:
{
Particle.velocity.y += ( 0.005 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 10 ) * Timedelta; // decelerate faster in cold weather
Particle.velocity.y -= ( 0.050 * Particle.velocity.y ) * Global.Overcast * Timedelta; // decelerate faster with high air humidity and/or precipitation
Particle.velocity.y = std::max<float>( 0.25 * ( 2.f - Global.Overcast ), Particle.velocity.y ); // put a cap on deceleration
break;
}
}
Particle.velocity.y += static_cast<float>(( 0.005 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 10 ) * Timedelta); // decelerate faster in cold weather
Particle.velocity.y -= static_cast<float>(( 0.050 * Particle.velocity.y ) * Global.Overcast * Timedelta); // decelerate faster with high air humidity and/or precipitation
Particle.velocity.y = std::max<float>( static_cast<float>(0.25 * ( 2.f - Global.Overcast )), Particle.velocity.y ); // put a cap on deceleration
}
Particle.position += Particle.velocity * static_cast<float>( Timedelta );
Particle.position += 0.1f * Particle.age * simulation::Environment.wind() * static_cast<float>( Timedelta );
// m_velocitymodifier.update( Particle.velocity, Timedelta );
Particle.age += Timedelta;
Particle.age += static_cast<float>(Timedelta);
// update bounding box
Boundingbox[ value_limit::min ] = glm::min( Boundingbox[ value_limit::min ], Particle.position - glm::dvec3{ Particle.size } );
@@ -467,21 +454,19 @@ particle_manager::find( std::string const &Template ) {
auto const templatename { ToLower( Template ) };
// try to locate specified rail profile...
auto const lookup { m_sourcetemplates.find( templatename ) };
if( lookup != m_sourcetemplates.end() ) {
if( auto const lookup { m_sourcetemplates.find( templatename ) }; lookup != m_sourcetemplates.end() ) {
// ...if it works, we're done...
return &(lookup->second);
}
// ... and if it fails try to add the template to the database from a data file
smoke_source source;
cParser parser(templatepath + templatename + ".txt", cParser::buffer_FILE);
if (source.deserialize(parser))
if (cParser parser(templatepath + templatename + ".txt", cParser::buffer_FILE); source.deserialize(parser))
{
// if deserialization didn't fail finish source setup...
source.m_opacitymodifier.bind( &Global.SmokeFidelity );
// ...then cache the source as template for future instances
m_sourcetemplates.emplace( templatename, source );
m_sourcetemplates.try_emplace( templatename, source );
// should be 'safe enough' to return lookup result directly afterwards
return &( m_sourcetemplates.find( templatename )->second );
}

View File

@@ -56,7 +56,7 @@ public:
return (
m_valuechangemodifier == nullptr ?
m_valuechange :
m_valuechange / *( m_valuechangemodifier ) ); }
m_valuechange / *m_valuechangemodifier ); }
private:
//types
@@ -122,7 +122,7 @@ private:
glm::vec3 color { 16.f / 255.f };
void deserialize( cParser &Input );
void initialize( smoke_particle &Particle );
void initialize( smoke_particle &Particle ) const;
};
using bounding_box = glm::dvec3[ 2 ]; // bounding box of owned particles
@@ -212,7 +212,7 @@ fixedstep_modifier<Type_>::update( Type_ &Variable, double const Timedelta ) con
auto const valuechange { (
m_valuechangemodifier == nullptr ?
m_valuechange :
m_valuechange / *( m_valuechangemodifier ) ) };
m_valuechange / *m_valuechangemodifier ) };
Variable += ( valuechange * static_cast<float>( Timedelta ) );
// clamp down to allowed value range
Variable = glm::max( Variable, m_valuelimits[ value_limit::min ] );

View File

@@ -29,9 +29,9 @@ void screenshot_manager::screenshot_save_thread( char *img, int w, int h )
stride = -w * 3;
}
char datetime[64];
std::array<char, 64> datetime{};
std::tm const tm_info = local_tm(std::time(nullptr));
strftime(datetime, 64, "%Y-%m-%d_%H-%M-%S", &tm_info);
strftime(datetime.data(), datetime.size(), "%Y-%m-%d_%H-%M-%S", &tm_info);
uint64_t perf;
#ifdef _WIN32
@@ -42,7 +42,7 @@ void screenshot_manager::screenshot_save_thread( char *img, int w, int h )
perf = ts.tv_nsec;
#endif
std::string filename = Global.screenshot_dir + "/" + std::string(datetime) +
std::string filename = Global.screenshot_dir + "/" + std::string(datetime.data()) +
"_" + std::to_string(perf) + ".png";
if (png_image_write_to_file(&png, filename.c_str(), 0, img, stride, nullptr) == 1)
@@ -55,7 +55,7 @@ void screenshot_manager::screenshot_save_thread( char *img, int w, int h )
void screenshot_manager::make_screenshot()
{
char *img = new char[Global.fb_size.x * Global.fb_size.y * 4];
auto img = new char[Global.fb_size.x * Global.fb_size.y * 4];
glReadPixels(0, 0, Global.fb_size.x, Global.fb_size.y, Global.gfx_usegles ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);
//m7t: use pbo