WEmitter::WEmitter(scene::ISceneNode* parent, scene::ISceneManager* mgr, s32 id, v3s16 position, s16 height) : scene::ISceneNode(parent, mgr, id), m_position(position), m_height(height), m_texture_v(0.5) { m_material.setFlag(video::EMF_LIGHTING, false); m_material.setFlag(video::EMF_BACK_FACE_CULLING, false); m_material.setFlag(video::EMF_BILINEAR_FILTER, false); m_material.setFlag(video::EMF_FOG_ENABLE, false); m_material.setFlag(video::EMF_ANTI_ALIASING, false); video::IVideoDriver* driver = SceneManager->getVideoDriver(); // driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false); m_material.setTexture(0, driver->getTexture(getTexturePath("rain.png").c_str())); m_material.MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; m_box = core::aabbox3d<f32>(m_position.X * BS - BS / 2, m_position.Y * BS - BS / 2, m_position.Z * BS - BS / 2, m_position.X * BS + BS / 2, m_position.Y * BS + BS / 2 + m_height * BS, m_position.Z * BS + BS / 2); f32 rx = BS / 2; f32 ry = BS / 2; f32 rz = BS / 2; f32 h = m_height * BS; m_material.getTextureMatrix(0).setTextureScale(1.0, -m_height); video::SColor c_top(128, 240, 240, 255); m_planes[0] = video::S3DVertex(-rx, h, 0, 0, 0, 0, c_top, 0, 1); m_planes[1] = video::S3DVertex( rx, h, 0, 0, 0, 0, c_top, 1, 1); m_planes[2] = video::S3DVertex( rx, -ry, 0, 0, 0, 0, c_top, 1, 0); m_planes[3] = video::S3DVertex(-rx, -ry, 0, 0, 0, 0, c_top, 0, 0); m_planes[4] = video::S3DVertex(0, h, -rz, 0, 0, 0, c_top, 0, 1); m_planes[5] = video::S3DVertex(0, h, rz, 0, 0, 0, c_top, 1, 1); m_planes[6] = video::S3DVertex(0, -ry, rz, 0, 0, 0, c_top, 1, 0); m_planes[7] = video::S3DVertex(0, -ry, -rz, 0, 0, 0, c_top, 0, 0); for (u16 i = 0; i < 8; i++) m_planes[i].Pos += v3f(m_position.X * BS, m_position.Y * BS, m_position.Z * BS); m_indices = { 0, 1, 2, 2, 3, 0, 4, 5, 6, 6, 7, 4 }; }
void Clouds::render() { video::IVideoDriver* driver = SceneManager->getVideoDriver(); /*if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT) return;*/ if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SOLID) return; ScopeProfiler sp(g_profiler, "Rendering of clouds, avg", SPT_AVG); int num_faces_to_draw = 6; if(g_settings->getBool("enable_2d_clouds")) num_faces_to_draw = 1; driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); driver->setMaterial(m_material); /* Clouds move from X+ towards X- */ const s16 cloud_radius_i = 12; const float cloud_size = BS*48; const v2f cloud_speed(-BS*2, 0); // Position of cloud noise origin in world coordinates v2f world_cloud_origin_pos_f = m_time*cloud_speed; // Position of cloud noise origin from the camera v2f cloud_origin_from_camera_f = world_cloud_origin_pos_f - m_camera_pos; // The center point of drawing in the noise v2f center_of_drawing_in_noise_f = -cloud_origin_from_camera_f; // The integer center point of drawing in the noise v2s16 center_of_drawing_in_noise_i( MYROUND(center_of_drawing_in_noise_f.X / cloud_size), MYROUND(center_of_drawing_in_noise_f.Y / cloud_size) ); // 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 ) + world_cloud_origin_pos_f; for(s16 zi=-cloud_radius_i; zi<cloud_radius_i; zi++) for(s16 xi=-cloud_radius_i; xi<cloud_radius_i; xi++) { v2s16 p_in_noise_i( xi+center_of_drawing_in_noise_i.X, zi+center_of_drawing_in_noise_i.Y ); /*if((p_in_noise_i.X + p_in_noise_i.Y)%2==0) continue;*/ /*if((p_in_noise_i.X/2 + p_in_noise_i.Y/2)%2==0) continue;*/ v2f p0 = v2f(xi,zi)*cloud_size + world_center_of_drawing_in_noise_f; double noise = noise2d_perlin_abs( (float)p_in_noise_i.X*cloud_size/BS/200, (float)p_in_noise_i.Y*cloud_size/BS/200, m_seed, 3, 0.4); if(noise < 0.95) continue; float b = m_brightness; 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); video::S3DVertex v[4] = { video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 1), video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 1), video::S3DVertex(0,0,0, 0,0,0, c_top, 1, 0), video::S3DVertex(0,0,0, 0,0,0, c_top, 0, 0) }; f32 rx = cloud_size; f32 ry = 8*BS; f32 rz = cloud_size; for(int i=0; i<num_faces_to_draw; i++) { switch(i) { case 0: // top v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz; v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz; v[2].Pos.X= rx; v[2].Pos.Y= ry; v[2].Pos.Z= rz; v[3].Pos.X= rx; v[3].Pos.Y= ry, v[3].Pos.Z=-rz; break; case 1: // back for(int j=0;j<4;j++) v[j].Color=c_side_1; v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz; v[1].Pos.X= rx; v[1].Pos.Y= ry; v[1].Pos.Z=-rz; v[2].Pos.X= rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz; v[3].Pos.X=-rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz; break; case 2: //right for(int j=0;j<4;j++) v[j].Color=c_side_2; v[0].Pos.X= rx; v[0].Pos.Y= ry; v[0].Pos.Z=-rz; v[1].Pos.X= rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz; v[2].Pos.X= rx; v[2].Pos.Y=-ry; v[2].Pos.Z= rz; v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz; break; case 3: // front for(int j=0;j<4;j++) v[j].Color=c_side_1; v[0].Pos.X= rx; v[0].Pos.Y= ry; v[0].Pos.Z= rz; v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z= rz; v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z= rz; v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z= rz; break; case 4: // left for(int j=0;j<4;j++) v[j].Color=c_side_2; v[0].Pos.X=-rx; v[0].Pos.Y= ry; v[0].Pos.Z= rz; v[1].Pos.X=-rx; v[1].Pos.Y= ry; v[1].Pos.Z=-rz; v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz; v[3].Pos.X=-rx; v[3].Pos.Y=-ry, v[3].Pos.Z= rz; break; case 5: // bottom for(int j=0;j<4;j++) v[j].Color=c_bottom; v[0].Pos.X= rx; v[0].Pos.Y=-ry; v[0].Pos.Z= rz; v[1].Pos.X=-rx; v[1].Pos.Y=-ry; v[1].Pos.Z= rz; v[2].Pos.X=-rx; v[2].Pos.Y=-ry; v[2].Pos.Z=-rz; v[3].Pos.X= rx; v[3].Pos.Y=-ry, v[3].Pos.Z=-rz; break; } v3f pos = v3f(p0.X,m_cloud_y,p0.Y); for(u16 i=0; i<4; i++) v[i].Pos += pos; u16 indices[] = {0,1,2,2,3,0}; driver->drawVertexPrimitiveList(v, 4, indices, 2, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT); } } }