void Alaska::calculate_ho() { double horizontal[2]; double root_of_phillips; double gauss_value[2];// this is where gauss generator returns two random values for (int i=0;i<NX;i++) { for (int j=0;j<NY;j++) { // hold_horizontal saves these fixed calculations for later use:k[2],klen,klen*klen horizontal[0]=hold_horizontal[i][j][0]=2.0*PI*((double)i-.5*NX)/MAX_WORLD_X;// center the origin horizontal[1]=hold_horizontal[i][j][1]=2.0*PI*((double)j-.5*NX)/MAX_WORLD_Y;// center the origin hold_horizontal[i][j][3]=hold_horizontal[i][j][0]*hold_horizontal[i][j][0]+hold_horizontal[i][j][1]*hold_horizontal[i][j][1]; hold_horizontal[i][j][2]=sqrt(hold_horizontal[i][j][3]); // horizontal[0]=hold_horizontal[i][j][0]=2.0*PI*((float)i-.5*NX)/MAX_WORLD_X; // horizontal[1]=hold_horizontal[i][j][1]=2.0*PI*((float)j-.5*NX)/MAX_WORLD_Y; gauss(gauss_value); root_of_phillips=sqrt(phillips(a_global,horizontal,wind_global)); mH0[i][j].real=INV_SQRT_TWO*gauss_value[0]*root_of_phillips; mH0[i][j].imag=INV_SQRT_TWO*gauss_value[1]*root_of_phillips; } } }
// Generate base heightfield in frequency space void generate_h0() { for (unsigned int y = 0; y<fftInputH; y++) { for (unsigned int x = 0; x<fftInputW; x++) { float kx = CUDART_PI_F * x / (float) patchSize; float ky = 2.0f * CUDART_PI_F * y / (float) patchSize; // note - these random numbers should be from a Gaussian distribution really float Er = 2.0f * rand() / (float) RAND_MAX - 1.0f; float Ei = 2.0f * rand() / (float) RAND_MAX - 1.0f; float P = sqrt(phillips(kx, ky, windDir, windSpeed, A)); float h0_re = 1.0f / sqrtf(2.0f) * Er * P; float h0_im = 1.0f / sqrtf(2.0f) * Ei * P; int i = y*fftInputW+x; h_h0[i].x = h0_re; h_h0[i].y = h0_im; } } }
GLFFTWater::GLFFTWater(GLFFTWaterParams ¶ms) { #ifdef _WIN32 m_h = (float *)__mingw_aligned_malloc((sizeof(float)*(params.N+2)*(params.N)), 4); m_dx = (float *)__mingw_aligned_malloc((sizeof(float)*(params.N+2)*(params.N)), 4); m_dz = (float *)__mingw_aligned_malloc((sizeof(float)*(params.N+2)*(params.N)), 4); m_w = (float *)__mingw_aligned_malloc((sizeof(float)*(params.N)*(params.N)), 4); #else posix_memalign((void **)&m_h,4,sizeof(float)*(params.N+2)*(params.N)); posix_memalign((void **)&m_dx,4,sizeof(float)*(params.N+2)*(params.N)); posix_memalign((void **)&m_dz,4,sizeof(float)*(params.N+2)*(params.N)); posix_memalign((void **)&m_w,4,sizeof(float)*(params.N)*(params.N)); #endif m_htilde0 = (fftwf_complex *)fftwf_malloc(sizeof(fftwf_complex)*(params.N)*(params.N)); m_heightmap = new float3[(params.N)*(params.N)]; m_params = params; std::tr1::mt19937 prng(1337); std::tr1::normal_distribution<float> normal; std::tr1::uniform_real<float> uniform; std::tr1::variate_generator<std::tr1::mt19937, std::tr1::normal_distribution<float> > randn(prng,normal); std::tr1::variate_generator<std::tr1::mt19937, std::tr1::uniform_real<float> > randu(prng,uniform); for(int i=0, k=0; i<params.N; i++) { float k_x = (-(params.N-1)*0.5f+i)*(2.f*3.141592654f / params.L); for(int j=0; j<params.N; j++, k++) { float k_y = (-(params.N-1)*0.5f+j)*(2.f*3.141592654f / params.L); float A = randn(); float theta = randu()*2.f*3.141592654f; float P = (k_x==0.f && k_y==0.0f) ? 0.f : sqrtf(phillips(k_x,k_y,m_w[k])); m_htilde0[k][0] = m_htilde0[k][1] = P*A*sinf(theta); } } m_kz = new float[params.N*(params.N / 2 + 1)]; m_kx = new float[params.N*(params.N / 2 + 1)]; const int hN = m_params.N / 2; for(int y=0; y<m_params.N; y++) { float kz = (float) (y - hN); for(int x=0; x<=hN; x++) { float kx = (float) (x - hN); float k = 1.f/sqrtf(kx*kx+kz*kz); m_kz[y*(hN+1)+x] = kz*k; m_kx[y*(hN+1)+x] = kx*k; } } if(!fftwf_init_threads()) { cerr << "Error initializing multithreaded fft." << endl; } else { fftwf_plan_with_nthreads(2); } m_fftplan = fftwf_plan_dft_c2r_2d(m_params.N, m_params.N, (fftwf_complex *)m_h, m_h, FFTW_ESTIMATE); glGenTextures(1, &m_texId); glBindTexture(GL_TEXTURE_2D, m_texId); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, params.N, params.N, 0, GL_RGB, GL_FLOAT, 0); glBindTexture(GL_TEXTURE_2D, 0); }