--- a/src/Terrain.cc Sun Dec 07 02:08:36 2008 +0000
+++ b/src/Terrain.cc Sun Dec 07 13:07:58 2008 +0000
@@ -16,7 +16,124 @@
this->generatePixelBuffer();
}
+void fractal_step(std::vector<double>& land, int size, double str, int dist) {
+ for(int i = 0; i < size; i += dist*2) {
+ for(int j = dist; j < size; j += dist*2) {
+ double sum = 0;
+ sum += land[((i+size-dist)%size)+(j*size)];
+ sum += land[i+((j+size-dist)%size)*size];
+ sum += land[((i+dist)%size)+j*size];
+ sum += land[i+((j+dist)%size)*size];
+ land[i+j*size] = sum/4 + (rand()%10000-5000)*str;
+ }
+ }
+ for(int i = dist; i < size; i += dist*2) {
+ for(int j = 0; j < size; j += dist*2) {
+ double sum = 0;
+ sum += land[((i+size-dist)%size)+(j*size)];
+ sum += land[i+((j+size-dist)%size)*size];
+ sum += land[((i+dist)%size)+j*size];
+ sum += land[i+((j+dist)%size)*size];
+ land[i+j*size] = sum/4 + (rand()%10000-5000)*str;
+ }
+ }
+}
+void fractal_diamond(std::vector<double>& land, int size, double str, int dist) {
+ for(int i = dist; i < size; i += dist*2) {
+ for(int j = dist; j < size; j += dist*2) {
+ double sum = 0;
+ sum += land[((i+size-dist)%size)+(((j+size-dist)%size)*size)];
+ sum += land[((i+dist)%size)+((j+size-dist)%size)*size];
+ sum += land[(i+size-dist)%size+((j+dist)%size)*size];
+ sum += land[(i+dist)%size+((j+dist)%size)*size];
+ land[i+j*size] = sum/4 + (rand()%10000-5000)*str;
+ }
+ }
+}
+
+
+void Terrain::generate_texture() {
+ int texturesize = 128;
+ texture = std::vector<std::vector<int> >(texturesize, std::vector<int>(texturesize));
+ std::vector<double> land(texture.size()*texture.size());
+ double str = 0.8;
+ double H = 0.5;
+ for(int i = 512; i >= 1; i /= 2) {
+ fractal_diamond(land, texturesize, str, i);
+ fractal_step(land, texturesize, str, i);
+ str *= H;
+ }
+ double min = 100000;
+ double max = -100000;
+ for(int i = 0; i < texturesize*texturesize; i++) {
+ if(land[i] < min) min = land[i];
+ if(land[i] > max) max = land[i];
+ }
+ max -= min;
+ for(int i = 0; i < texturesize*texturesize; i++) {
+ land[i] -= min;
+ }
+ for(int i = 0; i < texturesize*texturesize; i++) {
+ land[i] = land[i]*255/max;
+ texture[i%texturesize][i/texturesize] = (int)(land[i]);
+ }
+}
+
+/**
+ * Changes color depending on x and y values
+ * x and y should be valid coordinates (not outside)
+ */
+void Terrain::noisifyPixel(CL_Color& color, int x, int y) {
+ int tx = x%texture.size();
+ int ty = y%texture[0].size();
+ int red = color.get_red();
+ int green = color.get_green();
+ int blue = color.get_blue();
+ red += texture[tx][ty]/8-16;
+ green += texture[tx][ty]/8-16;
+ blue += texture[tx][ty]/8-16;
+ if(red < 0)
+ red = 0;
+ if(red >= 256)
+ red = 255;
+ if(green < 0)
+ green = 0;
+ if(blue >= 256)
+ blue = 255;
+ if(blue < 0)
+ blue = 0;
+ if(green >= 256)
+ green = 255;
+
+ color = CL_Color(red, green, blue);
+}
+
+/**
+ * Sets to color the correct color of pixel in (x,y)
+ */
+void Terrain::loadPixelColor(CL_Color& color, int x, int y) {
+ if ((x < 0) || (y < 0) ||(x >= MAP_WIDTH) || (y >= MAP_HEIGHT)) {
+ color = CL_Color(0, 0, 0);
+ return;
+ }
+ switch(terrain[x][y]) {
+ case EMPTY:
+ color = COLOR_EMPTY;
+ noisifyPixel(color, x, y);
+ break;
+ case DIRT:
+ color = COLOR_DIRT;
+ noisifyPixel(color, x, y);
+ break;
+ case ROCK:
+ color = COLOR_ROCK;
+ noisifyPixel(color, x, y);
+ break;
+ }
+}
+
void Terrain::generatePixelBuffer() {
+ generate_texture();
this->pixbuf = CL_PixelBuffer(MAP_WIDTH, MAP_HEIGHT, 4*MAP_WIDTH,
CL_PixelFormat::rgba8888);
@@ -36,6 +153,7 @@
default: // TODO: Shouldn't be here.
break;
}
+ loadPixelColor(color, i, j);
this->pixbuf.draw_pixel(i, j, color);
}
}
@@ -121,7 +239,9 @@
// out of bounds
if ((i-mid.x)*(i-mid.x)+(j-mid.y)*(j-mid.y) < r*r) {
terrain[i][j] = EMPTY;
- pixbuf.draw_pixel(i, j, COLOR_EMPTY);
+ CL_Color color(0, 0, 0);
+ loadPixelColor(color, i, j);
+ pixbuf.draw_pixel(i, j, color);
}
}
}
--- a/src/Terrain.hh Sun Dec 07 02:08:36 2008 +0000
+++ b/src/Terrain.hh Sun Dec 07 13:07:58 2008 +0000
@@ -42,6 +42,11 @@
private:
// Terrain graphic
CL_PixelBuffer pixbuf;
+ std::vector<std::vector<int> > texture;
+
+ void generate_texture();
+
+ void noisifyPixel(CL_Color& col, int x, int y);
/**
* Get pixel location of a point that is in "real" units.
@@ -59,6 +64,11 @@
*/
uint16_t scale(float x) const;
+ /**
+ * Sets to color the correct color of pixel in (x,y)
+ */
+ void loadPixelColor(CL_Color& color, int x, int y);
+
public:
// TODO: This should be private.