diff --git a/src/client/game.cpp b/src/client/game.cpp index 18a2ecc0e7cb..4a4c89fcf53e 100644 --- a/src/client/game.cpp +++ b/src/client/game.cpp @@ -398,7 +398,7 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter CachedPixelShaderSetting m_texture3{"texture3"}; CachedVertexShaderSetting m_texel_size0_vertex{"texelSize0"}; CachedPixelShaderSetting m_texel_size0_pixel{"texelSize0"}; - std::array m_texel_size0_values; + v2f m_texel_size0; CachedStructPixelShaderSetting m_exposure_params_pixel{ "exposureParams", std::array { @@ -477,10 +477,7 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter void onSetConstants(video::IMaterialRendererServices *services) override { video::SColorf fogcolorf(m_sky->getFogColor()); - float fogcolorfa[4] = { - fogcolorf.r, fogcolorf.g, fogcolorf.b, fogcolorf.a, - }; - m_fog_color.set(fogcolorfa, services); + m_fog_color.set(fogcolorf, services); float fog_distance = 10000 * BS; if (m_fog_enabled && !*m_force_fog_off) @@ -494,11 +491,7 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter u32 daynight_ratio = (float)m_client->getEnv().getDayNightRatio(); video::SColorf sunlight; get_sunlight_color(&sunlight, daynight_ratio); - float dnc[3] = { - sunlight.r, - sunlight.g, - sunlight.b }; - m_day_light.set(dnc, services); + m_day_light.set(sunlight, services); video::SColorf star_color = m_sky->getCurrentStarColor(); float clr[4] = {star_color.r, star_color.g, star_color.b, star_color.a}; @@ -513,24 +506,18 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter m_animation_timer_delta_vertex.set(&animation_timer_delta_f, services); m_animation_timer_delta_pixel.set(&animation_timer_delta_f, services); - float eye_position_array[3]; v3f epos = m_client->getEnv().getLocalPlayer()->getEyePosition(); - epos.getAs3Values(eye_position_array); - m_eye_position_pixel.set(eye_position_array, services); - m_eye_position_vertex.set(eye_position_array, services); + m_eye_position_pixel.set(epos, services); + m_eye_position_vertex.set(epos, services); if (m_client->getMinimap()) { - float minimap_yaw_array[3]; v3f minimap_yaw = m_client->getMinimap()->getYawVec(); - minimap_yaw.getAs3Values(minimap_yaw_array); - m_minimap_yaw.set(minimap_yaw_array, services); + m_minimap_yaw.set(minimap_yaw, services); } - float camera_offset_array[3]; v3f offset = intToFloat(m_client->getCamera()->getOffset(), BS); - offset.getAs3Values(camera_offset_array); - m_camera_offset_pixel.set(camera_offset_array, services); - m_camera_offset_vertex.set(camera_offset_array, services); + m_camera_offset_pixel.set(offset, services); + m_camera_offset_vertex.set(offset, services); SamplerLayer_t tex_id; tex_id = 0; @@ -542,8 +529,8 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter tex_id = 3; m_texture3.set(&tex_id, services); - m_texel_size0_vertex.set(m_texel_size0_values.data(), services); - m_texel_size0_pixel.set(m_texel_size0_values.data(), services); + m_texel_size0_vertex.set(m_texel_size0, services); + m_texel_size0_pixel.set(m_texel_size0, services); const AutoExposure &exposure_params = m_client->getEnv().getLocalPlayer()->getLighting().exposure; std::array exposure_buffer = { @@ -577,14 +564,12 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter transform.transformVect(sun_position); sun_position.normalize(); - float sun_position_array[3] = { sun_position.X, sun_position.Y, sun_position.Z}; - m_sun_position_pixel.set(sun_position_array, services); + m_sun_position_pixel.set(sun_position, services); float sun_brightness = rangelim(107.143f * m_sky->getSunDirection().dotProduct(v3f(0.f, 1.f, 0.f)), 0.f, 1.f); m_sun_brightness_pixel.set(&sun_brightness, services); } else { - float sun_position_array[3] = { 0.f, 0.f, -1.f }; - m_sun_position_pixel.set(sun_position_array, services); + m_sun_position_pixel.set(v3f(0.f, 0.f, -1.f), services); float sun_brightness = 0.f; m_sun_brightness_pixel.set(&sun_brightness, services); @@ -596,15 +581,12 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter transform.transformVect(moon_position); moon_position.normalize(); - float moon_position_array[3] = { moon_position.X, moon_position.Y, moon_position.Z}; - m_moon_position_pixel.set(moon_position_array, services); + m_moon_position_pixel.set(moon_position, services); float moon_brightness = rangelim(107.143f * m_sky->getMoonDirection().dotProduct(v3f(0.f, 1.f, 0.f)), 0.f, 1.f); m_moon_brightness_pixel.set(&moon_brightness, services); - } - else { - float moon_position_array[3] = { 0.f, 0.f, -1.f }; - m_moon_position_pixel.set(moon_position_array, services); + } else { + m_moon_position_pixel.set(v3f(0.f, 0.f, -1.f), services); float moon_brightness = 0.f; m_moon_brightness_pixel.set(&moon_brightness, services); @@ -619,12 +601,9 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter video::ITexture *texture = material.getTexture(0); if (texture) { core::dimension2du size = texture->getSize(); - m_texel_size0_values[0] = 1.f / size.Width; - m_texel_size0_values[1] = 1.f / size.Height; - } - else { - m_texel_size0_values[0] = 0.f; - m_texel_size0_values[1] = 0.f; + m_texel_size0 = v2f(1.f / size.Width, 1.f / size.Height); + } else { + m_texel_size0 = v2f(); } } }; diff --git a/src/client/shader.cpp b/src/client/shader.cpp index 219b4d80798c..f9274d691398 100644 --- a/src/client/shader.cpp +++ b/src/client/shader.cpp @@ -227,7 +227,7 @@ class MainShaderConstantSetter : public IShaderConstantSetter // Set world matrix core::matrix4 world = driver->getTransform(video::ETS_WORLD); - m_world.set(*reinterpret_cast(world.pointer()), services); + m_world.set(world, services); // Set clip matrix core::matrix4 worldView; @@ -237,12 +237,12 @@ class MainShaderConstantSetter : public IShaderConstantSetter core::matrix4 worldViewProj; worldViewProj = driver->getTransform(video::ETS_PROJECTION); worldViewProj *= worldView; - m_world_view_proj.set(*reinterpret_cast(worldViewProj.pointer()), services); + m_world_view_proj.set(worldViewProj, services); if (driver->getDriverType() == video::EDT_OGLES2 || driver->getDriverType() == video::EDT_OPENGL3) { core::matrix4 texture = driver->getTransform(video::ETS_TEXTURE_0); - m_world_view.set(*reinterpret_cast(worldView.pointer()), services); - m_texture.set(*reinterpret_cast(texture.pointer()), services); + m_world_view.set(worldView, services); + m_texture.set(texture, services); } } }; diff --git a/src/client/shader.h b/src/client/shader.h index fabb19922e8e..da4715545683 100644 --- a/src/client/shader.h +++ b/src/client/shader.h @@ -105,6 +105,57 @@ class CachedShaderSetting { has_been_set = true; } } + + /* Type specializations */ + + /* + * T2 looks redundant here but it is necessary so the compiler won't + * resolve the templates at class instantiation and then fail because + * some of these methods don't have valid types (= are not usable). + * ref: + * + * Note: a `bool dummy` template parameter would have been easier but MSVC + * does not like that. Also make sure not to define different specializations + * with the same parameters, MSVC doesn't like that either. + * I extend my thanks to Microsoft® + */ +#define SPECIALIZE(_type, _count_expr) \ + template \ + std::enable_if_t && std::is_same_v && (_count_expr)> + + SPECIALIZE(float, count == 2) + set(const v2f value, video::IMaterialRendererServices *services) + { + float array[2] = { value.X, value.Y }; + set(array, services); + } + + SPECIALIZE(float, count == 3) + set(const v3f value, video::IMaterialRendererServices *services) + { + float array[3] = { value.X, value.Y, value.Z }; + set(array, services); + } + + SPECIALIZE(float, count == 3 || count == 4) + set(const video::SColorf value, video::IMaterialRendererServices *services) + { + if constexpr (count == 3) { + float array[3] = { value.r, value.g, value.b }; + set(array, services); + } else { + float array[4] = { value.r, value.g, value.b, value.a }; + set(array, services); + } + } + + SPECIALIZE(float, count == 16) + set(const core::matrix4 &value, video::IMaterialRendererServices *services) + { + set(value.pointer(), services); + } + +#undef SPECIALIZE }; template diff --git a/src/client/shadows/shadowsshadercallbacks.cpp b/src/client/shadows/shadowsshadercallbacks.cpp index 4cfe0f081cc3..32d3e36bed55 100644 --- a/src/client/shadows/shadowsshadercallbacks.cpp +++ b/src/client/shadows/shadowsshadercallbacks.cpp @@ -32,9 +32,7 @@ void ShadowConstantSetter::onSetConstants(video::IMaterialRendererServices *serv shadowViewProj *= light.getViewMatrix(); m_shadow_view_proj.set(shadowViewProj.pointer(), services); - f32 v_LightDirection[3]; - light.getDirection().getAs3Values(v_LightDirection); - m_light_direction.set(v_LightDirection, services); + m_light_direction.set(light.getDirection(), services); f32 TextureResolution = light.getMapResolution(); m_texture_res.set(&TextureResolution, services); @@ -79,7 +77,7 @@ void ShadowDepthShaderCB::OnSetConstants( lightMVP *= driver->getTransform(video::ETS_WORLD); - m_light_mvp_setting.set(lightMVP.pointer(), services); + m_light_mvp_setting.set(lightMVP, services); m_map_resolution_setting.set(&MapRes, services); m_max_far_setting.set(&MaxFar, services); s32 TextureId = 0;