some generated texture
authornireco
Sun, 07 Dec 2008 13:07:58 +0000
changeset 243 25d9a0090397
parent 242 fb517ed0ecee
child 244 80a818ac288b
some generated texture
src/Terrain.cc
src/Terrain.hh
--- 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.