ColorRGB *ProceduralTexture::cobblestone(int stoneSize, int stoneNoise, ColorHSV color, int colorRange, float edgeIntensity, int edgeSize, float edgeOpacity, float edgeSmooth, int stoneLayers, float smoothness, float stoneBrightness, bool createNormalMap){ unsigned char *ct = generateCelluarTexture(stoneSize); gaussianBlur(ct, edgeSmooth); brightnessContrast(ct, 0, edgeIntensity); unsigned char *pn = generatePerlinNoise(stoneNoise); postEffect(pn, stoneLayers, smoothness); brightnessContrast(pn, stoneBrightness, 1); mix(pn, ct, edgeSize, edgeOpacity); delete[] ct; if (createNormalMap) generateNormalMap(pn); ColorRGB *cct = generateCelluarTexture(stoneSize, color, colorRange); mix(cct, pn); delete[] pn; return cct; }
int terrainInput(double elevation[IslandWidth][IslandHeight], Biome biomesInformation[IslandWidth][IslandHeight], double * circleVertices, glm::vec3 circleColor[IslandWidth][IslandHeight], glm::vec3 perlinOffsets[IslandWidth][IslandHeight], Mode pointMode, bool IslandMode){ int waterIdx; int waterLocCount = 15; terrain waterLocations[waterLocCount]; for(waterIdx = 0; waterIdx < waterLocCount; waterIdx++){ waterLocations[waterIdx].x = (rand() % (int) IslandWidth) + 1; // waterLocations[waterIdx].x = 700; waterLocations[waterIdx].y = (rand() % (int) IslandHeight) + 1; // waterLocations[waterIdx].y = 600; waterLocations[waterIdx].waterValue = 1.0f; } int circleIdx; int * circleLocations; int circlesCt; double xpos0, xpos1, ypos0, ypos1, r, rmax, myPow; rmax = 100; // for circles r = 160; switch(pointMode){ case Spiral: circlesCt = 180; if(IslandMode) circlesCt = 300; generateSpiralPoints(&circleLocations, circlesCt); break; case Random: circlesCt = 100; if(IslandMode) circlesCt = 300; generateRandomPoints(&circleLocations, circlesCt); break; case Grid: circlesCt = 80; // r = 100; if(IslandMode) circlesCt = 300; generateGridPoints(&circleLocations, circlesCt); break; default: break; } terrain allIntensity[circlesCt]; int heightRand; int maxHeight = 500; int i =0; for(circleIdx = 0; circleIdx < circlesCt; circleIdx++){ // allIntensity[circleIdx].x = (rand() % (int) IslandWidth) + 1; allIntensity[circleIdx].x = circleLocations[i++]; // allIntensity[circleIdx].y = (rand() % (int) IslandHeight) + 1; allIntensity[circleIdx].y = circleLocations[i++]; i++; heightRand = (rand() % maxHeight); // allIntensity[circleIdx].intensity = 0.2f; allIntensity[circleIdx].intensity = ((double) heightRand / maxHeight) * 0.4f; } double theta = 0; int vi = 0, coli = 0; double rrand = (rand() % (int) r); int x,y; i = 0; glm::vec2 center; glm::vec2 loc; center.x = IslandWidth /2; center.y = IslandHeight /2; double dIslandCtr; double distFromCenter; for(x = 0; x < IslandWidth; x++){ for(y = 0; y < IslandHeight; y++){ loc.x = x; loc.y = y; dIslandCtr = glm::length(loc -center); dIslandCtr /= glm::length(center); for(i = 0; i < circlesCt; i++){ // r = (rand() % (int) (rmax)) + rmax /2; distFromCenter = sqrt( (double) pow(allIntensity[i].x - x, 2) + (double) pow(allIntensity[i].y - y, 2)); distFromCenter = ((distFromCenter / r) > 1) ? 1.0f : (distFromCenter / r); // distFromCenter = ((distFromCenter / (r + rrand) ) > 1) ? 1.0f : (distFromCenter / r + rrand); if(distFromCenter <= 1.000000f){ // the further you are, the less intensity, lower elevation if((1.0 - distFromCenter) < (1.0 /3.0)){ myPow = 2; } else if((1.0 - distFromCenter) < (2.0 * 1.0 /3.0)){ myPow = 1; } else { myPow = 0.5; } if(IslandMode){ elevation[x][y] += allIntensity[i].intensity * pow(1.0 - distFromCenter, myPow) * pow(1.0 - dIslandCtr, 3); } else{ elevation[x][y] += allIntensity[i].intensity * pow(1.0 - distFromCenter, myPow); } } else { elevation[x][y] += 0.0f; } } } } // Perlin, may or may not be needed generatePerlinNoise(perlinOffsets, elevation); biomesGeneration(circleColor, elevation, waterLocations, waterLocCount, biomesInformation, IslandMode); return IslandWidth * IslandHeight; }
// Creates some perlin noise void Sprite::createClouds() { // Note: This is HIGHLY unoptimzied for two reasons: // 1) I still haven't grasped Perlin noise completely, and wish to learn it as I go. // Most of this stuff I found with random googling and implemented it as I could // 2) I want to experiment with multithreading and see the performance increase. // Eventually I hope to do this on a fragment shader std::vector<boost::thread*> threadContainer; std::vector<boost::thread*>::iterator iter; SDL_LockSurface(spriteSurface); number_of_threads = 8; int work_per_thread = floor(float(w) / float(number_of_threads)); float** base = generateBaseNoise(); std::vector<SDL_Surface*> surfaceVector; SDL_Surface* lovely_perlin = generatePerlinNoise(base, 12); spriteSurface = lovely_perlin; threads_ready = 0; // Give some output on the screen while we are working =) SDL_UnlockSurface(spriteSurface); regenerateTexture(); render(); SDL_GL_SwapBuffers(); SDL_LockSurface(spriteSurface); SDL_Surface* big_perlin = generatePerlinNoise(base, 10); SDL_Surface* bigger_perlin = generatePerlinNoise(base, 13); SDL_Surface* placeHolder = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, 0, 0, 0, 0); threadContainer.clear(); threads_ready = 0; for (int i = 0; i < number_of_threads; i++) { boost::thread surfaceMerger(mergeTwoSurfaces, bigger_perlin, big_perlin, placeHolder, 0.8f, true, i*work_per_thread, (i+1)*work_per_thread, 0, h); boost::thread* threadPtr = &surfaceMerger; threadContainer.push_back(threadPtr); } fprintf(stderr, "Waiting for threads to finish combining surfaces\n"); while (threads_ready < number_of_threads) { } fprintf(stderr, "Joining threads\n"); for (iter = threadContainer.begin(); iter != threadContainer.end(); iter++) { (*iter)->join(); } spriteSurface = placeHolder; SDL_UnlockSurface(spriteSurface); regenerateTexture(); render(); SDL_GL_SwapBuffers(); SDL_LockSurface(spriteSurface); threadContainer.clear(); threads_ready = 0; for (int i = 0; i < number_of_threads; i++) { boost::thread surfaceMerger(mergeTwoSurfaces, lovely_perlin, placeHolder, spriteSurface, 0.5f, true, i*work_per_thread, (i+1)*work_per_thread, 0, h); boost::thread* threadPtr = &surfaceMerger; threadContainer.push_back(threadPtr); } fprintf(stderr, "Waiting for threads to finish combining surfaces\n"); while (threads_ready < number_of_threads) { } fprintf(stderr, "Joining threads\n"); for (iter = threadContainer.begin(); iter != threadContainer.end(); iter++) { (*iter)->join(); } SDL_UnlockSurface(spriteSurface); regenerateTexture(); render(); SDL_GL_SwapBuffers(); SDL_LockSurface(spriteSurface); threadContainer.clear(); threads_ready = 0; for (int i = 0; i < number_of_threads; i++) { boost::thread blurrer(blurSurface, lovely_perlin, 8, 8, i*work_per_thread, (i+1)*work_per_thread, 0, h); boost::thread* threadPtr = &blurrer; threadContainer.push_back(threadPtr); } fprintf(stderr, "Waiting for threads to finish blurring\n"); while (threads_ready < number_of_threads) { } for (iter = threadContainer.begin(); iter != threadContainer.end(); iter++) { (*iter)->join(); } // Now that we have the first perlin noise, let's use that as a general global height map // Time to add sea level SDL_Color blue; blue.r = 255; // What the eff is this anyway? I want blue, not red. blue.g = 0; blue.b = 0; lovely_perlin = filterMap(lovely_perlin, blue, 140); spriteSurface = lovely_perlin; SDL_UnlockSurface(spriteSurface); regenerateTexture(); render(); SDL_GL_SwapBuffers(); SDL_LockSurface(spriteSurface); /* SDL_Surface* dark_and_messy = generatePerlinNoise(base, 2); SDL_UnlockSurface(spriteSurface); spriteSurface = dark_and_messy; regenerateTexture(); render(); SDL_GL_SwapBuffers(); SDL_LockSurface(spriteSurface); fprintf(stderr, "Blurring\n"); threads_ready = 0; // Blur the messy surface for (int i = 0; i < number_of_threads; i++) { boost::thread blurrer(blurSurface, dark_and_messy, 3, 3, i*work_per_thread, (i+1)*work_per_thread, 0, h); boost::thread* threadPtr = &blurrer; threadContainer.push_back(threadPtr); } fprintf(stderr, "Waiting for threads to finish blurring\n"); while (threads_ready < number_of_threads) { } for (iter = threadContainer.begin(); iter != threadContainer.end(); iter++) { (*iter)->join(); } spriteSurface = dark_and_messy; SDL_UnlockSurface(spriteSurface); regenerateTexture(); render(); SDL_GL_SwapBuffers(); SDL_LockSurface(spriteSurface); surfaceVector.push_back(lovely_perlin); surfaceVector.push_back(dark_and_messy); threadContainer.clear(); threads_ready = 0; for (int i = 0; i < number_of_threads; i++) { boost::thread surfaceMerger(mergeTwoSurfaces, lovely_perlin, dark_and_messy, spriteSurface, 0.8f, true, i*work_per_thread, (i+1)*work_per_thread, 0, h); boost::thread* threadPtr = &surfaceMerger; threadContainer.push_back(threadPtr); } fprintf(stderr, "Waiting for threads to finish combining surfaces\n"); while (threads_ready < number_of_threads) { } fprintf(stderr, "Joining threads\n"); for (iter = threadContainer.begin(); iter != threadContainer.end(); iter++) { (*iter)->join(); } SDL_UnlockSurface(spriteSurface); regenerateTexture(); */ }