/* load and split image into OpenGL cubemap, faceOrder takes 1 character for order to load in for example "ESWNUP" = East South West North Up Down */ GLuint LoadCubeMap(std::string file_location, std::string faceOrder) { GLuint tex_cube = SOIL_load_OGL_single_cubemap ( file_location.c_str(), faceOrder.c_str(), SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS ); if(tex_cube == 0) { std::cout << "Error loading cubemap" << std::endl; return 0; } else { return tex_cube; } }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wcex; HWND hwnd; HDC hDC; HGLRC hRC; MSG msg; BOOL bQuit = FALSE; float theta = 0.0f; // register window class wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_OWNDC; wcex.lpfnWndProc = WindowProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wcex.lpszMenuName = NULL; wcex.lpszClassName = "GLSample"; wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx(&wcex)) return 0; // create main window hwnd = CreateWindowEx(0, "GLSample", "SOIL Sample", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 512, 512, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, nCmdShow); // check my error handling /* SOIL_load_OGL_texture( "img_test.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, 0 ); std::cout << "'" << SOIL_last_result() << "'" << std::endl; */ // enable OpenGL for the window EnableOpenGL(hwnd, &hDC, &hRC); glEnable( GL_BLEND ); //glDisable( GL_BLEND ); // straight alpha glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); // premultiplied alpha (remember to do the same in glColor!!) //glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA ); // do I want alpha thresholding? glEnable( GL_ALPHA_TEST ); glAlphaFunc( GL_GREATER, 0.5f ); // log what the use is asking us to load std::string load_me = lpCmdLine; if( load_me.length() > 2 ) { //load_me = load_me.substr( 1, load_me.length() - 2 ); load_me = load_me.substr( 0, load_me.length() - 0 ); } else { //load_me = "img_test_uncompressed.dds"; //load_me = "img_test_indexed.tga"; //load_me = "img_test.dds"; load_me = "img_test.png"; //load_me = "odd_size.jpg"; //load_me = "img_cheryl.jpg"; //load_me = "oak_odd.png"; //load_me = "field_128_cube.dds"; //load_me = "field_128_cube_nomip.dds"; //load_me = "field_128_cube_uc.dds"; //load_me = "field_128_cube_uc_nomip.dds"; //load_me = "Goblin.dds"; //load_me = "parquet.dds"; //load_me = "stpeters_probe.hdr"; //load_me = "VeraMoBI_sdf.png"; // for testing the texture rectangle code //load_me = "test_rect.png"; } std::cout << "'" << load_me << "'" << std::endl; // 1st try to load it as a single-image-cubemap // (note, need DDS ordered faces: "EWUDNS") GLuint tex_ID; int time_me; std::cout << "Attempting to load as a cubemap" << std::endl; time_me = clock(); tex_ID = SOIL_load_OGL_single_cubemap( load_me.c_str(), SOIL_DDS_CUBEMAP_FACE_ORDER, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS //| SOIL_FLAG_COMPRESS_TO_DXT //| SOIL_FLAG_TEXTURE_REPEATS //| SOIL_FLAG_INVERT_Y | SOIL_FLAG_DDS_LOAD_DIRECT ); time_me = clock() - time_me; std::cout << "the load time was " << 0.001f * time_me << " seconds (warning: low resolution timer)" << std::endl; if( tex_ID > 0 ) { glEnable( GL_TEXTURE_CUBE_MAP ); glEnable( GL_TEXTURE_GEN_S ); glEnable( GL_TEXTURE_GEN_T ); glEnable( GL_TEXTURE_GEN_R ); glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP ); glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP ); glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP ); glBindTexture( GL_TEXTURE_CUBE_MAP, tex_ID ); // report std::cout << "the loaded single cube map ID was " << tex_ID << std::endl; //std::cout << "the load time was " << 0.001f * time_me << " seconds (warning: low resolution timer)" << std::endl; } else { std::cout << "Attempting to load as a HDR texture" << std::endl; time_me = clock(); tex_ID = SOIL_load_OGL_HDR_texture( load_me.c_str(), //SOIL_HDR_RGBE, //SOIL_HDR_RGBdivA, SOIL_HDR_RGBdivA2, 0, SOIL_CREATE_NEW_ID, SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS //| SOIL_FLAG_COMPRESS_TO_DXT ); time_me = clock() - time_me; std::cout << "the load time was " << 0.001f * time_me << " seconds (warning: low resolution timer)" << std::endl; // did I fail? if( tex_ID < 1 ) { // loading of the single-image-cubemap failed, try it as a simple texture std::cout << "Attempting to load as a simple 2D texture" << std::endl; // load the texture, if specified time_me = clock(); tex_ID = SOIL_load_OGL_texture( load_me.c_str(), SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS //| SOIL_FLAG_MULTIPLY_ALPHA //| SOIL_FLAG_COMPRESS_TO_DXT | SOIL_FLAG_DDS_LOAD_DIRECT //| SOIL_FLAG_NTSC_SAFE_RGB //| SOIL_FLAG_CoCg_Y //| SOIL_FLAG_TEXTURE_RECTANGLE ); time_me = clock() - time_me; std::cout << "the load time was " << 0.001f * time_me << " seconds (warning: low resolution timer)" << std::endl; } if( tex_ID > 0 ) { // enable texturing glEnable( GL_TEXTURE_2D ); //glEnable( 0x84F5 );// enables texture rectangle // bind an OpenGL texture ID glBindTexture( GL_TEXTURE_2D, tex_ID ); // report std::cout << "the loaded texture ID was " << tex_ID << std::endl; //std::cout << "the load time was " << 0.001f * time_me << " seconds (warning: low resolution timer)" << std::endl; } else { // loading of the texture failed...why? glDisable( GL_TEXTURE_2D ); std::cout << "Texture loading failed: '" << SOIL_last_result() << "'" << std::endl; } } // program main loop const float ref_mag = 0.1f; while (!bQuit) { // check for messages if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // handle or dispatch messages if (msg.message == WM_QUIT) { bQuit = TRUE; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } else { // OpenGL animation code goes here theta = clock() * 0.1; float tex_u_max = 1.0f;//0.2f; float tex_v_max = 1.0f;//0.2f; glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glScalef( 0.8f, 0.8f, 0.8f ); //glRotatef(-0.314159f*theta, 0.0f, 0.0f, 1.0f); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glNormal3f( 0.0f, 0.0f, 1.0f ); glBegin(GL_QUADS); glNormal3f( -ref_mag, -ref_mag, 1.0f ); glTexCoord2f( 0.0f, tex_v_max ); glVertex3f( -1.0f, -1.0f, -0.1f ); glNormal3f( ref_mag, -ref_mag, 1.0f ); glTexCoord2f( tex_u_max, tex_v_max ); glVertex3f( 1.0f, -1.0f, -0.1f ); glNormal3f( ref_mag, ref_mag, 1.0f ); glTexCoord2f( tex_u_max, 0.0f ); glVertex3f( 1.0f, 1.0f, -0.1f ); glNormal3f( -ref_mag, ref_mag, 1.0f ); glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, 1.0f, -0.1f ); glEnd(); glPopMatrix(); tex_u_max = 1.0f; tex_v_max = 1.0f; glPushMatrix(); glScalef( 0.8f, 0.8f, 0.8f ); glRotatef(theta, 0.0f, 0.0f, 1.0f); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glNormal3f( 0.0f, 0.0f, 1.0f ); glBegin(GL_QUADS); glTexCoord2f( 0.0f, tex_v_max ); glVertex3f( 0.0f, 0.0f, 0.1f ); glTexCoord2f( tex_u_max, tex_v_max ); glVertex3f( 1.0f, 0.0f, 0.1f ); glTexCoord2f( tex_u_max, 0.0f ); glVertex3f( 1.0f, 1.0f, 0.1f ); glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 0.0f, 1.0f, 0.1f ); glEnd(); glPopMatrix(); { /* check for errors */ GLenum err_code = glGetError(); while( GL_NO_ERROR != err_code ) { printf( "OpenGL Error @ %s: %i", "drawing loop", err_code ); err_code = glGetError(); } } SwapBuffers(hDC); Sleep (1); } } // and show off the screenshot capability /* load_me += "-screenshot.tga"; SOIL_save_screenshot( load_me.c_str(), SOIL_SAVE_TYPE_TGA, 0, 0, 512, 512 ); //*/ //* load_me += "-screenshot.bmp"; SOIL_save_screenshot( load_me.c_str(), SOIL_SAVE_TYPE_BMP, 0, 0, 512, 512 ); //*/ /* load_me += "-screenshot.dds"; SOIL_save_screenshot( load_me.c_str(), SOIL_SAVE_TYPE_DDS, 0, 0, 512, 512 ); //*/ // shutdown OpenGL DisableOpenGL(hwnd, hDC, hRC); // destroy the window explicitly DestroyWindow(hwnd); return msg.wParam; }
int main( int argc, char* argv[] ) { GLboolean running; // Initialise SDL2 if( 0 != SDL_Init( SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_EVENTS ) ) { fprintf( stderr, "Failed to initialize SDL2: %s\n", SDL_GetError() ); exit( EXIT_FAILURE ); } // Open OpenGL window SDL_Window * window = SDL_CreateWindow( "SOIL2 Test",SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 512, 512, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN ); if( NULL == window ) { fprintf( stderr, "Failed to open SDL2 window: %s\n", SDL_GetError() ); exit( EXIT_FAILURE ); } SDL_GLContext context = SDL_GL_CreateContext( window ); if ( NULL == context ) { fprintf( stderr, "Failed to create SDL2 OpenGL Context: %s\n", SDL_GetError() ); SDL_DestroyWindow( window ); exit( EXIT_FAILURE ); } SDL_GL_SetSwapInterval( 1 ); SDL_GL_MakeCurrent( window, context ); // log what the use is asking us to load std::string load_me; if ( argc >= 2 ) { load_me = std::string( argv[1] ); } else { load_me = ResourcePath( "img_test.png" ); } std::cout << "'" << load_me << "'" << std::endl; // 1st try to load it as a single-image-cubemap // (note, need DDS ordered faces: "EWUDNS") GLuint tex_ID; Uint64 time_me; std::cout << "Attempting to load as a cubemap" << std::endl; time_me = SDL_GetPerformanceCounter(); tex_ID = SOIL_load_OGL_single_cubemap( load_me.c_str(), SOIL_DDS_CUBEMAP_FACE_ORDER, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_DDS_LOAD_DIRECT | SOIL_FLAG_PVR_LOAD_DIRECT | SOIL_FLAG_ETC1_LOAD_DIRECT ); std::cout << "the load time was " << get_total_ms(time_me) << " milliseconds" << std::endl; if( tex_ID > 0 ) { glEnable( GL_TEXTURE_CUBE_MAP ); glEnable( GL_TEXTURE_GEN_S ); glEnable( GL_TEXTURE_GEN_T ); glEnable( GL_TEXTURE_GEN_R ); glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP ); glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP ); glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP ); glBindTexture( GL_TEXTURE_CUBE_MAP, tex_ID ); std::cout << "the loaded single cube map ID was " << tex_ID << std::endl; } else { std::cout << "Attempting to load as a HDR texture" << std::endl; time_me = SDL_GetPerformanceCounter(); tex_ID = SOIL_load_OGL_HDR_texture( load_me.c_str(), SOIL_HDR_RGBdivA2, 0, SOIL_CREATE_NEW_ID, SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_GL_MIPMAPS ); std::cout << "the load time was " << get_total_ms(time_me) << " milliseconds" << std::endl; // did I fail? if( tex_ID < 1 ) { // loading of the single-image-cubemap failed, try it as a simple texture std::cout << "Attempting to load as a simple 2D texture" << std::endl; // load the texture, if specified time_me = SDL_GetPerformanceCounter(); tex_ID = SOIL_load_OGL_texture( load_me.c_str(), SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS | SOIL_FLAG_GL_MIPMAPS | SOIL_FLAG_DDS_LOAD_DIRECT | SOIL_FLAG_PVR_LOAD_DIRECT | SOIL_FLAG_ETC1_LOAD_DIRECT | SOIL_FLAG_COMPRESS_TO_DXT ); std::cout << "the load time was " << get_total_ms(time_me) << " milliseconds" << std::endl; } if( tex_ID > 0 ) { // enable texturing glEnable( GL_TEXTURE_2D ); // bind an OpenGL texture ID glBindTexture( GL_TEXTURE_2D, tex_ID ); // report std::cout << "the loaded texture ID was " << tex_ID << std::endl; } else { // loading of the texture failed...why? glDisable( GL_TEXTURE_2D ); std::cout << "Texture loading failed: '" << SOIL_last_result() << "'" << std::endl; } } running = GL_TRUE; const float ref_mag = 0.1f; float theta = 0.0f; float tex_u_max = 1.0f; float tex_v_max = 1.0f; Uint64 counterOld = SDL_GetPerformanceCounter(); while( running ) { float dt = (float)((double)(SDL_GetPerformanceCounter() - counterOld) / (double)SDL_GetPerformanceFrequency()); counterOld = SDL_GetPerformanceCounter(); SDL_Event evt; while (SDL_PollEvent(&evt)) { switch (evt.type) { case SDL_QUIT: { running = false; break; } case SDL_KEYUP: { if ( SDLK_ESCAPE == evt.key.keysym.sym ) { running = false; } break; } } } theta += dt * 40; glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); // Draw our textured geometry (just a rectangle in this instance) glPushMatrix(); glScalef( 0.8f, 0.8f, 0.8f ); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glNormal3f( 0.0f, 0.0f, 1.0f ); glBegin(GL_QUADS); glNormal3f( -ref_mag, -ref_mag, 1.0f ); glTexCoord2f( 0.0f, tex_v_max ); glVertex3f( -1.0f, -1.0f, -0.1f ); glNormal3f( ref_mag, -ref_mag, 1.0f ); glTexCoord2f( tex_u_max, tex_v_max ); glVertex3f( 1.0f, -1.0f, -0.1f ); glNormal3f( ref_mag, ref_mag, 1.0f ); glTexCoord2f( tex_u_max, 0.0f ); glVertex3f( 1.0f, 1.0f, -0.1f ); glNormal3f( -ref_mag, ref_mag, 1.0f ); glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -1.0f, 1.0f, -0.1f ); glEnd(); glPopMatrix(); glPushMatrix(); glScalef( 0.8f, 0.8f, 0.8f ); glRotatef(theta, 0.0f, 0.0f, 1.0f); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glNormal3f( 0.0f, 0.0f, 1.0f ); glBegin(GL_QUADS); glTexCoord2f( 0.0f, tex_v_max ); glVertex3f( 0.0f, 0.0f, 0.1f ); glTexCoord2f( tex_u_max, tex_v_max ); glVertex3f( 1.0f, 0.0f, 0.1f ); glTexCoord2f( tex_u_max, 0.0f ); glVertex3f( 1.0f, 1.0f, 0.1f ); glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 0.0f, 1.0f, 0.1f ); glEnd(); glPopMatrix(); // Swap buffers SDL_GL_SwapWindow( window ); } // Close OpenGL window and terminate SDL2 SDL_GL_DeleteContext( context ); SDL_DestroyWindow( window ); exit( EXIT_SUCCESS ); }
OceanSurface::OceanSurface(int N, int M, float L_x, float L_z, float A, glm::vec2 _wind, float g, bool _lines, bool _gpu) : N(N), M(M), L_x(L_x), L_z(L_z), A(A), wind(_wind), g(g), lines(_lines), gpu(_gpu) { grid = new surface_vertex[N * M]; // construct wave height field grid init_positions = new vertex_2d[N * M]; grid_tex_cord = new tex_img_coord[N * N]; h_t0 = new complex_number[N * M]; h_t0_cc = new complex_number[N * M]; h_fft = new complex_number[N * M]; dx_fft = new complex_number[N * M]; dz_fft = new complex_number[N * M]; gradient_x = new complex_number[N * M]; gradient_z = new complex_number[N * M]; lambda = -1.0f; // numeric constant for calculating displacement num_indices = 0; num_triangle_indices = 0; indices = new GLuint[(N - 1) * (M - 1) * 6 + 2 * (N + M - 2)]; triangle_indices = new GLuint[(N - 1) * (M - 1) * 6 * 10]; if (gpu) { wind = glm::vec2(wind.y, wind.x); } //fft myFFT = new MyFFT(N, M); // compute shader FFT stuff char *s_name = "compute_shaders/fft_compute.glsl"; if (N == 32) { s_name = "compute_shaders/fft_compute_32.glsl"; } if (N == 64) { s_name = "compute_shaders/fft_compute_64.glsl"; } if (N == 128) { s_name = "compute_shaders/fft_compute_128.glsl"; } if (N == 256) { s_name = "compute_shaders/fft_compute_256.glsl"; } if (N == 512) { s_name = "compute_shaders/fft_compute_512.glsl"; } fft_comp_program = create_comp_program_from_file(s_name); int bits = log2(N * 1.0f); calc_binary_reverse(bits); glGenBuffers(1, &rev_ind_buffer); glBindBuffer(GL_SHADER_STORAGE_BUFFER, rev_ind_buffer); glBufferData(GL_SHADER_STORAGE_BUFFER, N * sizeof(int), binary_reverse, GL_STATIC_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); GLint steps_location = glGetUniformLocation(fft_comp_program, "steps"); fft_column_location = glGetUniformLocation(fft_comp_program, "fft_column"); glUseProgram(fft_comp_program); glUniform1i(steps_location, bits); // texture for inpute height map glGenTextures(1, &texture_H_t); glBindTexture(GL_TEXTURE_2D, texture_H_t); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RG32F, N, N, 0, GL_RG, GL_FLOAT, 0); /*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/ // texture for output height map per rows glGenTextures(1, &texture_H_fft_t_row); glBindTexture(GL_TEXTURE_2D, texture_H_fft_t_row); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); /*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/ // texture for output height map per columns glGenTextures(1, &texture_H_fft_t_col); glBindTexture(GL_TEXTURE_2D, texture_H_fft_t_col); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); /*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/ // texture for fft dx glGenTextures(1, &tex_dx_fft_row); glBindTexture(GL_TEXTURE_2D, tex_dx_fft_row); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); glGenTextures(1, &tex_dx_fft); glBindTexture(GL_TEXTURE_2D, tex_dx_fft); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); // texture for fft dz glGenTextures(1, &tex_dz_fft_row); glBindTexture(GL_TEXTURE_2D, tex_dz_fft_row); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); glGenTextures(1, &tex_dz_fft); glBindTexture(GL_TEXTURE_2D, tex_dz_fft); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); // texture for fft gradx glGenTextures(1, &tex_gradx_fft_row); glBindTexture(GL_TEXTURE_2D, tex_gradx_fft_row); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); glGenTextures(1, &tex_gradx_fft); glBindTexture(GL_TEXTURE_2D, tex_gradx_fft); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); // texture for fft gradz glGenTextures(1, &tex_gradz_fft_row); glBindTexture(GL_TEXTURE_2D, tex_gradz_fft_row); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); glGenTextures(1, &tex_gradz_fft); glBindTexture(GL_TEXTURE_2D, tex_gradz_fft); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); // unbind all textures glBindTexture(GL_TEXTURE_2D, 0); // assign each point its original 3d coordinates for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) { int pos = i * M + j; // one-dimensional pos from linear two-dimensional grid grid_tex_cord[pos] = tex_img_coord(i, j); // precomputer amplitudes at each point h_t0[pos] = h_t_0(i, j); h_t0_cc[pos] = h_t_0(-i, -j).cc(); // we project our N*M grid coordinates to real world L_x*L_z coordinates grid[pos].x = (i - (N >> 1)) * L_x / N; grid[pos].y = 0.0f; // height is 0 grid[pos].z = (j - (M >> 1)) * L_z / M; // save initial positions init_positions[pos].x = grid[pos].x; init_positions[pos].z = grid[pos].z; // construct indices for index drawing if (i != N - 1 && j != M - 1) { indices[num_indices++] = pos; indices[num_indices++] = pos + 1; indices[num_indices++] = pos; indices[num_indices++] = pos + M; indices[num_indices++] = pos; indices[num_indices++] = pos + M + 1; } if (i != N - 1 && j == M - 1) { indices[num_indices++] = pos; indices[num_indices++] = pos + M; } if (i == N - 1 && j != M - 1) { indices[num_indices++] = pos; indices[num_indices++] = pos + 1; } // construct indices for triangle index drawing if (i != N - 1 && j != M - 1) { triangle_indices[num_triangle_indices++] = pos; triangle_indices[num_triangle_indices++] = pos + N + 1; triangle_indices[num_triangle_indices++] = pos + 1; triangle_indices[num_triangle_indices++] = pos; triangle_indices[num_triangle_indices++] = pos + N; triangle_indices[num_triangle_indices++] = pos + N + 1; } } // check that its okay assert(num_indices == (N - 1) * (M - 1) * 6 + 2 * (N + M - 2)); //assert(num_triangle_indices, (N - 1) * (M - 1) * 6); prepare_for_pipeline(); // update height map compute shader program upd_height_program = create_comp_program_from_file("compute_shaders/update_height_map.glsl"); GLint len_location = glGetUniformLocation(upd_height_program, "L");; GLint n_location = glGetUniformLocation(upd_height_program, "N"); total_time_location = glGetUniformLocation(upd_height_program, "totalTime"); glUseProgram(upd_height_program); glUniform1f(len_location, L_x); glUniform1i(n_location, N); glUseProgram(0); // height map textures glGenTextures(1, &texture_H_t0); glGenTextures(1, &texture_H_t0_cc); glBindTexture(GL_TEXTURE_2D, texture_H_t0); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, N, N, GL_RG, GL_FLOAT, h_t0); glBindTexture(GL_TEXTURE_2D, texture_H_t0_cc); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, N, N, GL_RG, GL_FLOAT, h_t0_cc); glBindTexture(GL_TEXTURE_2D, 0); // displacement map textures glGenTextures(1, &texture_Dx); glGenTextures(1, &texture_Dz); glBindTexture(GL_TEXTURE_2D, texture_Dx); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); glBindTexture(GL_TEXTURE_2D, texture_Dz); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); glBindTexture(GL_TEXTURE_2D, 0); // gradient map textures glGenTextures(1, &texture_Gradx); glGenTextures(1, &texture_Gradz); glBindTexture(GL_TEXTURE_2D, texture_Gradx); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); glBindTexture(GL_TEXTURE_2D, texture_Gradz); glTexStorage2D(GL_TEXTURE_2D, 1, GL_RG32F, N, N); glBindTexture(GL_TEXTURE_2D, 0); // Fresnel textures int fres_size = 128; float g_SkyBlending = 16.0f; unsigned int *buffer = new unsigned int[fres_size]; for (int i = 0; i < fres_size; i++) { float cos_a = i / (float)fres_size; // Using water's refraction index 1.33 unsigned int fresnel = (unsigned int)(D3DXFresnelTerm(cos_a, 1.33f) * 255); unsigned int sky_blend = (unsigned int)(powf(1 / (1 + cos_a), g_SkyBlending) * 255); buffer[i] = (sky_blend << 8) | fresnel; } glGenTextures(1, &tex_Fresnel); glBindTexture(GL_TEXTURE_1D, tex_Fresnel); glTexStorage1D(GL_TEXTURE_1D, 1, GL_RGBA8, fres_size); glTexSubImage1D(GL_TEXTURE_1D, 0, 0, fres_size, GL_RGBA, GL_UNSIGNED_INT, buffer); const GLfloat border[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glTexParameterfv(GL_TEXTURE_1D, GL_TEXTURE_BORDER_COLOR, border); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_COMPARE_FUNC, GL_NEVER); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glBindTexture(GL_TEXTURE_1D, 0); delete[] buffer; // Reflect cube textures tex_ReflectCube = SOIL_load_OGL_single_cubemap ( "textures/sky_cube.dds", SOIL_DDS_CUBEMAP_FACE_ORDER, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_DDS_LOAD_DIRECT ); }