),
m_con(PROTOCOL_ID, 512, CONNECTION_TIMEOUT, this),
m_device(device),
- camera_position(0,0,0),
- camera_direction(0,0,1),
m_server_ser_ver(SER_FMT_VER_INVALID),
m_inventory_updated(false),
m_time_of_day(0),
void Client::updateCamera(v3f pos, v3f dir)
{
m_env.getClientMap().updateCamera(pos, dir);
- camera_position = pos;
- camera_direction = dir;
+}
+
+void Client::renderPostFx()
+{
+ m_env.getClientMap().renderPostFx();
}
MapNode Client::getNode(v3s16 p)
return m_env.getMap().getNodeMetadata(p);
}
+LocalPlayer* Client::getLocalPlayer()
+{
+ return m_env.getLocalPlayer();
+}
+
v3f Client::getPlayerPosition(v3f *eye_position)
{
//JMutexAutoLock envlock(m_env_mutex); //bulk comment-out
void updateCamera(v3f pos, v3f dir);
+ void renderPostFx();
+
// Returns InvalidPositionException if not found
MapNode getNode(v3s16 p);
// Wrapper to Map
NodeMetadata* getNodeMetadata(v3s16 p);
- // Get the player position, and optionally put the
- // eye position in *eye_position
- v3f getPlayerPosition(v3f *eye_position=NULL);
+ LocalPlayer* getLocalPlayer();
+
+ v3f getPlayerPosition(v3f *eye_position);
void setPlayerControl(PlayerControl &control);
{
return m_access_denied_reason;
}
-
- /*
- This should only be used for calling the special drawing stuff in
- ClientEnvironment
- */
- ClientEnvironment * getEnv()
- {
- return &m_env;
- }
private:
IrrlichtDevice *m_device;
- v3f camera_position;
- v3f camera_direction;
-
// Server serialization version
u8 m_server_ser_ver;
f->liquid_alternative_source = CONTENT_WATERSOURCE;
f->liquid_viscosity = WATER_VISC;
f->vertex_alpha = WATER_ALPHA;
+ f->post_effect_color = video::SColor(64, 100, 100, 200);
if(f->special_material == NULL && g_texturesource)
{
// Flowing water material
f->liquid_alternative_source = CONTENT_WATERSOURCE;
f->liquid_viscosity = WATER_VISC;
f->vertex_alpha = WATER_ALPHA;
+ f->post_effect_color = video::SColor(64, 100, 100, 200);
if(f->special_material == NULL && g_texturesource)
{
// Flowing water material
f->liquid_alternative_source = CONTENT_LAVASOURCE;
f->liquid_viscosity = LAVA_VISC;
f->damage_per_second = 4*2;
+ f->post_effect_color = video::SColor(192, 255, 64, 0);
if(f->special_material == NULL && g_texturesource)
{
// Flowing lava material
f->liquid_alternative_source = CONTENT_LAVASOURCE;
f->liquid_viscosity = LAVA_VISC;
f->damage_per_second = 4*2;
+ f->post_effect_color = video::SColor(192, 255, 64, 0);
if(f->special_material == NULL && g_texturesource)
{
// Flowing lava material
return m_client_event_queue.pop_front();
}
-void ClientEnvironment::drawPostFx(video::IVideoDriver* driver, v3f camera_pos)
-{
- /*LocalPlayer *player = getLocalPlayer();
- assert(player);
- v3f pos_f = player->getPosition() + v3f(0,BS*1.625,0);*/
- v3f pos_f = camera_pos;
- v3s16 p_nodes = floatToInt(pos_f, BS);
- MapNode n = m_map->getNodeNoEx(p_nodes);
- if(n.getContent() == CONTENT_WATER || n.getContent() == CONTENT_WATERSOURCE)
- {
- v2u32 ss = driver->getScreenSize();
- core::rect<s32> rect(0,0, ss.X, ss.Y);
- driver->draw2DRectangle(video::SColor(64, 100, 100, 200), rect);
- }
- else if(content_features(n).solidness == 2 &&
- g_settings.getBool("free_move") == false)
- {
- v2u32 ss = driver->getScreenSize();
- core::rect<s32> rect(0,0, ss.X, ss.Y);
- driver->draw2DRectangle(video::SColor(255, 0, 0, 0), rect);
- }
-}
-
#endif // #ifndef SERVER
// Get event from queue. CEE_NONE is returned if queue is empty.
ClientEnvEvent getClientEvent();
-
- // Post effects
- void drawPostFx(video::IVideoDriver* driver, v3f camera_pos);
private:
ClientMap *m_map;
update_skybox(driver, smgr, skybox, brightness);
/*
- Update coulds
+ Update clouds
*/
if(clouds)
{
driver->draw3DBox(*i, video::SColor(255,0,0,0));
}
+ /*
+ Post effects
+ */
+ {
+ client.renderPostFx();
+ }
+
/*
Frametime log
*/
// 0-1ms
guienv->drawAll();
- /*
- Environment post fx
- */
- {
- client.getEnv()->drawPostFx(driver, camera_position);
- }
-
/*
Draw hotbar
*/
<<", rendered "<<vertex_count<<" vertices."<<std::endl;*/
}
+void ClientMap::renderPostFx()
+{
+ // Sadly ISceneManager has no "post effects" render pass, in that case we
+ // could just register for that and handle it in renderMap().
+
+ m_camera_mutex.Lock();
+ v3f camera_position = m_camera_position;
+ m_camera_mutex.Unlock();
+
+ MapNode n = getNodeNoEx(floatToInt(camera_position, BS));
+
+ // - If the player is in a solid node, make everything black.
+ // - If the player is in liquid, draw a semi-transparent overlay.
+ ContentFeatures& features = content_features(n);
+ video::SColor post_effect_color = features.post_effect_color;
+ if(features.solidness == 2 && g_settings.getBool("free_move") == false)
+ {
+ post_effect_color = video::SColor(255, 0, 0, 0);
+ }
+ if (post_effect_color.getAlpha() != 0)
+ {
+ // Draw a full-screen rectangle
+ video::IVideoDriver* driver = SceneManager->getVideoDriver();
+ v2u32 ss = driver->getScreenSize();
+ core::rect<s32> rect(0,0, ss.X, ss.Y);
+ driver->draw2DRectangle(post_effect_color, rect);
+ }
+}
+
bool ClientMap::setTempMod(v3s16 p, NodeMod mod,
core::map<v3s16, MapBlock*> *affected_blocks)
{
void renderMap(video::IVideoDriver* driver, s32 pass);
+ void renderPostFx();
+
/*
Methods for setting temporary modifications to nodes for
drawing.
u8 liquid_viscosity;
// Used currently for flowing liquids
u8 vertex_alpha;
+ // Post effect color, drawn when the camera is inside the node.
+ video::SColor post_effect_color;
// Special irrlicht material, used sometimes
video::SMaterial *special_material;
AtlasPointer *special_atlas;
liquid_alternative_source = CONTENT_IGNORE;
liquid_viscosity = 0;
vertex_alpha = 255;
+ post_effect_color = video::SColor(0, 0, 0, 0);
special_material = NULL;
special_atlas = NULL;
light_source = 0;