mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 08:03:45 +01:00
VBO-related optimizations and improvements (#14395)
This commit is contained in:
parent
d85c842ce9
commit
bb7f57b095
17
client/shaders/cloud_shader/opengl_fragment.glsl
Normal file
17
client/shaders/cloud_shader/opengl_fragment.glsl
Normal file
@ -0,0 +1,17 @@
|
||||
uniform vec4 fogColor;
|
||||
uniform float fogDistance;
|
||||
uniform float fogShadingParameter;
|
||||
varying vec3 eyeVec;
|
||||
|
||||
varying lowp vec4 varColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
vec4 col = varColor;
|
||||
|
||||
float clarity = clamp(fogShadingParameter
|
||||
- fogShadingParameter * length(eyeVec) / fogDistance, 0.0, 1.0);
|
||||
col.rgb = mix(fogColor.rgb, col.rgb, clarity);
|
||||
|
||||
gl_FragColor = col;
|
||||
}
|
21
client/shaders/cloud_shader/opengl_vertex.glsl
Normal file
21
client/shaders/cloud_shader/opengl_vertex.glsl
Normal file
@ -0,0 +1,21 @@
|
||||
uniform vec4 emissiveColor;
|
||||
|
||||
varying lowp vec4 varColor;
|
||||
|
||||
varying vec3 eyeVec;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_Position = mWorldViewProj * inVertexPosition;
|
||||
|
||||
#ifdef GL_ES
|
||||
vec4 color = inVertexColor.bgra;
|
||||
#else
|
||||
vec4 color = inVertexColor;
|
||||
#endif
|
||||
|
||||
color *= emissiveColor;
|
||||
varColor = color;
|
||||
|
||||
eyeVec = -(mWorldView * inVertexPosition).xyz;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
uniform vec4 starColor;
|
||||
uniform vec4 emissiveColor;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_FragColor = starColor;
|
||||
gl_FragColor = emissiveColor;
|
||||
}
|
||||
|
@ -39,53 +39,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
#include <algorithm>
|
||||
#include "client/renderingengine.h"
|
||||
|
||||
/*
|
||||
CAOShaderConstantSetter
|
||||
*/
|
||||
|
||||
//! Shader constant setter for passing material emissive color to the CAO object_shader
|
||||
class CAOShaderConstantSetter : public IShaderConstantSetter
|
||||
{
|
||||
public:
|
||||
~CAOShaderConstantSetter() override = default;
|
||||
|
||||
void onSetConstants(video::IMaterialRendererServices *services) override
|
||||
{
|
||||
// Ambient color
|
||||
video::SColorf emissive_color(m_emissive_color);
|
||||
|
||||
float as_array[4] = {
|
||||
emissive_color.r,
|
||||
emissive_color.g,
|
||||
emissive_color.b,
|
||||
emissive_color.a,
|
||||
};
|
||||
m_emissive_color_setting.set(as_array, services);
|
||||
}
|
||||
|
||||
void onSetMaterial(const video::SMaterial& material) override
|
||||
{
|
||||
m_emissive_color = material.EmissiveColor;
|
||||
}
|
||||
|
||||
private:
|
||||
video::SColor m_emissive_color;
|
||||
CachedPixelShaderSetting<float, 4>
|
||||
m_emissive_color_setting{"emissiveColor"};
|
||||
};
|
||||
|
||||
class CAOShaderConstantSetterFactory : public IShaderConstantSetterFactory
|
||||
{
|
||||
public:
|
||||
CAOShaderConstantSetterFactory()
|
||||
{}
|
||||
|
||||
virtual IShaderConstantSetter* create()
|
||||
{
|
||||
return new CAOShaderConstantSetter();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
ClientEnvironment
|
||||
*/
|
||||
@ -97,8 +50,6 @@ ClientEnvironment::ClientEnvironment(ClientMap *map,
|
||||
m_texturesource(texturesource),
|
||||
m_client(client)
|
||||
{
|
||||
auto *shdrsrc = m_client->getShaderSource();
|
||||
shdrsrc->addShaderConstantSetterFactory(new CAOShaderConstantSetterFactory());
|
||||
}
|
||||
|
||||
ClientEnvironment::~ClientEnvironment()
|
||||
|
@ -107,7 +107,7 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_rendering_engine->get_video_driver() == NULL) {
|
||||
if (!m_rendering_engine->get_video_driver()) {
|
||||
errorstream << "Could not initialize video driver." << std::endl;
|
||||
return false;
|
||||
}
|
||||
@ -125,51 +125,16 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
|
||||
setAttribute(scene::ALLOW_ZWRITE_ON_TRANSPARENT, true);
|
||||
|
||||
guienv = m_rendering_engine->get_gui_env();
|
||||
skin = guienv->getSkin();
|
||||
skin->setColor(gui::EGDC_WINDOW_SYMBOL, video::SColor(255, 255, 255, 255));
|
||||
skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255));
|
||||
skin->setColor(gui::EGDC_3D_LIGHT, video::SColor(0, 0, 0, 0));
|
||||
skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 30, 30, 30));
|
||||
skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255, 0, 0, 0));
|
||||
skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255, 70, 120, 50));
|
||||
skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255, 255, 255, 255));
|
||||
|
||||
float density = rangelim(g_settings->getFloat("gui_scaling"), 0.5, 20) *
|
||||
RenderingEngine::getDisplayDensity();
|
||||
skin->setSize(gui::EGDS_CHECK_BOX_WIDTH, (s32)(17.0f * density));
|
||||
skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(14.0f * density));
|
||||
skin->setSize(gui::EGDS_WINDOW_BUTTON_WIDTH, (s32)(15.0f * density));
|
||||
if (density > 1.5f) {
|
||||
std::string sprite_path = porting::path_share + "/textures/base/pack/";
|
||||
if (density > 3.5f)
|
||||
sprite_path.append("checkbox_64.png");
|
||||
else if (density > 2.0f)
|
||||
sprite_path.append("checkbox_32.png");
|
||||
else
|
||||
sprite_path.append("checkbox_16.png");
|
||||
// Texture dimensions should be a power of 2
|
||||
gui::IGUISpriteBank *sprites = skin->getSpriteBank();
|
||||
video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
|
||||
video::ITexture *sprite_texture = driver->getTexture(sprite_path.c_str());
|
||||
if (sprite_texture) {
|
||||
s32 sprite_id = sprites->addTextureAsSprite(sprite_texture);
|
||||
if (sprite_id != -1)
|
||||
skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, sprite_id);
|
||||
}
|
||||
}
|
||||
init_guienv(guienv);
|
||||
|
||||
g_fontengine = new FontEngine(guienv);
|
||||
FATAL_ERROR_IF(g_fontengine == NULL, "Font engine creation failed.");
|
||||
|
||||
// Irrlicht 1.8 input colours
|
||||
skin->setColor(gui::EGDC_EDITABLE, video::SColor(255, 128, 128, 128));
|
||||
skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255, 96, 134, 49));
|
||||
FATAL_ERROR_IF(!g_fontengine, "Font engine creation failed.");
|
||||
|
||||
// Create the menu clouds
|
||||
if (!g_menucloudsmgr)
|
||||
// This is only global so it can be used by RenderingEngine::draw_load_screen().
|
||||
assert(!g_menucloudsmgr && !g_menuclouds);
|
||||
g_menucloudsmgr = m_rendering_engine->get_scene_manager()->createNewSceneManager();
|
||||
if (!g_menuclouds)
|
||||
g_menuclouds = new Clouds(g_menucloudsmgr, -1, rand());
|
||||
g_menuclouds = new Clouds(g_menucloudsmgr, nullptr, -1, rand());
|
||||
g_menuclouds->setHeight(100.0f);
|
||||
g_menuclouds->update(v3f(0, 0, 0), video::SColor(255, 240, 240, 255));
|
||||
scene::ICameraSceneNode* camera;
|
||||
@ -223,7 +188,7 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
|
||||
guiroot = m_rendering_engine->get_gui_env()->addStaticText(L"",
|
||||
core::rect<s32>(0, 0, 10000, 10000));
|
||||
|
||||
bool game_has_run = launch_game(error_message, reconnect_requested,
|
||||
bool should_run_game = launch_game(error_message, reconnect_requested,
|
||||
start_data, cmd_args);
|
||||
|
||||
// Reset the reconnect_requested flag
|
||||
@ -232,13 +197,11 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
|
||||
// If skip_main_menu, we only want to startup once
|
||||
if (skip_main_menu && !first_loop)
|
||||
break;
|
||||
|
||||
first_loop = false;
|
||||
|
||||
if (!game_has_run) {
|
||||
if (!should_run_game) {
|
||||
if (skip_main_menu)
|
||||
break;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -246,9 +209,6 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
|
||||
if (!m_rendering_engine->run() || *kill)
|
||||
break;
|
||||
|
||||
m_rendering_engine->get_video_driver()->setTextureCreationFlag(
|
||||
video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
|
||||
|
||||
if (g_settings->getBool("enable_touch")) {
|
||||
receiver->m_touchscreengui = new TouchScreenGUI(m_rendering_engine->get_raw_device(), receiver);
|
||||
g_touchscreengui = receiver->m_touchscreengui;
|
||||
@ -301,17 +261,18 @@ bool ClientLauncher::run(GameStartData &start_data, const Settings &cmd_args)
|
||||
|
||||
// If no main menu, show error and exit
|
||||
if (skip_main_menu) {
|
||||
if (!error_message.empty()) {
|
||||
verbosestream << "error_message = "
|
||||
<< error_message << std::endl;
|
||||
if (!error_message.empty())
|
||||
retval = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} // Menu-game loop
|
||||
|
||||
assert(g_menuclouds->getReferenceCount() == 1);
|
||||
g_menuclouds->drop();
|
||||
g_menuclouds = nullptr;
|
||||
assert(g_menucloudsmgr->getReferenceCount() == 1);
|
||||
g_menucloudsmgr->drop();
|
||||
g_menucloudsmgr = nullptr;
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -373,6 +334,45 @@ void ClientLauncher::init_input()
|
||||
}
|
||||
}
|
||||
|
||||
void ClientLauncher::init_guienv(gui::IGUIEnvironment *guienv)
|
||||
{
|
||||
gui::IGUISkin *skin = guienv->getSkin();
|
||||
|
||||
skin->setColor(gui::EGDC_WINDOW_SYMBOL, video::SColor(255, 255, 255, 255));
|
||||
skin->setColor(gui::EGDC_BUTTON_TEXT, video::SColor(255, 255, 255, 255));
|
||||
skin->setColor(gui::EGDC_3D_LIGHT, video::SColor(0, 0, 0, 0));
|
||||
skin->setColor(gui::EGDC_3D_HIGH_LIGHT, video::SColor(255, 30, 30, 30));
|
||||
skin->setColor(gui::EGDC_3D_SHADOW, video::SColor(255, 0, 0, 0));
|
||||
skin->setColor(gui::EGDC_HIGH_LIGHT, video::SColor(255, 70, 120, 50));
|
||||
skin->setColor(gui::EGDC_HIGH_LIGHT_TEXT, video::SColor(255, 255, 255, 255));
|
||||
skin->setColor(gui::EGDC_EDITABLE, video::SColor(255, 128, 128, 128));
|
||||
skin->setColor(gui::EGDC_FOCUSED_EDITABLE, video::SColor(255, 96, 134, 49));
|
||||
|
||||
float density = rangelim(g_settings->getFloat("gui_scaling"), 0.5f, 20) *
|
||||
RenderingEngine::getDisplayDensity();
|
||||
skin->setSize(gui::EGDS_CHECK_BOX_WIDTH, (s32)(17.0f * density));
|
||||
skin->setSize(gui::EGDS_SCROLLBAR_SIZE, (s32)(14.0f * density));
|
||||
skin->setSize(gui::EGDS_WINDOW_BUTTON_WIDTH, (s32)(15.0f * density));
|
||||
if (density > 1.5f) {
|
||||
std::string sprite_path = porting::path_share + "/textures/base/pack/";
|
||||
if (density > 3.5f)
|
||||
sprite_path.append("checkbox_64.png");
|
||||
else if (density > 2.0f)
|
||||
sprite_path.append("checkbox_32.png");
|
||||
else
|
||||
sprite_path.append("checkbox_16.png");
|
||||
// Texture dimensions should be a power of 2
|
||||
gui::IGUISpriteBank *sprites = skin->getSpriteBank();
|
||||
video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
|
||||
video::ITexture *sprite_texture = driver->getTexture(sprite_path.c_str());
|
||||
if (sprite_texture) {
|
||||
s32 sprite_id = sprites->addTextureAsSprite(sprite_texture);
|
||||
if (sprite_id != -1)
|
||||
skin->setIcon(gui::EGDI_CHECK_BOX_CHECKED, sprite_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ClientLauncher::launch_game(std::string &error_message,
|
||||
bool reconnect_requested, GameStartData &start_data,
|
||||
const Settings &cmd_args)
|
||||
|
@ -38,6 +38,7 @@ private:
|
||||
void init_args(GameStartData &start_data, const Settings &cmd_args);
|
||||
bool init_engine();
|
||||
void init_input();
|
||||
void init_guienv(gui::IGUIEnvironment *guienv);
|
||||
|
||||
bool launch_game(std::string &error_message, bool reconnect_requested,
|
||||
GameStartData &start_data, const Settings &cmd_args);
|
||||
@ -49,5 +50,4 @@ private:
|
||||
RenderingEngine *m_rendering_engine = nullptr;
|
||||
InputHandler *input = nullptr;
|
||||
MyEventReceiver *receiver = nullptr;
|
||||
gui::IGUISkin *skin = nullptr;
|
||||
};
|
||||
|
@ -18,10 +18,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
*/
|
||||
|
||||
#include "client/renderingengine.h"
|
||||
#include "client/shader.h"
|
||||
#include "clouds.h"
|
||||
#include "noise.h"
|
||||
#include "constants.h"
|
||||
#include "debug.h"
|
||||
#include "irrlicht_changes/printing.h"
|
||||
#include "noise.h"
|
||||
#include "profiler.h"
|
||||
#include "settings.h"
|
||||
#include <cmath>
|
||||
@ -40,35 +42,38 @@ static void cloud_3d_setting_changed(const std::string &settingname, void *data)
|
||||
((Clouds *)data)->readSettings();
|
||||
}
|
||||
|
||||
Clouds::Clouds(scene::ISceneManager* mgr,
|
||||
Clouds::Clouds(scene::ISceneManager* mgr, IShaderSource *ssrc,
|
||||
s32 id,
|
||||
u32 seed
|
||||
):
|
||||
scene::ISceneNode(mgr->getRootSceneNode(), mgr, id),
|
||||
m_seed(seed)
|
||||
{
|
||||
m_enable_shaders = g_settings->getBool("enable_shaders");
|
||||
// menu clouds use shader-less clouds for simplicity (ssrc == NULL)
|
||||
m_enable_shaders = m_enable_shaders && ssrc;
|
||||
|
||||
m_material.Lighting = false;
|
||||
m_material.BackfaceCulling = true;
|
||||
m_material.FogEnable = true;
|
||||
m_material.AntiAliasing = video::EAAM_SIMPLE;
|
||||
if (m_enable_shaders) {
|
||||
auto sid = ssrc->getShader("cloud_shader", TILE_MATERIAL_ALPHA);
|
||||
m_material.MaterialType = ssrc->getShaderInfo(sid).material;
|
||||
} else {
|
||||
m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
m_material.forEachTexture([] (auto &tex) {
|
||||
tex.MinFilter = video::ETMINF_NEAREST_MIPMAP_NEAREST;
|
||||
tex.MagFilter = video::ETMAGF_NEAREST;
|
||||
});
|
||||
}
|
||||
|
||||
m_params.height = 120;
|
||||
m_params.density = 0.4f;
|
||||
m_params.thickness = 16.0f;
|
||||
m_params.color_bright = video::SColor(229, 240, 240, 255);
|
||||
m_params.color_ambient = video::SColor(255, 0, 0, 0);
|
||||
m_params.speed = v2f(0.0f, -2.0f);
|
||||
m_params = SkyboxDefaults::getCloudDefaults();
|
||||
|
||||
readSettings();
|
||||
g_settings->registerChangedCallback("enable_3d_clouds",
|
||||
&cloud_3d_setting_changed, this);
|
||||
|
||||
updateBox();
|
||||
|
||||
m_meshbuffer.reset(new scene::SMeshBuffer());
|
||||
m_meshbuffer->setHardwareMappingHint(scene::EHM_DYNAMIC);
|
||||
}
|
||||
|
||||
Clouds::~Clouds()
|
||||
@ -82,38 +87,14 @@ void Clouds::OnRegisterSceneNode()
|
||||
if(IsVisible)
|
||||
{
|
||||
SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
|
||||
//SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID);
|
||||
}
|
||||
|
||||
ISceneNode::OnRegisterSceneNode();
|
||||
}
|
||||
|
||||
void Clouds::render()
|
||||
void Clouds::updateMesh()
|
||||
{
|
||||
|
||||
if (m_params.density <= 0.0f)
|
||||
return; // no need to do anything
|
||||
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
|
||||
if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT)
|
||||
//if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SOLID)
|
||||
return;
|
||||
|
||||
ScopeProfiler sp(g_profiler, "Clouds::render()", SPT_AVG);
|
||||
|
||||
int num_faces_to_draw = m_enable_3d ? 6 : 1;
|
||||
|
||||
m_material.BackfaceCulling = m_enable_3d;
|
||||
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
driver->setMaterial(m_material);
|
||||
|
||||
/*
|
||||
Clouds move from Z+ towards Z-
|
||||
*/
|
||||
|
||||
const float cloud_full_radius = cloud_size * m_cloud_radius_i;
|
||||
// Clouds move from Z+ towards Z-
|
||||
|
||||
v2f camera_pos_2d(m_camera_pos.X, m_camera_pos.Z);
|
||||
// Position of cloud noise origin from the camera
|
||||
@ -126,56 +107,61 @@ void Clouds::render()
|
||||
std::floor(center_of_drawing_in_noise_f.Y / cloud_size)
|
||||
);
|
||||
|
||||
// Only update mesh if it has moved enough, this saves lots of GPU buffer uploads.
|
||||
constexpr float max_d = 5 * BS;
|
||||
|
||||
if (!m_mesh_valid) {
|
||||
// mesh was never created or invalidated
|
||||
} else if (m_mesh_origin.getDistanceFrom(m_origin) >= max_d) {
|
||||
// clouds moved
|
||||
} else if (center_of_drawing_in_noise_i != m_last_noise_center) {
|
||||
// noise offset changed
|
||||
// I think in practice this never happens due to the camera offset
|
||||
// being smaller than the cloud size.(?)
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
ScopeProfiler sp(g_profiler, "Clouds::updateMesh()", SPT_AVG);
|
||||
m_mesh_origin = m_origin;
|
||||
m_last_noise_center = center_of_drawing_in_noise_i;
|
||||
m_mesh_valid = true;
|
||||
|
||||
const u32 num_faces_to_draw = m_enable_3d ? 6 : 1;
|
||||
|
||||
// The world position of the integer center point of drawing in the noise
|
||||
v2f world_center_of_drawing_in_noise_f = v2f(
|
||||
center_of_drawing_in_noise_i.X * cloud_size,
|
||||
center_of_drawing_in_noise_i.Y * cloud_size
|
||||
) + m_origin;
|
||||
|
||||
/*video::SColor c_top(128,b*240,b*240,b*255);
|
||||
video::SColor c_side_1(128,b*230,b*230,b*255);
|
||||
video::SColor c_side_2(128,b*220,b*220,b*245);
|
||||
video::SColor c_bottom(128,b*205,b*205,b*230);*/
|
||||
// Colors with primitive shading
|
||||
|
||||
video::SColorf c_top_f(m_color);
|
||||
video::SColorf c_side_1_f(m_color);
|
||||
video::SColorf c_side_2_f(m_color);
|
||||
video::SColorf c_bottom_f(m_color);
|
||||
c_side_1_f.r *= 0.95;
|
||||
c_side_1_f.g *= 0.95;
|
||||
c_side_1_f.b *= 0.95;
|
||||
c_side_2_f.r *= 0.90;
|
||||
c_side_2_f.g *= 0.90;
|
||||
c_side_2_f.b *= 0.90;
|
||||
c_bottom_f.r *= 0.80;
|
||||
c_bottom_f.g *= 0.80;
|
||||
c_bottom_f.b *= 0.80;
|
||||
if (m_enable_shaders) {
|
||||
// shader mixes the base color, set via EmissiveColor
|
||||
c_top_f = c_side_1_f = c_side_2_f = c_bottom_f = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
c_side_1_f.r *= 0.95f;
|
||||
c_side_1_f.g *= 0.95f;
|
||||
c_side_1_f.b *= 0.95f;
|
||||
c_side_2_f.r *= 0.90f;
|
||||
c_side_2_f.g *= 0.90f;
|
||||
c_side_2_f.b *= 0.90f;
|
||||
c_bottom_f.r *= 0.80f;
|
||||
c_bottom_f.g *= 0.80f;
|
||||
c_bottom_f.b *= 0.80f;
|
||||
video::SColor c_top = c_top_f.toSColor();
|
||||
video::SColor c_side_1 = c_side_1_f.toSColor();
|
||||
video::SColor c_side_2 = c_side_2_f.toSColor();
|
||||
video::SColor c_bottom = c_bottom_f.toSColor();
|
||||
|
||||
// Get fog parameters for setting them back later
|
||||
video::SColor fog_color(0,0,0,0);
|
||||
video::E_FOG_TYPE fog_type = video::EFT_FOG_LINEAR;
|
||||
f32 fog_start = 0;
|
||||
f32 fog_end = 0;
|
||||
f32 fog_density = 0;
|
||||
bool fog_pixelfog = false;
|
||||
bool fog_rangefog = false;
|
||||
driver->getFog(fog_color, fog_type, fog_start, fog_end, fog_density,
|
||||
fog_pixelfog, fog_rangefog);
|
||||
|
||||
// Set our own fog, unless it was already disabled
|
||||
if (fog_start < FOG_RANGE_ALL) {
|
||||
driver->setFog(fog_color, fog_type, cloud_full_radius * 0.5,
|
||||
cloud_full_radius*1.2, fog_density, fog_pixelfog, fog_rangefog);
|
||||
}
|
||||
|
||||
// Read noise
|
||||
|
||||
std::vector<bool> grid(m_cloud_radius_i * 2 * m_cloud_radius_i * 2);
|
||||
std::vector<video::S3DVertex> vertices;
|
||||
vertices.reserve(16 * m_cloud_radius_i * m_cloud_radius_i);
|
||||
|
||||
for(s16 zi = -m_cloud_radius_i; zi < m_cloud_radius_i; zi++) {
|
||||
u32 si = (zi + m_cloud_radius_i) * m_cloud_radius_i * 2 + m_cloud_radius_i;
|
||||
@ -190,10 +176,23 @@ void Clouds::render()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
auto *mb = m_meshbuffer.get();
|
||||
{
|
||||
const u32 vertex_count = num_faces_to_draw * 16 * m_cloud_radius_i * m_cloud_radius_i;
|
||||
const u32 quad_count = vertex_count / 4;
|
||||
const u32 index_count = quad_count * 6;
|
||||
|
||||
// reserve memory
|
||||
mb->Vertices.reallocate(vertex_count);
|
||||
mb->Indices.reallocate(index_count);
|
||||
}
|
||||
|
||||
#define GETINDEX(x, z, radius) (((z)+(radius))*(radius)*2 + (x)+(radius))
|
||||
#define INAREA(x, z, radius) \
|
||||
((x) >= -(radius) && (x) < (radius) && (z) >= -(radius) && (z) < (radius))
|
||||
|
||||
mb->Vertices.set_used(0);
|
||||
for (s16 zi0= -m_cloud_radius_i; zi0 < m_cloud_radius_i; zi0++)
|
||||
for (s16 xi0= -m_cloud_radius_i; xi0 < m_cloud_radius_i; xi0++)
|
||||
{
|
||||
@ -224,7 +223,7 @@ void Clouds::render()
|
||||
const f32 ry = m_enable_3d ? m_params.thickness * BS : 0.0f;
|
||||
const f32 rz = cloud_size / 2;
|
||||
|
||||
for(int i=0; i<num_faces_to_draw; i++)
|
||||
for(u32 i = 0; i < num_faces_to_draw; i++)
|
||||
{
|
||||
switch(i)
|
||||
{
|
||||
@ -310,27 +309,87 @@ void Clouds::render()
|
||||
}
|
||||
|
||||
v3f pos(p0.X, m_params.height * BS, p0.Y);
|
||||
pos -= intToFloat(m_camera_offset, BS);
|
||||
|
||||
for (video::S3DVertex &vertex : v) {
|
||||
vertex.Pos += pos;
|
||||
vertices.push_back(vertex);
|
||||
mb->Vertices.push_back(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
int quad_count = vertices.size() / 4;
|
||||
std::vector<u16> indices;
|
||||
indices.reserve(quad_count * 6);
|
||||
for (int k = 0; k < quad_count; k++) {
|
||||
indices.push_back(4 * k + 0);
|
||||
indices.push_back(4 * k + 1);
|
||||
indices.push_back(4 * k + 2);
|
||||
indices.push_back(4 * k + 2);
|
||||
indices.push_back(4 * k + 3);
|
||||
indices.push_back(4 * k + 0);
|
||||
mb->setDirty(scene::EBT_VERTEX);
|
||||
|
||||
const u32 quad_count = mb->getVertexCount() / 4;
|
||||
const u32 index_count = quad_count * 6;
|
||||
// rewrite index array as needed
|
||||
if (mb->getIndexCount() > index_count) {
|
||||
mb->Indices.set_used(index_count);
|
||||
mb->setDirty(scene::EBT_INDEX);
|
||||
} else if (mb->getIndexCount() < index_count) {
|
||||
const u32 start = mb->getIndexCount() / 6;
|
||||
assert(start * 6 == mb->getIndexCount());
|
||||
for (u32 k = start; k < quad_count; k++) {
|
||||
mb->Indices.push_back(4 * k + 0);
|
||||
mb->Indices.push_back(4 * k + 1);
|
||||
mb->Indices.push_back(4 * k + 2);
|
||||
mb->Indices.push_back(4 * k + 2);
|
||||
mb->Indices.push_back(4 * k + 3);
|
||||
mb->Indices.push_back(4 * k + 0);
|
||||
}
|
||||
driver->drawVertexPrimitiveList(vertices.data(), vertices.size(), indices.data(), 2 * quad_count,
|
||||
video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
|
||||
mb->setDirty(scene::EBT_INDEX);
|
||||
}
|
||||
|
||||
tracestream << "Cloud::updateMesh(): " << mb->getVertexCount() << " vertices"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
void Clouds::render()
|
||||
{
|
||||
if (m_params.density <= 0.0f)
|
||||
return; // no need to do anything
|
||||
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
|
||||
if (SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT)
|
||||
return;
|
||||
|
||||
updateMesh();
|
||||
|
||||
// Update position
|
||||
{
|
||||
v2f off_origin = m_origin - m_mesh_origin;
|
||||
v3f rel(off_origin.X, 0, off_origin.Y);
|
||||
rel -= intToFloat(m_camera_offset, BS);
|
||||
setPosition(rel);
|
||||
updateAbsolutePosition();
|
||||
}
|
||||
|
||||
m_material.BackfaceCulling = m_enable_3d;
|
||||
if (m_enable_shaders)
|
||||
m_material.EmissiveColor = m_color.toSColor();
|
||||
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
driver->setMaterial(m_material);
|
||||
|
||||
const float cloud_full_radius = cloud_size * m_cloud_radius_i;
|
||||
|
||||
// Get fog parameters for setting them back later
|
||||
video::SColor fog_color(0,0,0,0);
|
||||
video::E_FOG_TYPE fog_type = video::EFT_FOG_LINEAR;
|
||||
f32 fog_start = 0;
|
||||
f32 fog_end = 0;
|
||||
f32 fog_density = 0;
|
||||
bool fog_pixelfog = false;
|
||||
bool fog_rangefog = false;
|
||||
driver->getFog(fog_color, fog_type, fog_start, fog_end, fog_density,
|
||||
fog_pixelfog, fog_rangefog);
|
||||
|
||||
// Set our own fog, unless it was already disabled
|
||||
if (fog_start < FOG_RANGE_ALL) {
|
||||
driver->setFog(fog_color, fog_type, cloud_full_radius * 0.5,
|
||||
cloud_full_radius*1.2, fog_density, fog_pixelfog, fog_rangefog);
|
||||
}
|
||||
|
||||
driver->drawMeshBuffer(m_meshbuffer.get());
|
||||
|
||||
// Restore fog settings
|
||||
driver->setFog(fog_color, fog_type, fog_start, fog_end, fog_density,
|
||||
@ -346,13 +405,13 @@ void Clouds::update(const v3f &camera_p, const video::SColorf &color_diffuse)
|
||||
{
|
||||
video::SColorf ambient(m_params.color_ambient);
|
||||
video::SColorf bright(m_params.color_bright);
|
||||
m_camera_pos = camera_p;
|
||||
m_color.r = core::clamp(color_diffuse.r * bright.r, ambient.r, 1.0f);
|
||||
m_color.g = core::clamp(color_diffuse.g * bright.g, ambient.g, 1.0f);
|
||||
m_color.b = core::clamp(color_diffuse.b * bright.b, ambient.b, 1.0f);
|
||||
m_color.a = bright.a;
|
||||
|
||||
// is the camera inside the cloud mesh?
|
||||
m_camera_pos = camera_p;
|
||||
m_camera_inside_cloud = false; // default
|
||||
if (m_enable_3d) {
|
||||
float camera_height = camera_p.Y - BS * m_camera_offset.Y;
|
||||
@ -369,9 +428,14 @@ void Clouds::update(const v3f &camera_p, const video::SColorf &color_diffuse)
|
||||
|
||||
void Clouds::readSettings()
|
||||
{
|
||||
// Upper limit was chosen due to posible render bugs
|
||||
m_cloud_radius_i = rangelim(g_settings->getU16("cloud_radius"), 1, 62);
|
||||
// The code isn't designed to go over 64k vertices so the upper limits were
|
||||
// chosen to avoid exactly that.
|
||||
// refer to vertex_count in updateMesh()
|
||||
m_enable_3d = g_settings->getBool("enable_3d_clouds");
|
||||
const u16 maximum = m_enable_3d ? 62 : 25;
|
||||
m_cloud_radius_i = rangelim(g_settings->getU16("cloud_radius"), 1, maximum);
|
||||
|
||||
invalidateMesh();
|
||||
}
|
||||
|
||||
bool Clouds::gridFilled(int x, int y) const
|
||||
|
@ -19,10 +19,13 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include <iostream>
|
||||
#include "constants.h"
|
||||
#include "irr_ptr.h"
|
||||
#include "irrlichttypes_extrabloated.h"
|
||||
#include "skyparams.h"
|
||||
#include <iostream>
|
||||
|
||||
class IShaderSource;
|
||||
|
||||
// Menu clouds
|
||||
class Clouds;
|
||||
@ -34,7 +37,7 @@ extern scene::ISceneManager *g_menucloudsmgr;
|
||||
class Clouds : public scene::ISceneNode
|
||||
{
|
||||
public:
|
||||
Clouds(scene::ISceneManager* mgr,
|
||||
Clouds(scene::ISceneManager* mgr, IShaderSource *ssrc,
|
||||
s32 id,
|
||||
u32 seed
|
||||
);
|
||||
@ -72,7 +75,7 @@ public:
|
||||
|
||||
void update(const v3f &camera_p, const video::SColorf &color);
|
||||
|
||||
void updateCameraOffset(const v3s16 &camera_offset)
|
||||
void updateCameraOffset(v3s16 camera_offset)
|
||||
{
|
||||
m_camera_offset = camera_offset;
|
||||
updateBox();
|
||||
@ -82,24 +85,29 @@ public:
|
||||
|
||||
void setDensity(float density)
|
||||
{
|
||||
if (m_params.density == density)
|
||||
return;
|
||||
m_params.density = density;
|
||||
// currently does not need bounding
|
||||
invalidateMesh();
|
||||
}
|
||||
|
||||
void setColorBright(const video::SColor &color_bright)
|
||||
void setColorBright(video::SColor color_bright)
|
||||
{
|
||||
m_params.color_bright = color_bright;
|
||||
}
|
||||
|
||||
void setColorAmbient(const video::SColor &color_ambient)
|
||||
void setColorAmbient(video::SColor color_ambient)
|
||||
{
|
||||
m_params.color_ambient = color_ambient;
|
||||
}
|
||||
|
||||
void setHeight(float height)
|
||||
{
|
||||
m_params.height = height; // add bounding when necessary
|
||||
if (m_params.height == height)
|
||||
return;
|
||||
m_params.height = height;
|
||||
updateBox();
|
||||
invalidateMesh();
|
||||
}
|
||||
|
||||
void setSpeed(v2f speed)
|
||||
@ -109,8 +117,11 @@ public:
|
||||
|
||||
void setThickness(float thickness)
|
||||
{
|
||||
if (m_params.thickness == thickness)
|
||||
return;
|
||||
m_params.thickness = thickness;
|
||||
updateBox();
|
||||
invalidateMesh();
|
||||
}
|
||||
|
||||
bool isCameraInsideCloud() const { return m_camera_inside_cloud; }
|
||||
@ -126,18 +137,33 @@ private:
|
||||
BS * 1000000.0f, height_bs + thickness_bs - BS * m_camera_offset.Y, BS * 1000000.0f);
|
||||
}
|
||||
|
||||
void updateMesh();
|
||||
void invalidateMesh()
|
||||
{
|
||||
m_mesh_valid = false;
|
||||
}
|
||||
|
||||
bool gridFilled(int x, int y) const;
|
||||
|
||||
video::SMaterial m_material;
|
||||
irr_ptr<scene::SMeshBuffer> m_meshbuffer;
|
||||
// Value of m_origin at the time the mesh was last updated
|
||||
v2f m_mesh_origin;
|
||||
// Value of center_of_drawing_in_noise_i at the time the mesh was last updated
|
||||
v2s16 m_last_noise_center;
|
||||
// Was the mesh ever generated?
|
||||
bool m_mesh_valid = false;
|
||||
|
||||
aabb3f m_box;
|
||||
v2f m_origin;
|
||||
u16 m_cloud_radius_i;
|
||||
bool m_enable_3d;
|
||||
u32 m_seed;
|
||||
v3f m_camera_pos;
|
||||
v2f m_origin;
|
||||
|
||||
v3s16 m_camera_offset;
|
||||
video::SColorf m_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
CloudParams m_params;
|
||||
bool m_camera_inside_cloud = false;
|
||||
|
||||
bool m_enable_shaders, m_enable_3d;
|
||||
video::SColorf m_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
CloudParams m_params;
|
||||
};
|
||||
|
@ -812,7 +812,6 @@ void GenericCAO::addToScene(ITextureSource *tsrc, scene::ISceneManager *smgr)
|
||||
(m_prop.visual == "wielditem"));
|
||||
|
||||
m_wield_meshnode->setScale(m_prop.visual_size / 2.0f);
|
||||
m_wield_meshnode->setColor(video::SColor(0xFFFFFFFF));
|
||||
} else {
|
||||
infostream<<"GenericCAO::addToScene(): \""<<m_prop.visual
|
||||
<<"\" not supported"<<std::endl;
|
||||
|
@ -379,7 +379,6 @@ class GameGlobalShaderConstantSetter : public IShaderConstantSetter
|
||||
CachedPixelShaderSetting<float>
|
||||
m_animation_timer_delta_pixel{"animationTimerDelta"};
|
||||
CachedPixelShaderSetting<float, 3> m_day_light{"dayLight"};
|
||||
CachedPixelShaderSetting<float, 4> m_star_color{"starColor"};
|
||||
CachedPixelShaderSetting<float, 3> m_eye_position_pixel{"eyePosition"};
|
||||
CachedVertexShaderSetting<float, 3> m_eye_position_vertex{"eyePosition"};
|
||||
CachedPixelShaderSetting<float, 3> m_minimap_yaw{"yawVec"};
|
||||
@ -473,10 +472,6 @@ public:
|
||||
get_sunlight_color(&sunlight, daynight_ratio);
|
||||
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};
|
||||
m_star_color.set(clr, services);
|
||||
|
||||
u32 animation_timer = m_client->getEnv().getFrameTime() % 1000000;
|
||||
float animation_timer_f = (float)animation_timer / 100000.f;
|
||||
m_animation_timer_vertex.set(&animation_timer_f, services);
|
||||
@ -529,7 +524,9 @@ public:
|
||||
m_bloom_radius_pixel.set(&m_bloom_radius, services);
|
||||
m_bloom_strength_pixel.set(&m_bloom_strength, services);
|
||||
}
|
||||
float saturation = m_client->getEnv().getLocalPlayer()->getLighting().saturation;
|
||||
|
||||
const auto &lighting = m_client->getEnv().getLocalPlayer()->getLighting();
|
||||
float saturation = lighting.saturation;
|
||||
m_saturation_pixel.set(&saturation, services);
|
||||
|
||||
if (m_volumetric_light_enabled) {
|
||||
@ -540,13 +537,13 @@ public:
|
||||
|
||||
if (m_sky->getSunVisible()) {
|
||||
v3f sun_position = camera_node->getAbsolutePosition() +
|
||||
10000. * m_sky->getSunDirection();
|
||||
10000.f * m_sky->getSunDirection();
|
||||
transform.transformVect(sun_position);
|
||||
sun_position.normalize();
|
||||
|
||||
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);
|
||||
float sun_brightness = core::clamp(107.143f * m_sky->getSunDirection().Y, 0.f, 1.f);
|
||||
m_sun_brightness_pixel.set(&sun_brightness, services);
|
||||
} else {
|
||||
m_sun_position_pixel.set(v3f(0.f, 0.f, -1.f), services);
|
||||
@ -557,13 +554,13 @@ public:
|
||||
|
||||
if (m_sky->getMoonVisible()) {
|
||||
v3f moon_position = camera_node->getAbsolutePosition() +
|
||||
10000. * m_sky->getMoonDirection();
|
||||
10000.f * m_sky->getMoonDirection();
|
||||
transform.transformVect(moon_position);
|
||||
moon_position.normalize();
|
||||
|
||||
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);
|
||||
float moon_brightness = core::clamp(107.143f * m_sky->getMoonDirection().Y, 0.f, 1.f);
|
||||
m_moon_brightness_pixel.set(&moon_brightness, services);
|
||||
} else {
|
||||
m_moon_position_pixel.set(v3f(0.f, 0.f, -1.f), services);
|
||||
@ -571,7 +568,8 @@ public:
|
||||
float moon_brightness = 0.f;
|
||||
m_moon_brightness_pixel.set(&moon_brightness, services);
|
||||
}
|
||||
float volumetric_light_strength = m_client->getEnv().getLocalPlayer()->getLighting().volumetric_light_strength;
|
||||
|
||||
float volumetric_light_strength = lighting.volumetric_light_strength;
|
||||
m_volumetric_light_strength_pixel.set(&volumetric_light_strength, services);
|
||||
}
|
||||
}
|
||||
@ -1099,6 +1097,8 @@ bool Game::startup(bool *kill,
|
||||
driver = device->getVideoDriver();
|
||||
smgr = m_rendering_engine->get_scene_manager();
|
||||
|
||||
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, g_settings->getBool("mip_map"));
|
||||
|
||||
smgr->getParameters()->setAttribute(scene::OBJ_LOADER_IGNORE_MATERIAL_FILES, true);
|
||||
|
||||
// Reinit runData
|
||||
@ -1454,7 +1454,7 @@ bool Game::createClient(const GameStartData &start_data)
|
||||
/* Clouds
|
||||
*/
|
||||
if (m_cache_enable_clouds)
|
||||
clouds = new Clouds(smgr, -1, time(0));
|
||||
clouds = new Clouds(smgr, shader_src, -1, rand());
|
||||
|
||||
/* Skybox
|
||||
*/
|
||||
|
@ -97,7 +97,7 @@ Hud::Hud(Client *client, LocalPlayer *player,
|
||||
|
||||
if (g_settings->getBool("enable_shaders")) {
|
||||
IShaderSource *shdrsrc = client->getShaderSource();
|
||||
u16 shader_id = shdrsrc->getShader(
|
||||
auto shader_id = shdrsrc->getShader(
|
||||
m_mode == HIGHLIGHT_HALO ? "selection_shader" : "default_shader", TILE_MATERIAL_ALPHA);
|
||||
m_selection_material.MaterialType = shdrsrc->getShaderInfo(shader_id).material;
|
||||
} else {
|
||||
@ -1100,24 +1100,23 @@ void drawItemStack(
|
||||
video::SColor basecolor =
|
||||
client->idef()->getItemstackColor(item, client);
|
||||
|
||||
u32 mc = mesh->getMeshBufferCount();
|
||||
const u32 mc = mesh->getMeshBufferCount();
|
||||
if (mc > imesh->buffer_colors.size())
|
||||
imesh->buffer_colors.resize(mc);
|
||||
for (u32 j = 0; j < mc; ++j) {
|
||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||
// we can modify vertices relatively fast,
|
||||
// because these meshes are not buffered.
|
||||
assert(buf->getHardwareMappingHint_Vertex() == scene::EHM_NEVER);
|
||||
video::SColor c = basecolor;
|
||||
|
||||
if (imesh->buffer_colors.size() > j) {
|
||||
ItemPartColor *p = &imesh->buffer_colors[j];
|
||||
if (p->override_base)
|
||||
c = p->color;
|
||||
}
|
||||
auto &p = imesh->buffer_colors[j];
|
||||
p.applyOverride(c);
|
||||
|
||||
if (p.needColorize(c)) {
|
||||
buf->setDirty(scene::EBT_VERTEX);
|
||||
if (imesh->needs_shading)
|
||||
colorizeMeshBuffer(buf, &c);
|
||||
else
|
||||
setMeshBufferColor(buf, c);
|
||||
}
|
||||
|
||||
video::SMaterial &material = buf->getMaterial();
|
||||
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF;
|
||||
|
@ -615,7 +615,7 @@ void Minimap::drawMinimap(core::rect<s32> rect)
|
||||
material.TextureLayers[1].Texture = data->heightmap_texture;
|
||||
|
||||
if (m_enable_shaders && data->mode.type == MINIMAP_TYPE_SURFACE) {
|
||||
u16 sid = m_shdrsrc->getShader("minimap_shader", TILE_MATERIAL_ALPHA);
|
||||
auto sid = m_shdrsrc->getShader("minimap_shader", TILE_MATERIAL_ALPHA);
|
||||
material.MaterialType = m_shdrsrc->getShaderInfo(sid).material;
|
||||
} else {
|
||||
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
|
@ -94,7 +94,7 @@ class FogShaderConstantSetter : public IShaderConstantSetter
|
||||
public:
|
||||
void onSetConstants(video::IMaterialRendererServices *services) override
|
||||
{
|
||||
auto *driver = RenderingEngine::get_video_driver();
|
||||
auto *driver = services->getVideoDriver();
|
||||
assert(driver);
|
||||
|
||||
video::SColor fog_color(0);
|
||||
@ -314,15 +314,17 @@ void RenderingEngine::draw_load_screen(const std::wstring &text,
|
||||
gui::StaticText::add(guienv, text, textrect, false, false);
|
||||
guitext->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_UPPERLEFT);
|
||||
|
||||
if (sky && g_settings->getBool("menu_clouds")) {
|
||||
auto *driver = get_video_driver();
|
||||
|
||||
if (sky) {
|
||||
driver->beginScene(true, true, RenderingEngine::MENU_SKY_COLOR);
|
||||
if (g_settings->getBool("menu_clouds")) {
|
||||
g_menuclouds->step(dtime * 3);
|
||||
g_menuclouds->render();
|
||||
get_video_driver()->beginScene(true, true, RenderingEngine::MENU_SKY_COLOR);
|
||||
g_menucloudsmgr->drawAll();
|
||||
} else if (sky)
|
||||
get_video_driver()->beginScene(true, true, RenderingEngine::MENU_SKY_COLOR);
|
||||
else
|
||||
get_video_driver()->beginScene(true, true, video::SColor(255, 0, 0, 0));
|
||||
}
|
||||
} else {
|
||||
driver->beginScene(true, true, video::SColor(255, 0, 0, 0));
|
||||
}
|
||||
|
||||
// draw progress bar
|
||||
if ((percent >= 0) && (percent <= 100)) {
|
||||
@ -367,7 +369,7 @@ void RenderingEngine::draw_load_screen(const std::wstring &text,
|
||||
}
|
||||
|
||||
guienv->drawAll();
|
||||
get_video_driver()->endScene();
|
||||
driver->endScene();
|
||||
guitext->remove();
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,6 @@ public:
|
||||
|
||||
bool setupTopLevelWindow();
|
||||
bool setWindowIcon();
|
||||
static bool print_video_modes();
|
||||
void cleanupMeshCache();
|
||||
|
||||
void removeMesh(const scene::IMesh* mesh);
|
||||
|
@ -217,13 +217,22 @@ class MainShaderConstantSetter : public IShaderConstantSetter
|
||||
// Texture matrix
|
||||
CachedVertexShaderSetting<float, 16> m_texture{"mTexture"};
|
||||
|
||||
// commonly used way to pass material color to shader
|
||||
video::SColor m_emissive_color;
|
||||
CachedPixelShaderSetting<float, 4> m_emissive_color_setting{"emissiveColor"};
|
||||
|
||||
public:
|
||||
~MainShaderConstantSetter() = default;
|
||||
|
||||
virtual void onSetMaterial(const video::SMaterial& material) override
|
||||
{
|
||||
m_emissive_color = material.EmissiveColor;
|
||||
}
|
||||
|
||||
virtual void onSetConstants(video::IMaterialRendererServices *services) override
|
||||
{
|
||||
video::IVideoDriver *driver = services->getVideoDriver();
|
||||
sanity_check(driver);
|
||||
assert(driver);
|
||||
|
||||
// Set world matrix
|
||||
core::matrix4 world = driver->getTransform(video::ETS_WORLD);
|
||||
@ -244,6 +253,9 @@ public:
|
||||
m_world_view.set(worldView, services);
|
||||
m_texture.set(texture, services);
|
||||
}
|
||||
|
||||
video::SColorf emissive_color(m_emissive_color);
|
||||
m_emissive_color_setting.set(emissive_color, services);
|
||||
}
|
||||
};
|
||||
|
||||
@ -545,11 +557,11 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
|
||||
return shaderinfo;
|
||||
|
||||
video::IVideoDriver *driver = RenderingEngine::get_video_driver();
|
||||
if (!driver->queryFeature(video::EVDF_ARB_GLSL)) {
|
||||
video::IGPUProgrammingServices *gpu = driver->getGPUProgrammingServices();
|
||||
if (!driver->queryFeature(video::EVDF_ARB_GLSL) || !gpu) {
|
||||
throw ShaderException(gettext("Shaders are enabled but GLSL is not "
|
||||
"supported by the driver."));
|
||||
}
|
||||
video::IGPUProgrammingServices *gpu = driver->getGPUProgrammingServices();
|
||||
|
||||
// Create shaders header
|
||||
bool fully_programmable = driver->getDriverType() == video::EDT_OGLES2 || driver->getDriverType() == video::EDT_OPENGL3;
|
||||
@ -610,14 +622,6 @@ ShaderInfo ShaderSource::generateShader(const std::string &name,
|
||||
#define textureFlags texture2
|
||||
)";
|
||||
|
||||
// Since this is the first time we're using the GL bindings be extra careful.
|
||||
// This should be removed before 5.6.0 or similar.
|
||||
if (!GL.GetString) {
|
||||
errorstream << "OpenGL procedures were not loaded correctly, "
|
||||
"please open a bug report with details about your platform/OS." << std::endl;
|
||||
abort();
|
||||
}
|
||||
|
||||
bool use_discard = fully_programmable;
|
||||
// For renderers that should use discard instead of GL_ALPHA_TEST
|
||||
const char *renderer = reinterpret_cast<const char*>(GL.GetString(GL.RENDERER));
|
||||
|
@ -77,6 +77,7 @@ Sky::Sky(s32 id, RenderingEngine *rendering_engine, ITextureSource *tsrc, IShade
|
||||
// Create materials
|
||||
|
||||
m_materials[0] = baseMaterial();
|
||||
// FIXME: shouldn't this check m_enable_shaders?
|
||||
m_materials[0].MaterialType = ssrc->getShaderInfo(ssrc->getShader("stars_shader", TILE_MATERIAL_ALPHA)).material;
|
||||
m_materials[0].Lighting = true;
|
||||
m_materials[0].ColorMaterial = video::ECM_NONE;
|
||||
@ -683,11 +684,12 @@ void Sky::draw_stars(video::IVideoDriver * driver, float wicked_time_of_day)
|
||||
float starbrightness = (0.25f - std::abs(tod)) * 20.0f;
|
||||
float alpha = clamp(starbrightness, day_opacity, 1.0f);
|
||||
|
||||
m_star_color = m_star_params.starcolor;
|
||||
m_star_color.a *= alpha;
|
||||
if (m_star_color.a <= 0.0f) // Stars are only drawn when not fully transparent
|
||||
video::SColorf color(m_star_params.starcolor);
|
||||
color.a *= alpha;
|
||||
if (color.a <= 0.0f) // Stars are only drawn when not fully transparent
|
||||
return;
|
||||
m_materials[0].DiffuseColor = m_materials[0].EmissiveColor = m_star_color.toSColor();
|
||||
m_materials[0].EmissiveColor = color.toSColor();
|
||||
|
||||
auto sky_rotation = core::matrix4().setRotationAxisRadians(2.0f * M_PI * (wicked_time_of_day - 0.25f), v3f(0.0f, 0.0f, 1.0f));
|
||||
auto world_matrix = driver->getTransform(video::ETS_WORLD);
|
||||
driver->setTransform(video::ETS_WORLD, world_matrix * sky_rotation);
|
||||
|
@ -114,7 +114,6 @@ public:
|
||||
void clearSkyboxTextures() { m_sky_params.textures.clear(); }
|
||||
void addTextureToSkybox(const std::string &texture, int material_id,
|
||||
ITextureSource *tsrc);
|
||||
const video::SColorf &getCurrentStarColor() const { return m_star_color; }
|
||||
|
||||
// Note: the Sky class doesn't use these values. It just stores them.
|
||||
void setFogDistance(s16 fog_distance) { m_sky_params.fog_distance = fog_distance; }
|
||||
@ -210,7 +209,6 @@ private:
|
||||
|
||||
u64 m_seed = 0;
|
||||
irr_ptr<scene::SMeshBuffer> m_stars;
|
||||
video::SColorf m_star_color;
|
||||
|
||||
video::ITexture *m_sun_texture;
|
||||
video::ITexture *m_moon_texture;
|
||||
|
@ -508,22 +508,27 @@ void WieldMeshSceneNode::setColor(video::SColor c)
|
||||
u8 red = c.getRed();
|
||||
u8 green = c.getGreen();
|
||||
u8 blue = c.getBlue();
|
||||
u32 mc = mesh->getMeshBufferCount();
|
||||
|
||||
const u32 mc = mesh->getMeshBufferCount();
|
||||
if (mc > m_colors.size())
|
||||
m_colors.resize(mc);
|
||||
for (u32 j = 0; j < mc; j++) {
|
||||
video::SColor bc(m_base_color);
|
||||
if ((m_colors.size() > j) && (m_colors[j].override_base))
|
||||
bc = m_colors[j].color;
|
||||
m_colors[j].applyOverride(bc);
|
||||
video::SColor buffercolor(255,
|
||||
bc.getRed() * red / 255,
|
||||
bc.getGreen() * green / 255,
|
||||
bc.getBlue() * blue / 255);
|
||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(j);
|
||||
|
||||
if (m_colors[j].needColorize(buffercolor)) {
|
||||
buf->setDirty(scene::EBT_VERTEX);
|
||||
if (m_enable_shaders)
|
||||
setMeshBufferColor(buf, buffercolor);
|
||||
else
|
||||
colorizeMeshBuffer(buf, &buffercolor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WieldMeshSceneNode::setNodeLightColor(video::SColor color)
|
||||
@ -536,8 +541,7 @@ void WieldMeshSceneNode::setNodeLightColor(video::SColor color)
|
||||
video::SMaterial &material = m_meshnode->getMaterial(i);
|
||||
material.EmissiveColor = color;
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
setColor(color);
|
||||
}
|
||||
}
|
||||
@ -557,6 +561,12 @@ void WieldMeshSceneNode::changeToMesh(scene::IMesh *mesh)
|
||||
dummymesh->drop(); // m_meshnode grabbed it
|
||||
} else {
|
||||
m_meshnode->setMesh(mesh);
|
||||
// without shaders recolored often for lighting
|
||||
// otherwise only once
|
||||
if (m_enable_shaders)
|
||||
mesh->setHardwareMappingHint(scene::EHM_STATIC);
|
||||
else
|
||||
mesh->setHardwareMappingHint(scene::EHM_DYNAMIC);
|
||||
}
|
||||
|
||||
m_meshnode->forEachMaterial([this] (auto &mat) {
|
||||
@ -651,8 +661,7 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
|
||||
}
|
||||
}
|
||||
|
||||
u32 mc = mesh->getMeshBufferCount();
|
||||
for (u32 i = 0; i < mc; ++i) {
|
||||
for (u32 i = 0; i < mesh->getMeshBufferCount(); ++i) {
|
||||
scene::IMeshBuffer *buf = mesh->getMeshBuffer(i);
|
||||
video::SMaterial &material = buf->getMaterial();
|
||||
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
@ -668,6 +677,12 @@ void getItemMesh(Client *client, const ItemStack &item, ItemMesh *result)
|
||||
rotateMeshXZby(mesh, -45);
|
||||
rotateMeshYZby(mesh, -30);
|
||||
}
|
||||
|
||||
// might need to be re-colorized, this is done only when needed
|
||||
if (mesh) {
|
||||
mesh->setHardwareMappingHint(scene::EHM_DYNAMIC, scene::EBT_VERTEX);
|
||||
mesh->setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_INDEX);
|
||||
}
|
||||
result->mesh = mesh;
|
||||
}
|
||||
|
||||
@ -722,11 +737,10 @@ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
|
||||
bool use_shaders, bool set_material, const video::E_MATERIAL_TYPE *mattype,
|
||||
std::vector<ItemPartColor> *colors, bool apply_scale)
|
||||
{
|
||||
u32 mc = mesh->getMeshBufferCount();
|
||||
const u32 mc = mesh->getMeshBufferCount();
|
||||
// Allocate colors for existing buffers
|
||||
colors->clear();
|
||||
for (u32 i = 0; i < mc; ++i)
|
||||
colors->push_back(ItemPartColor());
|
||||
colors->resize(mc);
|
||||
|
||||
for (u32 i = 0; i < mc; ++i) {
|
||||
const TileSpec *tile = &(f.tiles[i]);
|
||||
@ -741,11 +755,11 @@ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
|
||||
mesh->addMeshBuffer(copy);
|
||||
copy->drop();
|
||||
buf = copy;
|
||||
colors->push_back(
|
||||
ItemPartColor(layer->has_color, layer->color));
|
||||
colors->emplace_back(layer->has_color, layer->color);
|
||||
} else {
|
||||
(*colors)[i] = ItemPartColor(layer->has_color, layer->color);
|
||||
}
|
||||
|
||||
video::SMaterial &material = buf->getMaterial();
|
||||
if (set_material)
|
||||
layer->applyMaterialOptions(material);
|
||||
@ -768,6 +782,7 @@ void postProcessNodeMesh(scene::SMesh *mesh, const ContentFeatures &f,
|
||||
}
|
||||
material.setTexture(2, layer->flags_texture);
|
||||
}
|
||||
|
||||
if (apply_scale && tile->world_aligned) {
|
||||
u32 n = buf->getVertexCount();
|
||||
for (u32 k = 0; k != n; ++k)
|
||||
|
@ -29,38 +29,54 @@ class ITextureSource;
|
||||
struct ContentFeatures;
|
||||
class ShadowRenderer;
|
||||
|
||||
/*!
|
||||
/*
|
||||
* Holds color information of an item mesh's buffer.
|
||||
*/
|
||||
struct ItemPartColor
|
||||
class ItemPartColor
|
||||
{
|
||||
/*!
|
||||
* If this is false, the global base color of the item
|
||||
* will be used instead of the specific color of the
|
||||
* buffer.
|
||||
/*
|
||||
* Optional color that overrides the global base color.
|
||||
*/
|
||||
bool override_base = false;
|
||||
/*!
|
||||
* The color of the buffer.
|
||||
video::SColor override_color;
|
||||
/*
|
||||
* Stores the last color this mesh buffer was colorized as.
|
||||
*/
|
||||
video::SColor color = 0;
|
||||
video::SColor last_colorized;
|
||||
|
||||
// saves some bytes compared to two std::optionals
|
||||
bool override_color_set = false;
|
||||
bool last_colorized_set = false;
|
||||
|
||||
public:
|
||||
|
||||
ItemPartColor() = default;
|
||||
|
||||
ItemPartColor(bool override, video::SColor color) :
|
||||
override_base(override), color(color)
|
||||
{
|
||||
override_color(color), override_color_set(override)
|
||||
{}
|
||||
|
||||
void applyOverride(video::SColor &dest) const {
|
||||
if (override_color_set)
|
||||
dest = override_color;
|
||||
}
|
||||
|
||||
bool needColorize(video::SColor target) {
|
||||
if (last_colorized_set && target == last_colorized)
|
||||
return false;
|
||||
last_colorized_set = true;
|
||||
last_colorized = target;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct ItemMesh
|
||||
{
|
||||
scene::IMesh *mesh = nullptr;
|
||||
/*!
|
||||
/*
|
||||
* Stores the color of each mesh buffer.
|
||||
*/
|
||||
std::vector<ItemPartColor> buffer_colors;
|
||||
/*!
|
||||
/*
|
||||
* If false, all faces of the item should have the same brightness.
|
||||
* Disables shading based on normal vectors.
|
||||
*/
|
||||
|
@ -19,25 +19,26 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
|
||||
#include "guiEngine.h"
|
||||
|
||||
#include <IGUIStaticText.h>
|
||||
#include <ICameraSceneNode.h>
|
||||
#include "client/renderingengine.h"
|
||||
#include "scripting_mainmenu.h"
|
||||
#include "config.h"
|
||||
#include "version.h"
|
||||
#include "porting.h"
|
||||
#include "filesys.h"
|
||||
#include "settings.h"
|
||||
#include "guiMainMenu.h"
|
||||
#include "sound.h"
|
||||
#include "httpfetch.h"
|
||||
#include "log.h"
|
||||
#include "client/fontengine.h"
|
||||
#include "client/guiscalingfilter.h"
|
||||
#include "irrlicht_changes/static_text.h"
|
||||
#include "client/renderingengine.h"
|
||||
#include "client/shader.h"
|
||||
#include "client/tile.h"
|
||||
#include "config.h"
|
||||
#include "content/content.h"
|
||||
#include "content/mods.h"
|
||||
#include "filesys.h"
|
||||
#include "guiMainMenu.h"
|
||||
#include "httpfetch.h"
|
||||
#include "irrlicht_changes/static_text.h"
|
||||
#include "log.h"
|
||||
#include "porting.h"
|
||||
#include "scripting_mainmenu.h"
|
||||
#include "settings.h"
|
||||
#include "sound.h"
|
||||
#include "version.h"
|
||||
#include <ICameraSceneNode.h>
|
||||
#include <IGUIStaticText.h>
|
||||
|
||||
#if USE_SOUND
|
||||
#include "client/sound/sound_openal.h"
|
||||
@ -139,6 +140,10 @@ GUIEngine::GUIEngine(JoystickController *joystick,
|
||||
// create texture source
|
||||
m_texture_source = std::make_unique<MenuTextureSource>(rendering_engine->get_video_driver());
|
||||
|
||||
// create shader source
|
||||
// (currently only used by clouds)
|
||||
m_shader_source.reset(createShaderSource());
|
||||
|
||||
// create soundmanager
|
||||
#if USE_SOUND
|
||||
if (g_settings->getBool("enable_sound") && g_sound_manager_singleton.get()) {
|
||||
@ -285,10 +290,10 @@ bool GUIEngine::loadMainMenuScript()
|
||||
void GUIEngine::run()
|
||||
{
|
||||
IrrlichtDevice *device = m_rendering_engine->get_raw_device();
|
||||
video::IVideoDriver *driver = device->getVideoDriver();
|
||||
|
||||
// Always create clouds because they may or may not be
|
||||
// needed based on the game selected
|
||||
video::IVideoDriver *driver = m_rendering_engine->get_video_driver();
|
||||
|
||||
cloudInit();
|
||||
|
||||
unsigned int text_height = g_fontengine->getTextHeight();
|
||||
@ -375,23 +380,24 @@ GUIEngine::~GUIEngine()
|
||||
|
||||
m_sound_manager.reset();
|
||||
|
||||
m_irr_toplefttext->setText(L"");
|
||||
m_irr_toplefttext->remove();
|
||||
|
||||
//clean up texture pointers
|
||||
m_cloud.clouds.reset();
|
||||
|
||||
// delete textures
|
||||
for (image_definition &texture : m_textures) {
|
||||
if (texture.texture)
|
||||
m_rendering_engine->get_video_driver()->removeTexture(texture.texture);
|
||||
}
|
||||
|
||||
m_texture_source.reset();
|
||||
|
||||
m_cloud.clouds.reset();
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
void GUIEngine::cloudInit()
|
||||
{
|
||||
m_cloud.clouds = make_irr<Clouds>(m_smgr, -1, rand());
|
||||
m_shader_source->addShaderConstantSetterFactory(
|
||||
new FogShaderConstantSetterFactory());
|
||||
|
||||
m_cloud.clouds = make_irr<Clouds>(m_smgr, m_shader_source.get(), -1, rand());
|
||||
m_cloud.clouds->setHeight(100.0f);
|
||||
m_cloud.clouds->update(v3f(0, 0, 0), video::SColor(255,240,240,255));
|
||||
|
||||
@ -404,7 +410,6 @@ void GUIEngine::cloudInit()
|
||||
void GUIEngine::drawClouds(float dtime)
|
||||
{
|
||||
m_cloud.clouds->step(dtime*3);
|
||||
m_cloud.clouds->render();
|
||||
m_smgr->drawAll();
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,7 @@ struct image_definition {
|
||||
class GUIEngine;
|
||||
class RenderingEngine;
|
||||
class MainMenuScripting;
|
||||
class IWritableShaderSource;
|
||||
struct MainMenuData;
|
||||
|
||||
/******************************************************************************/
|
||||
@ -203,7 +204,9 @@ private:
|
||||
MainMenuData *m_data = nullptr;
|
||||
/** texture source */
|
||||
std::unique_ptr<ISimpleTextureSource> m_texture_source;
|
||||
/** sound manager*/
|
||||
/** shader source */
|
||||
std::unique_ptr<IWritableShaderSource> m_shader_source;
|
||||
/** sound manager */
|
||||
std::unique_ptr<ISoundManager> m_sound_manager;
|
||||
|
||||
/** representation of form source to be used in mainmenu formspec */
|
||||
|
@ -466,10 +466,6 @@ public:
|
||||
if (!inventory_image.empty())
|
||||
cc->inventory_texture = tsrc->getTexture(inventory_image);
|
||||
getItemMesh(client, item, &(cc->wield_mesh));
|
||||
// note: vertices are modified frequently (see hud.cpp) so only indices
|
||||
// can be mapped
|
||||
if (auto mesh = cc->wield_mesh.mesh)
|
||||
mesh->setHardwareMappingHint(scene::EHM_STATIC, scene::EBT_INDEX);
|
||||
|
||||
cc->palette = tsrc->getPalette(def.palette_image);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user