3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 A quick messy implementation of terrain rendering for a long
22 distance according to map seed
26 #include "constants.h"
32 scene::ISceneNode* parent,
33 scene::ISceneManager* mgr,
37 scene::ISceneNode(parent, mgr, id),
42 dstream<<__FUNCTION_NAME<<std::endl;
44 m_material.setFlag(video::EMF_LIGHTING, false);
45 m_material.setFlag(video::EMF_BACK_FACE_CULLING, true);
46 m_material.setFlag(video::EMF_BILINEAR_FILTER, false);
47 m_material.setFlag(video::EMF_FOG_ENABLE, false);
48 //m_material.setFlag(video::EMF_ANTI_ALIASING, true);
49 //m_material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
51 m_box = core::aabbox3d<f32>(-BS*1000000,-BS*31000,-BS*1000000,
52 BS*1000000,BS*31000,BS*1000000);
58 dstream<<__FUNCTION_NAME<<std::endl;
61 void FarMesh::OnRegisterSceneNode()
65 //SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
66 //SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID);
67 SceneManager->registerNodeForRendering(this, scene::ESNRP_SKY_BOX);
70 ISceneNode::OnRegisterSceneNode();
73 #define MYROUND(x) (x > 0.0 ? (int)x : (int)x - 1)
76 core::map<v2s16, float> g_heights;
78 float ground_height(u64 seed, v2s16 p2d)
80 core::map<v2s16, float>::Node *n = g_heights.find(p2d);
83 float avg_mud_amount = 4;
84 float gh = BS*base_rock_level_2d(seed, p2d) + avg_mud_amount*BS;
90 void FarMesh::render()
92 video::IVideoDriver* driver = SceneManager->getVideoDriver();
94 /*if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_TRANSPARENT)
96 /*if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SOLID)
98 if(SceneManager->getSceneNodeRenderPass() != scene::ESNRP_SKY_BOX)
101 driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
102 driver->setMaterial(m_material);
104 const s16 grid_radius_i = 12;
105 const float grid_size = BS*50;
106 const v2f grid_speed(-BS*0, 0);
108 // Position of grid noise origin in world coordinates
109 v2f world_grid_origin_pos_f(0,0);
110 // Position of grid noise origin from the camera
111 v2f grid_origin_from_camera_f = world_grid_origin_pos_f - m_camera_pos;
112 // The center point of drawing in the noise
113 v2f center_of_drawing_in_noise_f = -grid_origin_from_camera_f;
114 // The integer center point of drawing in the noise
115 v2s16 center_of_drawing_in_noise_i(
116 MYROUND(center_of_drawing_in_noise_f.X / grid_size),
117 MYROUND(center_of_drawing_in_noise_f.Y / grid_size)
119 // The world position of the integer center point of drawing in the noise
120 v2f world_center_of_drawing_in_noise_f = v2f(
121 center_of_drawing_in_noise_i.X * grid_size,
122 center_of_drawing_in_noise_i.Y * grid_size
123 ) + world_grid_origin_pos_f;
125 for(s16 zi=-grid_radius_i; zi<grid_radius_i; zi++)
126 for(s16 xi=-grid_radius_i; xi<grid_radius_i; xi++)
129 xi+center_of_drawing_in_noise_i.X,
130 zi+center_of_drawing_in_noise_i.Y
133 /*if((p_in_noise_i.X + p_in_noise_i.Y)%2==0)
135 /*if((p_in_noise_i.X/2 + p_in_noise_i.Y/2)%2==0)
138 v2f p0 = v2f(xi,zi)*grid_size + world_center_of_drawing_in_noise_f;
142 noise[0] = d*noise2d_perlin(
143 (float)(p_in_noise_i.X+0)*grid_size/BS/100,
144 (float)(p_in_noise_i.Y+0)*grid_size/BS/100,
147 noise[1] = d*noise2d_perlin(
148 (float)(p_in_noise_i.X+0)*grid_size/BS/100,
149 (float)(p_in_noise_i.Y+1)*grid_size/BS/100,
152 noise[2] = d*noise2d_perlin(
153 (float)(p_in_noise_i.X+1)*grid_size/BS/100,
154 (float)(p_in_noise_i.Y+1)*grid_size/BS/100,
157 noise[3] = d*noise2d_perlin(
158 (float)(p_in_noise_i.X+1)*grid_size/BS/100,
159 (float)(p_in_noise_i.Y+0)*grid_size/BS/100,
163 noise[0] = ground_height(m_seed, v2s16(
164 (p_in_noise_i.X+0)*grid_size/BS,
165 (p_in_noise_i.Y+0)*grid_size/BS));
166 noise[1] = ground_height(m_seed, v2s16(
167 (p_in_noise_i.X+0)*grid_size/BS,
168 (p_in_noise_i.Y+1)*grid_size/BS));
169 noise[2] = ground_height(m_seed, v2s16(
170 (p_in_noise_i.X+1)*grid_size/BS,
171 (p_in_noise_i.Y+1)*grid_size/BS));
172 noise[3] = ground_height(m_seed, v2s16(
173 (p_in_noise_i.X+1)*grid_size/BS,
174 (p_in_noise_i.Y+0)*grid_size/BS));
176 float h_min = BS*65535;
177 float h_max = -BS*65536;
178 for(u32 i=0; i<4; i++)
185 float steepness = (h_max - h_min)/grid_size;
187 float h_avg = (noise[0]+noise[1]+noise[2]+noise[3])/4.0;
188 float light_f = noise[0]+noise[1]-noise[2]-noise[3];
190 if(light_f < -1.0) light_f = -1.0;
191 if(light_f > 1.0) light_f = 1.0;
195 v2f p1 = p0 + v2f(1,1)*grid_size;
199 if(h_avg < WATER_LEVEL*BS && h_max < (WATER_LEVEL+5)*BS)
201 c = video::SColor(128,59,86,146);
202 /*// Set to water level
203 for(u32 i=0; i<4; i++)
205 if(noise[i] < BS*WATER_LEVEL)
206 noise[i] = BS*WATER_LEVEL;
210 else if(steepness > 2.0)
211 c = video::SColor(128,128,128,128);
213 c = video::SColor(128,107,134,51);
215 // Set to water level
216 for(u32 i=0; i<4; i++)
218 if(noise[i] < BS*WATER_LEVEL)
219 noise[i] = BS*WATER_LEVEL;
222 float b = m_brightness + light_f*0.1*m_brightness;
226 c = video::SColor(128, b*c.getRed(), b*c.getGreen(), b*c.getBlue());
228 video::S3DVertex vertices[4] =
230 video::S3DVertex(p0.X,noise[0],p0.Y, 0,0,0, c, 0,1),
231 video::S3DVertex(p0.X,noise[1],p1.Y, 0,0,0, c, 1,1),
232 video::S3DVertex(p1.X,noise[2],p1.Y, 0,0,0, c, 1,0),
233 video::S3DVertex(p1.X,noise[3],p0.Y, 0,0,0, c, 0,0),
235 u16 indices[] = {0,1,2,2,3,0};
236 driver->drawVertexPrimitiveList(vertices, 4, indices, 2,
237 video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
240 driver->clearZBuffer();
243 void FarMesh::step(float dtime)
248 void FarMesh::update(v2f camera_p, float brightness)
250 m_camera_pos = camera_p;
251 m_brightness = brightness;