void addLandNoise(WORLD* w) { voronoiTiles(w, ZOOM_FACTOR_SQRD); blurPlateLines(w, ZOOM_FACTOR_SQRD); int a,b,c; tripleFor(a,b,c) { POINT* p = coordinateFromRelativeIndex(a,b,c); int height = SEA_LEVEL; double r = scaled_octave_noise_2d(5.0f, .5f, ZOOM_FACTOR, 0, 1, p->x, p->y); int dir = (((random()%2)*2)-1); //(((random()%2)*2)-1); //((getPlateDirection(w->tileRelative(a, b, c))*2)-1); height += dir*(r*HEIGHT_RADIUS); double rx = random()%2; double ry = random()%2; if (rx == 0 || p->x == W_WIDTH-1) { rx = scaled_octave_noise_2d(5.0f, .5f, ZOOM_FACTOR, 0, 1, p->x - 1, p->y); } else { rx = scaled_octave_noise_2d(5.0f, .5f, ZOOM_FACTOR, 0, 1, p->x + 1, p->y); } if (ry == 0 || p->y == W_HEIGHT-1) { ry = scaled_octave_noise_2d(5.0f, .5f, ZOOM_FACTOR, 0, 1, p->x, p->y - 1); } else { ry = scaled_octave_noise_2d(5.0f, .5f, ZOOM_FACTOR, 0, 1, p->x, p->y + 1); } height += dir*((rx/3.0)*HEIGHT_RADIUS) + dir*((rx/3.0)*HEIGHT_RADIUS); setHeight(w->tileRelative(a, b, c), height); }}}
float get_terrain_height_at(float x, float y) { return ( scaled_octave_noise_2d(1.0f, 1.0f, 10.0f, -1.0f, 5.0f, x / 400.0f, y / 400.0f) + scaled_octave_noise_2d(1.0f, 1.0f, 10.0f, 0.0f, 10.0f, x / 4000.0f, y / 4000.0f) + scaled_octave_noise_2d(1.0f, 1.0f, 100.0f, 0.0f, 10.0f, x / 8000.0f, y / 8000.0f) + 0.0f ); }
void NoiseGen::exportToTXT() { std::ofstream ofile; ofile.open("export.txt"); //create vector to story array heightmap in std::vector< std::vector<int> > height_map; //set vector dimensions height_map.resize(IMAGE_SIZE); for(int i = 0; i < IMAGE_SIZE; i++) height_map[i].resize(IMAGE_SIZE); //get noise for heightmap for(int i = 0; i < IMAGE_SIZE; i++) { for(int n = 0; n < IMAGE_SIZE; n++) { //these were copied and modified from the createmap function if(N_MODE == SIMPLEX) height_map[i][n] = scaled_octave_noise_2d(octaves,persistence,scale,0,255,n + xpos,i + ypos); else if(N_MODE == PERLIN) height_map[i][n] = getNoise(octaves, persistence, scale, n + xpos, i + ypos); if(n == IMAGE_SIZE-1) ofile << height_map[i][n] << std::endl; else ofile << height_map[i][n] << ","; } } std::cout << "height map exported to export.txt\n"; ofile.close(); }
void plantTrees() { printf("planting trees: "); init_noise(treeSeed); srand(treeSeedPos); int i = 0; int j = 0; while(i < treeNumber) { if(j++ > 1024 * 1024 * 8) break; int x = rand() % 1024; int y = rand() % 1024; if(material[y][x] != GRASS) continue; double val = scaled_octave_noise_2d(treeOctaves, treeOctavePersistence, treeOctaveScale, 0.0, 1.0, (x - 512) * treeScale / 1024, (y - 512) * treeScale / 1024); if(treeFalloff) val *= falloff(x, y); if(treeValueInvert) val = 1.0 - val; if(val > treeDensity) { trees[i++] = ((top[y][x] - 1) << 20) + (y << 10) + x; material[y][x] = DIRT; } } if(i < treeNumber) { printf("\ncould only plant %d trees\n", i); treeNumber = i; } printf(" done.\n"); }
std::vector< std::vector<int> > Engine::genNoise(int width, int height, int xoffset, int yoffset, float persistence, float octaves, float scale, int minval, int maxval) { //seed //srand(m_Seed); //create a 2d array to store noise map std::vector< std::vector<int> > noisemap; noisemap.resize(height); for(int i = 0; i < height; i++) noisemap[i].resize(width); //clear all data in array for(int i = 0; i < int(noisemap.size()); i++) { for(int n = 0; n < int(noisemap[0].size()); n++) { noisemap[i][n] = 0; } } //generate noise for(int i = 0; i < int(noisemap.size()); i++) { for(int n = 0; n < int(noisemap[0].size()); n++) { noisemap[i][n] = scaled_octave_noise_2d(octaves, persistence, scale, minval, maxval, xoffset+n, yoffset+i); } } return noisemap; }
void generateIsland() { printf("generating island outline: "); init_noise(islandSeed); for(int y = 0; y < 1024; ++y) { for(int x = 0; x < 1024; ++x) { double val = scaled_octave_noise_2d(islandOctaves, islandOctavePersistence, islandOctaveScale, 0.0, 1.0, (x - 512) * islandScale / 1024, (y - 512) * islandScale / 1024); val *= falloff(x, y); if(val > (1.0 - islandDensity)) material[y][x] = GRASS; } } printf(" done.\n"); }
void NoiseGen::createMapImage(int nx, int ny) { mapTexture->clear(); for(int i = 0; i < IMAGE_SIZE; i++) { for(int n = 0; n < IMAGE_SIZE; n++) { //note , the scale factor for simplex differs from perlin, perlin > value zooms in, simplex < value zooms in if(N_MODE == SIMPLEX && !terrainmode) drawPixel(mapTexture, n, i, scaled_octave_noise_2d(octaves,persistence,scale,0,255,n+nx,i + ny) , IMAGE_SCALE); else if(N_MODE == SIMPLEX && terrainmode) drawPixelTerrain(mapTexture, n, i, scaled_octave_noise_2d(octaves,persistence,scale,0,255,(n + nx),(i + ny)), IMAGE_SCALE); else if(N_MODE == PERLIN && !terrainmode) drawPixel(mapTexture, n, i, getNoise(octaves, persistence, scale, n + nx, i + ny), IMAGE_SCALE); else if(N_MODE == PERLIN && terrainmode) drawPixelTerrain(mapTexture, n, i, getNoise(octaves, persistence, scale, n + nx, i + ny), IMAGE_SCALE); } } std::cout << nx << "," << ny << std::endl; }
void generateTop() { printf("generating island top layer: "); init_noise(heightSeed); for(int y = 0; y < 1024; ++y) { for(int x = 0; x < 1024; ++x) { double val = scaled_octave_noise_2d(heightOctaves, heightOctavePersistence, heightOctaveScale, 0.0, 1.0, (x - 512) * heightScale / 1024, (y - 512) * heightScale / 1024); if(heightFalloff) val *= falloff(x, y); if(heightValueInvert) val = 1.0f - val; double height = pow(val, heightExponent); height = heightBase + (heightTop - heightBase) * height; if(material[y][x] != 0) { top[y][x] = height; fraction[y][x] = (height - top[y][x]) * 3.0 + 1.0; bottom[y][x] = top[y][x] - bottomMinThick; } } } printf(" done.\n"); }
void HexMap::generateBiomes(mt19937& urng) { land.clear(); static uniform_real_distribution<float> offset(-10000000.0f, 10000000.0f); int townChance = 16384 / 24; const HexTileS* type = &HexTileS::get(HexTileS::NONE); int colorIndex = 0; sf::Vector2f offsetHeight = { offset(urng), offset(urng) }; sf::Vector2f offsetTemperature = { offset(urng), offset(urng) }; sf::Vector2f offsetMoisture = { offset(urng), offset(urng) }; sf::Vector2f offsetDrainage = { offset(urng), offset(urng) }; sf::Vector2i hexPos; sf::Vector2f p; float heightVal = 0.0f; float tempVal = 0.0f; float moistVal = 0.0f; float drainVal = 0.0f; for (int r = 0; r < mapSize_.y; r++) { for (int q = 0, qoff = (int)-floor(r / 2.0); q < mapSize_.x; q++, qoff++) { hexPos = { q, r }; p = { qoff + r * 0.5f, (float)r }; heightVal = scaled_octave_noise_2d(config::gen::heightParams[0], config::gen::heightParams[1], config::gen::heightParams[2], 0.0f, 255.0f, p.x + offsetHeight.x, p.y + offsetHeight.y); tempVal = scaled_octave_noise_2d(config::gen::tempParams[0], config::gen::tempParams[1], config::gen::tempParams[2], 96.0f, 160.0f, p.x + offsetTemperature.x, p.y + offsetTemperature.y); moistVal = scaled_octave_noise_2d(config::gen::moistParams[0], config::gen::moistParams[1], config::gen::moistParams[2], 0.0f, 255.0f, p.x + offsetMoisture.x, p.y + offsetMoisture.y); drainVal = scaled_octave_noise_2d(config::gen::drainParams[0], config::gen::drainParams[1], config::gen::drainParams[2], 0.0f, 255.0f, p.x + offsetDrainage.x, p.y + offsetDrainage.y); switch (0) { // fix case 0: tempVal += (r - 64) * 1.5f; break; case 1: tempVal -= (r - 64) * 1.5f; break; case 2: tempVal += (q - 64) * 1.5f; break; case 3: tempVal -= (q - 64) * 1.5f; } // Determine the terrain type based on elevation, temperature, moisture and drainage if (heightVal < SEA_LEVEL) { type = &HexTileS::get(HexTileS::OCEAN); colorIndex = (int)heightVal; } else { land.push_back(p); colorIndex = (int)heightVal - SEA_LEVEL; if (tempVal < config::gen::cold) { if (moistVal >= config::gen::forest[0]) { if (tempVal < 50.0f) { if (moistVal >= config::gen::forest[2]) { type = &HexTileS::get(HexTileS::TAIGA_SNOW_L); } else if (moistVal >= config::gen::forest[1]) { type = &HexTileS::get(HexTileS::TAIGA_SNOW_M); } else { type = &HexTileS::get(HexTileS::TAIGA_SNOW_S); } } else { if (moistVal >= config::gen::forest[2]) { type = &HexTileS::get(HexTileS::TAIGA_L); } else if (moistVal >= config::gen::forest[1]) { type = &HexTileS::get(HexTileS::TAIGA_M); } else { type = &HexTileS::get(HexTileS::TAIGA_S); } } } else { if (tempVal < 50.0f) { type = &HexTileS::get(HexTileS::TUNDRA_SNOW); } else { type = &HexTileS::get(HexTileS::TUNDRA); } } } else if (tempVal < config::gen::hot) { if (moistVal >= config::gen::forest[0]) { if (drainVal >= config::gen::swamp) { if (moistVal >= config::gen::forest[2]) { type = &HexTileS::get(HexTileS::FOREST_L); } else if (moistVal >= config::gen::forest[1]) { type = &HexTileS::get(HexTileS::FOREST_M); } else { type = &HexTileS::get(HexTileS::FOREST_S); } } else { type = &HexTileS::get(HexTileS::SWAMP); } } else if (moistVal >= config::gen::desert) { type = &HexTileS::get(HexTileS::GRASSLAND); } else { if (drainVal >= config::gen::sand) { type = &HexTileS::get(HexTileS::SEMIARID); } else { type = &HexTileS::get(HexTileS::DESERT); } } } else { if (moistVal >= config::gen::forest[0]) { if (drainVal >= config::gen::swamp) { if (moistVal >= config::gen::forest[2]) { type = &HexTileS::get(HexTileS::JUNGLE_L); } else if (moistVal >= config::gen::forest[1]) { type = &HexTileS::get(HexTileS::JUNGLE_M); } else { type = &HexTileS::get(HexTileS::JUNGLE_S); } } else { type = &HexTileS::get(HexTileS::SWAMP); } } else if (moistVal >= config::gen::desert) { type = &HexTileS::get(HexTileS::SAVANNA); } else { if (drainVal >= config::gen::sand) { type = &HexTileS::get(HexTileS::SEMIARID); } else { type = &HexTileS::get(HexTileS::DESERT); } } } } getOffset(hexPos.x, hexPos.y).FLAGS = 0; setTile(hexPos, *type, urng); if (type->FLAGS[HexTileS::GRADIENT]) { pushTileColor(hexPos, type->colors[colorIndex]); } else { pushTileColor(hexPos, sf::Color::White); } } } }
/** * Generates terrain equals the size height*width. */ bool SmoothTerrain::generateTerrain(unsigned int width, unsigned int height) { std::cout << "running smooth terrain generation ... "; vertices.clear(); texCoords.clear(); normals.clear(); mountains.clear(); float miny = 0; float maxy = 0.20; float detail = 0.25; for (float z = 0; z < height; z += detail) { for (float x = 0; x < width; x += detail) { float y1 = scaled_octave_noise_2d(5, 0.1, 1, miny, maxy, x, z); float y2 = scaled_octave_noise_2d(5, 0.1, 1, miny, maxy, x, z+detail); float y3 = scaled_octave_noise_2d(5, 0.1, 1, miny, maxy, x+detail, z); float y4 = scaled_octave_noise_2d(5, 0.1, 1, miny, maxy, x+detail, z+detail); //y1 = 0, y2 = 0, y3 = 0, y4 = 0; glm::vec3 t1 = glm::vec3(x, y1, z); glm::vec3 t2 = glm::vec3(x, y2, z+detail); glm::vec3 t3 = glm::vec3(x+detail, y3, z); glm::vec3 t4 = glm::vec3(x+detail, y4, z+detail); vertices.push_back(t1); vertices.push_back(t2); vertices.push_back(t3); vertices.push_back(t3); vertices.push_back(t2); vertices.push_back(t4); normals.push_back(glm::cross(t2 - t1, t3 - t1)); normals.push_back(glm::cross(t2 - t1, t3 - t1)); normals.push_back(glm::cross(t2 - t1, t3 - t1)); normals.push_back(glm::cross(t3 - t4, t2 - t4)); normals.push_back(glm::cross(t3 - t4, t2 - t4)); normals.push_back(glm::cross(t3 - t4, t2 - t4)); texCoords.push_back(glm::vec2(0.0, 0.0)); texCoords.push_back(glm::vec2(1.0, 0.0)); texCoords.push_back(glm::vec2(0.0, 1.0)); texCoords.push_back(glm::vec2(0.0, 1.0)); texCoords.push_back(glm::vec2(1.0, 0.0)); texCoords.push_back(glm::vec2(1.0, 1.0)); } } // generate random hills at random.x and player.z srand(time(NULL)); int msize = width / 2; float startx = Settings::playerStart.x + 7.0, startz = Settings::playerStart.z; for (int i = 0; i < msize; i++) { startx += rand() % 5; float starty = rand() % 10; // Low mountains near the boss so you don't get a high peak behind the bird if(startx - Settings::bossStart.x >= -1.0*Settings::startBossStateRange - 10.0 && startx - Settings::bossStart.x <= 5.0) starty = rand() % 4; //if(startx - Settings::bossStart.x <= -5.0 || startx - Settings::bossStart.x >= 5.0) mountains.push_back(glm::vec3(startx, starty, startz)); } for (int i = 0; i < vertices.size(); i++) { for (int j = 0; j < msize; j++) { float distance = glm::distance(glm::vec2(vertices[i].x, vertices[i].z), glm::vec2(mountains[j].x, mountains[j].z)); if (distance < 4.0) { vertices[i].y += 0.2 * (1.0 / (distance + 1.0)) * mountains[j].y; } //std::cout << "vertices y : " << vertices[i].y << std::endl; // recalculate normal /* glm::vec3 t1 = vertices[i - (i % 3)]; glm::vec3 t2 = vertices[i - (i % 3) + 1]; glm::vec3 t3 = vertices[i - (i % 3) + 2];*/ } } //calulate highest y point for every 1/4 x value with some threshold on the x value. float maxYSingle = 0; int counter = 0; for (float x = 0; x < width; x += detail) { for (int i = 0; i < vertices.size(); i++) { if(vertices[i].x >= (x - 0.1) && vertices[i].x <= (x + 0.1) && vertices[i].y > maxYSingle) { maxYSingle = vertices[i].y; } } new_vec.push_back(maxYSingle); maxYSingle = 0; counter++; } int texWidth, texHeight; unsigned char *image = SOIL_load_image("resources/grass.png", &texWidth, &texHeight, 0, SOIL_LOAD_RGB); if (!image) { std::cerr << "could not load image resources/grass.png" << std::endl; } else { // load textures glGenTextures(1, textures); glBindTexture(GL_TEXTURE_2D, textures[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texWidth, texHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, image); SOIL_free_image_data(image); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // add textures to texture buffer glGenBuffers(1, &vboTexCoords); glBindBuffer(GL_ARRAY_BUFFER, vboTexCoords); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec2) * texCoords.size(), &texCoords[0], GL_STATIC_DRAW); } // load data into VBO glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices.size(), &vertices[0], GL_STATIC_DRAW); // load normals glGenBuffers(1, &normalBuffer); glBindBuffer(GL_ARRAY_BUFFER, normalBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * normals.size(), &normals[0], GL_STATIC_DRAW); std::cout << "done" << std::endl; return true; }