From 0e71905c8bc640361ef95a4776732a96161b6077 Mon Sep 17 00:00:00 2001 From: lhark Date: Sun, 26 Nov 2017 00:46:30 -0500 Subject: [PATCH] Add FBO & Fix microsoft induced compilation errors --- Packets.cpp | 214 +++++++++++++++++++++++++--------------------------- Packets.h | 3 + constants.h | 5 +- inf2705.h | 3 + makefile | 73 +++++++++++------- ripple.cpp | 37 +++++++-- 6 files changed, 190 insertions(+), 145 deletions(-) diff --git a/Packets.cpp b/Packets.cpp index 0cc5ba3..58e57a5 100644 --- a/Packets.cpp +++ b/Packets.cpp @@ -1,16 +1,15 @@ // taken from https://github.com/jeschke/water-wave-packets // Include the OS headers //----------------------- -#include -#include -#include #include #include +#include #include #include #include -#include +#include #include "Packets.h" +#include "util.h" #pragma warning( disable: 4996 ) @@ -40,10 +39,10 @@ float Packets::GetIntersectionDistance(Vector2f pos1, Vector2f dir1, Vector2f po inline float Packets::GetGroundVal(Vector2f &p) { Vector2f pTex = Vector2f(p.x()/SCENE_EXTENT+0.5f,p.y()/SCENE_EXTENT+0.5f); // convert from world space to texture space - float val1 = m_ground[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; - float val2 = m_ground[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; - float val3 = m_ground[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; - float val4 = m_ground[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; + float val1 = m_ground[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; + float val2 = m_ground[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; + float val3 = m_ground[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; + float val4 = m_ground[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; float xOffs = (pTex.x()*m_groundSizeX) - (int)(pTex.x()*m_groundSizeX); float yOffs = (pTex.y()*m_groundSizeY) - (int)(pTex.y()*m_groundSizeY); float valH1 = (1.0f-xOffs)*val1 + xOffs*val2; @@ -54,10 +53,10 @@ inline float Packets::GetGroundVal(Vector2f &p) inline Vector2f Packets::GetGroundNormal(Vector2f &p) { Vector2f pTex = Vector2f(p.x()/SCENE_EXTENT+0.5f,p.y()/SCENE_EXTENT+0.5f); // convert from world space to texture space - Vector2f val1 = m_gndDeriv[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; - Vector2f val2 = m_gndDeriv[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; - Vector2f val3 = m_gndDeriv[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; - Vector2f val4 = m_gndDeriv[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; + Vector2f val1 = m_gndDeriv[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; + Vector2f val2 = m_gndDeriv[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; + Vector2f val3 = m_gndDeriv[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; + Vector2f val4 = m_gndDeriv[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; float xOffs = (pTex.x()*m_groundSizeX) - (int)(pTex.x()*m_groundSizeX); float yOffs = (pTex.y()*m_groundSizeY) - (int)(pTex.y()*m_groundSizeY); Vector2f valH1 = (1.0f-xOffs)*val1 + xOffs*val2; @@ -72,10 +71,10 @@ inline Vector2f Packets::GetGroundNormal(Vector2f &p) inline float Packets::GetBoundaryDist(Vector2f &p) { Vector2f pTex = Vector2f(p.x()/SCENE_EXTENT+0.5f,p.y()/SCENE_EXTENT+0.5f); // convert from world space to texture space - float val1 = m_distMap[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; - float val2 = m_distMap[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; - float val3 = m_distMap[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; - float val4 = m_distMap[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; + float val1 = m_distMap[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; + float val2 = m_distMap[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; + float val3 = m_distMap[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; + float val4 = m_distMap[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; float xOffs = (pTex.x()*m_groundSizeX) - (int)(pTex.x()*m_groundSizeX); float yOffs = (pTex.y()*m_groundSizeY) - (int)(pTex.y()*m_groundSizeY); float valH1 = (1.0f-xOffs)*val1 + xOffs*val2; @@ -86,10 +85,10 @@ inline float Packets::GetBoundaryDist(Vector2f &p) inline Vector2f Packets::GetBoundaryNormal(Vector2f &p) { Vector2f pTex = Vector2f(p.x()/SCENE_EXTENT+0.5f,p.y()/SCENE_EXTENT+0.5f); // convert from world space to texture space - Vector2f val1 = m_bndDeriv[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; - Vector2f val2 = m_bndDeriv[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; - Vector2f val3 = m_bndDeriv[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; - Vector2f val4 = m_bndDeriv[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; + Vector2f val1 = m_bndDeriv[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; + Vector2f val2 = m_bndDeriv[(int)(max(0,min(m_groundSizeY-1,pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; + Vector2f val3 = m_bndDeriv[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,pTex.x()*m_groundSizeX)))]; + Vector2f val4 = m_bndDeriv[(int)(max(0,min(m_groundSizeY-1,1+pTex.y()*m_groundSizeY)))*m_groundSizeX + (int)(max(0,min(m_groundSizeX-1,1+pTex.x()*m_groundSizeX)))]; float xOffs = (pTex.x()*m_groundSizeX) - (int)(pTex.x()*m_groundSizeX); float yOffs = (pTex.y()*m_groundSizeY) - (int)(pTex.y()*m_groundSizeY); Vector2f valH1 = (1.0f-xOffs)*val1 + xOffs*val2; @@ -108,42 +107,43 @@ inline Vector2f Packets::GetBoundaryNormal(Vector2f &p) #pragma warning( disable : 4996) Packets::Packets(int packetBudget) { - WCHAR wcInfo[512]; - //load ground/boundary texture for CPU processing - LPCWSTR groundTexFile = WATER_TERRAIN_FILE; - tagBITMAPFILEHEADER bmpheader; - tagBITMAPINFOHEADER bmpinfo; - DWORD bytesread; - HANDLE file = CreateFile( groundTexFile , GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL ); - if (file == NULL) - { - throw std::exception("Media file not found"); - return; + char groundTexFile[] = WATER_TERRAIN_FILE; + + /* https://stackoverflow.com/questions/9296059/read-pixel-value-in-bmp-file */ + /* TODO Test bitmap reader implementation */ + int i; + FILE* f = fopen(groundTexFile, "rb"); + unsigned char info[54]; + + if (!f) { + die("Can't open terrain file"); } - if ( (ReadFile ( file, &bmpheader, sizeof ( BITMAPFILEHEADER ), &bytesread, NULL ) == false) - || (ReadFile(file, &bmpinfo, sizeof(BITMAPINFOHEADER), &bytesread, NULL) == false) - || (bmpheader.bfType != 'MB') - || (bmpinfo.biCompression != BI_RGB) - || (bmpinfo.biBitCount != 24) ) - { - CloseHandle ( file ); - throw std::exception("Error reading media file"); - return; + fread(info, sizeof(unsigned char), 54, f); // read the 54-byte header + + // extract image height and width from header + auto fileSize = *reinterpret_cast(&info[2]); + auto dataOffset = *reinterpret_cast(&info[10]); + auto width = *reinterpret_cast(&info[18]); + auto height = *reinterpret_cast(&info[22]); + auto depth = *reinterpret_cast(&info[28]); + + if (info[0] != 'B' || info[1] != 'M') { + fclose(f); + die("Incorrect bitmap header will loading terrain file"); } - m_groundSizeX = abs(bmpinfo.biWidth); - m_groundSizeY = abs(bmpinfo.biHeight); - long size = bmpheader.bfSize-bmpheader.bfOffBits; - SetFilePointer ( file, bmpheader.bfOffBits, NULL, FILE_BEGIN ); - BYTE* Buffer = new BYTE[size]; - if ( ReadFile ( file, Buffer, size, &bytesread, NULL ) == false ) - { - delete[](Buffer); - CloseHandle(file); - throw std::exception("Media file not found"); - return; + if (depth != 24) { + fclose(f); + die("Incorrect color depth for terrain file"); } - CloseHandle(file); + + m_groundSizeX = abs(width); + m_groundSizeY = abs(height); + long size = fileSize - dataOffset; + unsigned char* Buffer = new unsigned char[size]; // allocate 3 bytes per pixel + fread(Buffer, sizeof(unsigned char), size, f); // read the rest of the data at once + fclose(f); + // convert read buffer to our rgb datastructure int padding = 0; int scanlinebytes = m_groundSizeX*3; @@ -167,8 +167,7 @@ Packets::Packets(int packetBudget) // boundary texture distance transform // init helper distance map (pMap) - StringCchPrintf(wcInfo, 512, L"Computing boundary distance transform.."); - OutputDebugString(wcInfo); + printf("Computing boundary distance transform.."); int *pMap = new int[m_groundSizeX*m_groundSizeY]; #pragma omp parallel for for (int y = 0; y < m_groundSizeY; y++) @@ -176,16 +175,16 @@ Packets::Packets(int packetBudget) { // if we are at the boundary, intialize the distance function with 0, otherwise with maximum value if ((bound[y*m_groundSizeX + x] > 0.5f) && - ((bound[max(0, min(m_groundSizeY - 1, y + 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] <= 0.5f) - || (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 1))] <= 0.5f) - || (bound[max(0, min(m_groundSizeY - 1, y - 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] <= 0.5f) - || (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x - 1))] <= 0.5f))) + ((bound[max(0, min(m_groundSizeY - 1, y + 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] <= 0.5f) + || (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 1))] <= 0.5f) + || (bound[max(0, min(m_groundSizeY - 1, y - 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] <= 0.5f) + || (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x - 1))] <= 0.5f))) pMap[y*m_groundSizeX + x] = 0; // initialize with maximum x distance else if ((bound[y*m_groundSizeX + x] <= 0.5f) && - ((bound[max(0, min(m_groundSizeY - 1, y + 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] > 0.5f) - || (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 1))] > 0.5f) - || (bound[max(0, min(m_groundSizeY - 1, y - 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] > 0.5f) - || (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x - 1))] > 0.5f))) + ((bound[max(0, min(m_groundSizeY - 1, y + 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] > 0.5f) + || (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 1))] > 0.5f) + || (bound[max(0, min(m_groundSizeY - 1, y - 1))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x + 0))] > 0.5f) + || (bound[max(0, min(m_groundSizeY - 1, y + 0))*m_groundSizeX + max(0, min(m_groundSizeX - 1, x - 1))] > 0.5f))) pMap[y*m_groundSizeX + x] = 0; // initialize with maximum x distance else pMap[y*m_groundSizeX + x] = m_groundSizeX*m_groundSizeX; // initialize with maximum x distance @@ -203,7 +202,7 @@ Packets::Packets(int packetBudget) { if (pMap[y*m_groundSizeX+x] == 0) lastBoundX = x; - pMap[y*m_groundSizeX+x] = min(pMap[y*m_groundSizeX+x], (x-lastBoundX)*(x-lastBoundX)); + pMap[y*m_groundSizeX+x] = min(pMap[y*m_groundSizeX+x], (x-lastBoundX)*(x-lastBoundX)); } } #pragma omp parallel for @@ -214,7 +213,7 @@ Packets::Packets(int packetBudget) { if (pMap[y*m_groundSizeX+x] == 0) lastBoundX = x; - pMap[y*m_groundSizeX+x] = min(pMap[y*m_groundSizeX+x], (lastBoundX-x)*(lastBoundX-x)); + pMap[y*m_groundSizeX+x] = min(pMap[y*m_groundSizeX+x], (lastBoundX-x)*(lastBoundX-x)); } } #pragma omp parallel for @@ -224,13 +223,13 @@ Packets::Packets(int packetBudget) int minDist = pMap[y*m_groundSizeX+x]; for (int yd=1; yd+y<=m_groundSizeY-1; yd++) { - minDist = min(minDist, yd*yd+pMap[(y+yd)*m_groundSizeX+x]); + minDist = min(minDist, yd*yd+pMap[(y+yd)*m_groundSizeX+x]); if (minDist < yd*yd) break; } for (int yd=-1; yd+y>=0; yd--) { - minDist = min(minDist, yd*yd+pMap[(y+yd)*m_groundSizeX+x]); + minDist = min(minDist, yd*yd+pMap[(y+yd)*m_groundSizeX+x]); if (minDist < yd*yd) break; } @@ -247,33 +246,29 @@ Packets::Packets(int packetBudget) m_distMap[y*m_groundSizeX+x] = -m_distMap[y*m_groundSizeX+x]; // negative distance INSIDE a boundary regions m_distMap[y*m_groundSizeX+x] = m_distMap[y*m_groundSizeX+x]*SCENE_EXTENT / m_groundSizeX; } - StringCchPrintf(wcInfo, 512, L"done!\n"); - OutputDebugString(wcInfo); + printf("done!\n"); // derivative (2D normal) of the boundary texture - StringCchPrintf( wcInfo, 512, L"Computing boundary derivatives.."); - OutputDebugString( wcInfo ); + printf("Computing boundary derivatives.."); m_bndDeriv = new Vector2f[m_groundSizeX*m_groundSizeY]; #pragma omp parallel for for (int y=0; y(0,min(m_groundSizeX-1,x+1))] - m_distMap[y*m_groundSizeX + x]; + float dy = m_distMap[max(0,min(m_groundSizeY-1,y+1))*m_groundSizeX + x] - m_distMap[y*m_groundSizeX + x]; Vector2f dV = Vector2f(dx,dy); - dx = m_distMap[y*m_groundSizeX + x] - m_distMap[y*m_groundSizeX + max(0,min(m_groundSizeX-1,x-1))]; - dy = m_distMap[y*m_groundSizeX + x] - m_distMap[max(0,min(m_groundSizeY-1,y-1))*m_groundSizeX + x]; + dx = m_distMap[y*m_groundSizeX + x] - m_distMap[y*m_groundSizeX + max(0,min(m_groundSizeX-1,x-1))]; + dy = m_distMap[y*m_groundSizeX + x] - m_distMap[max(0,min(m_groundSizeY-1,y-1))*m_groundSizeX + x]; dV += Vector2f(dx,dy); m_bndDeriv[y*m_groundSizeX+x] = Vector2f(0,0); if ((dV.x() != 0) || (dV.y() != 0)) m_bndDeriv[y*m_groundSizeX+x] = dV.normalized(); } - StringCchPrintf( wcInfo, 512, L"done!\n"); - OutputDebugString( wcInfo ); + printf("done!\n"); //smooth the derivative to avoid staricase artifacts of the texture - StringCchPrintf( wcInfo, 512, L"Smoothing boundary derivatives.."); - OutputDebugString( wcInfo ); + printf("Smoothing boundary derivatives.."); Vector2f *m_bndDerivH = new Vector2f[m_groundSizeX*m_groundSizeY]; for (int i=0; i<2; i++) //15 { @@ -290,7 +285,7 @@ Packets::Packets(int packetBudget) w = 4.0/16.0; else if ((abs(dy) == 0) || (abs(dx) == 0)) w = 2.0/16.0; - dV += w*m_bndDeriv[max(0,min(m_groundSizeY-1,y+dy))*m_groundSizeX + max(0,min(m_groundSizeX-1,x+dx))]; + dV += w*m_bndDeriv[max(0,min(m_groundSizeY-1,y+dy))*m_groundSizeX + max(0,min(m_groundSizeX-1,x+dx))]; } if ((dV.x() != 0) || (dV.y() != 0)) m_bndDerivH[y*m_groundSizeX+x] = dV.normalized(); @@ -299,29 +294,26 @@ Packets::Packets(int packetBudget) memcpy(m_bndDeriv, m_bndDerivH, sizeof(Vector2f)*m_groundSizeX*m_groundSizeY); } delete[](m_bndDerivH); - StringCchPrintf( wcInfo, 512, L"done!\n"); - OutputDebugString( wcInfo ); + printf("done!\n"); // derivative (2D normal) of the ground texture - StringCchPrintf( wcInfo, 512, L"Computing ground derivatives.."); - OutputDebugString( wcInfo ); + printf("Computing ground derivatives.."); m_gndDeriv = new Vector2f[m_groundSizeX*m_groundSizeY]; #pragma omp parallel for for (int y=0; y(0,min(m_groundSizeX-1,x+1))] - m_ground[y*m_groundSizeX + x]; + float dy = m_ground[max(0,min(m_groundSizeY-1,y+1))*m_groundSizeX + x] - m_ground[y*m_groundSizeX + x]; Vector2f dV = Vector2f(dx,dy); - dx = m_ground[y*m_groundSizeX + x] - m_ground[y*m_groundSizeX + max(0,min(m_groundSizeX-1,x-1))]; - dy = m_ground[y*m_groundSizeX + x] - m_ground[max(0,min(m_groundSizeY-1,y-1))*m_groundSizeX + x]; + dx = m_ground[y*m_groundSizeX + x] - m_ground[y*m_groundSizeX + max(0,min(m_groundSizeX-1,x-1))]; + dy = m_ground[y*m_groundSizeX + x] - m_ground[max(0,min(m_groundSizeY-1,y-1))*m_groundSizeX + x]; dV += Vector2f(dx,dy); m_gndDeriv[y*m_groundSizeX+x] = Vector2f(0,0); if ((dV.x() != 0) || (dV.y() != 0)) m_gndDeriv[y*m_groundSizeX+x] = dV.normalized(); } - StringCchPrintf( wcInfo, 512, L"done!\n"); - OutputDebugString( wcInfo ); + printf("done!\n"); // init variables m_packetBudget = packetBudget; @@ -381,9 +373,7 @@ void Packets::ExpandWavePacketMemory(int targetNum) { if (targetNum < m_packetNum) // this should never happen return; - WCHAR wcFileInfo[512]; - StringCchPrintf(wcFileInfo, 512, L"(INFO): Expanding packet memory from %i to %i packets (%i MB).\n", m_packetNum, targetNum, (targetNum)*(sizeof(WAVE_PACKET) + sizeof(GHOST_PACKET) + 4 * sizeof(int)) / (1024 * 1024)); - OutputDebugString(wcFileInfo); + printf("(INFO): Expanding packet memory from %i to %i packets (%i MB).\n", m_packetNum, targetNum, (targetNum)*(sizeof(WAVE_PACKET) + sizeof(GHOST_PACKET) + 4 * sizeof(int)) / (1024 * 1024)); WAVE_PACKET *p = new WAVE_PACKET[targetNum]; GHOST_PACKET *pG = new GHOST_PACKET[targetNum]; int *uP = new int[targetNum]; @@ -487,8 +477,8 @@ void Packets::DeleteGhost(int id) void Packets::CreatePacket(float pos1x, float pos1y, float pos2x, float pos2y, float dir1x, float dir1y, float dir2x, float dir2y, float k_L, float k_H, float E) { // make sure we have enough memory - if ( max(m_usedPackets, m_usedGhosts) + 10 > m_packetNum) - ExpandWavePacketMemory(max(m_usedPackets,m_usedGhosts) + PACKET_BUFFER_DELTA); + if ( max(m_usedPackets, m_usedGhosts) + 10 > m_packetNum) + ExpandWavePacketMemory(max(m_usedPackets,m_usedGhosts) + PACKET_BUFFER_DELTA); float speedDummy, kDummy; int firstfree = GetFreePackedID(); m_packet[firstfree].pos1 = Vector2f(pos1x,pos1y); @@ -522,9 +512,9 @@ void Packets::CreatePacket(float pos1x, float pos1y, float pos2x, float pos2y, f m_packet[firstfree].sOld1 = m_packet[firstfree].speed1; GetWaveParameters(GetWaterDepth(m_packet[firstfree].pos2), m_packet[firstfree].w0, m_packet[firstfree].k, kDummy, m_packet[firstfree].speed2); m_packet[firstfree].sOld2 = m_packet[firstfree].speed2; - m_packet[firstfree].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[firstfree].k)); // adjust envelope size to represented wavelength + m_packet[firstfree].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[firstfree].k)); // adjust envelope size to represented wavelength m_packet[firstfree].ampOld = 0.0; - float a1 = min(MAX_SPEEDNESS*2.0f*M_PI / m_packet[firstfree].k, GetWaveAmplitude(m_packet[firstfree].envelope*(m_packet[firstfree].pos1 - m_packet[firstfree].pos2).norm(), m_packet[firstfree].E, m_packet[firstfree].k)); + float a1 = min(MAX_SPEEDNESS*2.0f*M_PI / m_packet[firstfree].k, GetWaveAmplitude(m_packet[firstfree].envelope*(m_packet[firstfree].pos1 - m_packet[firstfree].pos2).norm(), m_packet[firstfree].E, m_packet[firstfree].k)); m_packet[firstfree].dAmp = 0.5f*(m_packet[firstfree].speed1+m_packet[firstfree].speed2)*m_elapsedTime/(PACKET_BLEND_TRAVEL_FACTOR*m_packet[firstfree].envelope)*a1; // Test for wave number splitting -> if the packet interval crosses the slowest waves, divide so that each part has a monotonic speed function (assumed for travel spread/error calculation) @@ -541,9 +531,9 @@ void Packets::CreatePacket(float pos1x, float pos1y, float pos2x, float pos2y, f m_packet[firstfree].k = 0.5f*(m_packet[firstfree].k_L+m_packet[firstfree].k_H); GetWaveParameters(wd, m_packet[firstfree].w0, m_packet[firstfree].k, m_packet[firstfree].k, m_packet[firstfree].speed1); m_packet[firstfree].speed2 = m_packet[firstfree].speed1; - m_packet[firstfree].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[firstfree].k)); // adjust envelope size to represented wavelength + m_packet[firstfree].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[firstfree].k)); // adjust envelope size to represented wavelength m_packet[firstfree].ampOld = 0.0; - a1 = min(MAX_SPEEDNESS*2.0f*M_PI / m_packet[firstfree].k, GetWaveAmplitude(m_packet[firstfree].envelope*(m_packet[firstfree].pos1 - m_packet[firstfree].pos2).norm(), m_packet[firstfree].E, m_packet[firstfree].k)); + a1 = min(MAX_SPEEDNESS*2.0f*M_PI / m_packet[firstfree].k, GetWaveAmplitude(m_packet[firstfree].envelope*(m_packet[firstfree].pos1 - m_packet[firstfree].pos2).norm(), m_packet[firstfree].E, m_packet[firstfree].k)); m_packet[firstfree].dAmp = 0.5f*(m_packet[firstfree].speed1 + m_packet[firstfree].speed2)*m_elapsedTime / (PACKET_BLEND_TRAVEL_FACTOR*m_packet[firstfree].envelope)*a1; // also adjust freq. interval and envelope size of existing wave m_packet[i1].k_H = PACKET_SLOWAVE_K; @@ -553,9 +543,9 @@ void Packets::CreatePacket(float pos1x, float pos1y, float pos2x, float pos2y, f m_packet[i1].k = 0.5f*(m_packet[i1].k_L+m_packet[i1].k_H); GetWaveParameters(wd, m_packet[i1].w0, m_packet[i1].k, m_packet[i1].k, m_packet[i1].speed1); m_packet[i1].speed2 = m_packet[i1].speed1; - m_packet[i1].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[i1].k)); // adjust envelope size to represented wavelength + m_packet[i1].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[i1].k)); // adjust envelope size to represented wavelength m_packet[i1].ampOld = 0.0f; - a1 = min(MAX_SPEEDNESS*2.0f*M_PI / m_packet[i1].k, GetWaveAmplitude(m_packet[i1].envelope*(m_packet[i1].pos1 - m_packet[i1].pos2).norm(), m_packet[i1].E, m_packet[i1].k)); + a1 = min(MAX_SPEEDNESS*2.0f*M_PI / m_packet[i1].k, GetWaveAmplitude(m_packet[i1].envelope*(m_packet[i1].pos1 - m_packet[i1].pos2).norm(), m_packet[i1].E, m_packet[i1].k)); m_packet[i1].dAmp = 0.5f*(m_packet[i1].speed1 + m_packet[i1].speed2)*m_elapsedTime / (PACKET_BLEND_TRAVEL_FACTOR*m_packet[i1].envelope)*a1; } } @@ -591,7 +581,7 @@ void Packets::CreateSpreadingPacket(float xPos, float yPos, float dirx, float di void Packets::CreateCircularWavefront(float xPos, float yPos, float radius, float lambda_L, float lambda_H, float E) { // adapt initial packet crestlength to impact radius and wavelength - float dAng = min(24.0f, 360.0f * ((0.5f*lambda_L + 0.5f*lambda_H)*3.0f) / (2.0f*M_PI*radius)); + float dAng = min(24.0f, 360.0f * ((0.5f*lambda_L + 0.5f*lambda_H)*3.0f) / (2.0f*M_PI*radius)); for (float i = 0; i < 360.0f; i += dAng) CreatePacket( xPos + radius*sin(i*M_PI / 180.0f), yPos + radius*cos(i*M_PI / 180.0f), @@ -687,7 +677,7 @@ bool Packets::AdvectPacketVertex(float elapsedTime, Vector2f &posIn, Vector2f & GetWaveParameters(GetWaterDepth(pNext), w0, kIn, k, speed2); float cos1 = nDir.dot(-dirIn); - float cos2 = sqrt( max(0.0f, 1.0f - (speed2*speed2)/(speed1*speed1)*(1.0f - cos1*cos1) )); + float cos2 = sqrt( max(0.0f, 1.0f - (speed2*speed2)/(speed1*speed1)*(1.0f - cos1*cos1) )); Vector2f nRefrac; if (cos1 <= 0.0f) nRefrac = speed2/speed1*dirIn + (speed2/speed1*cos1 + cos2)*nDir; @@ -867,7 +857,7 @@ void Packets::AdvectWavePackets(float dTime) GetWaveParameters(wd, m_packet[i1].w0_H, m_packet[i1].k_H, m_packet[i1].k_H, dummySpeed); GetWaveParameters(wd, m_packet[i1].w0, 0.5f*(m_packet[i1].k_L+m_packet[i1].k_H), m_packet[i1].k, dummySpeed); m_packet[i1].d_L = 0.0; m_packet[i1].d_H = 0.0; // reset the internally tracked error - m_packet[i1].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[i1].k)); + m_packet[i1].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[i1].k)); } //if both vertices bounced, the reflected wave needs to smoothly reappear if (m_packet[i1].bounced1==m_packet[i1].bounced2) @@ -967,8 +957,8 @@ void Packets::AdvectWavePackets(float dTime) // wavenumber interval subdivision if travel distance between fastest and slowest wave packets differ more than PACKET_SPLIT_DISPERSION x envelope size - if ( max(m_usedGhosts + m_usedPackets, 2*m_usedPackets) > m_packetNum) - ExpandWavePacketMemory(max(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) + PACKET_BUFFER_DELTA); + if ( max(m_usedGhosts + m_usedPackets, 2*m_usedPackets) > m_packetNum) + ExpandWavePacketMemory(max(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) + PACKET_BUFFER_DELTA); #pragma omp parallel for for (int uP = m_usedPackets-1; uP>=0; uP--) if (!m_packet[m_usedPacket[uP]].use3rd) @@ -1016,7 +1006,7 @@ void Packets::AdvectWavePackets(float dTime) float d_All = m_packet[i1].d_L; m_packet[firstfree].d_L = dSL*d_All / (dSH + dSL); m_packet[firstfree].d_H = d_All - m_packet[firstfree].d_L; - m_packet[firstfree].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[firstfree].k)); + m_packet[firstfree].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[firstfree].k)); // set the new upper freq. boundary and representative freq. m_packet[i1].k_L = m_packet[i1].k; m_packet[i1].w0_L = m_packet[i1].w0; @@ -1030,7 +1020,7 @@ void Packets::AdvectWavePackets(float dTime) d_All = m_packet[i1].d_H; m_packet[i1].d_L = dSL*d_All / (dSH + dSL); m_packet[i1].d_H = d_All - m_packet[i1].d_L; - m_packet[i1].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[i1].k)); + m_packet[i1].envelope = min(PACKET_ENVELOPE_MAXSIZE, max(PACKET_ENVELOPE_MINSIZE, PACKET_ENVELOPE_SIZE_FACTOR*2.0f*M_PI/m_packet[i1].k)); // distribute the energy such that both max. wave gradients are equal -> both get the same wave shape m_packet[firstfree].E = abs(m_packet[i1].E)/(1.0f + (m_packet[i1].envelope*m_packet[firstfree].k*m_packet[firstfree].k*(DENSITY*GRAVITY+SIGMA*m_packet[i1].k*m_packet[i1].k))/(m_packet[firstfree].envelope*m_packet[i1].k*m_packet[i1].k*(DENSITY*GRAVITY+SIGMA*m_packet[firstfree].k*m_packet[firstfree].k))); m_packet[i1].E = abs(m_packet[i1].E)-m_packet[firstfree].E; @@ -1046,8 +1036,8 @@ void Packets::AdvectWavePackets(float dTime) // crest-refinement of packets of regular packet (not at any boundary, i.e. having no 3rd vertex) - if (max(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) > m_packetNum) - ExpandWavePacketMemory(max(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) + PACKET_BUFFER_DELTA); + if (max(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) > m_packetNum) + ExpandWavePacketMemory(max(m_usedGhosts + m_usedPackets, 2 * m_usedPackets) + PACKET_BUFFER_DELTA); #pragma omp parallel for for (int uP = m_usedPackets-1; uP>=0; uP--) if (!m_packet[m_usedPacket[uP]].use3rd) @@ -1195,7 +1185,7 @@ void Packets::AdvectWavePackets(float dTime) } // damping, insignificant packet removal (if too low amplitude), reduce energy of steep waves with too high gradient - m_softDampFactor = 1.0f + 100.0f*pow(max(0.0f, (float)(m_usedPackets)/(float)(m_packetBudget) - 1.0f), 2.0f); + m_softDampFactor = 1.0f + 100.0f*pow(max(0.0f, (float)(m_usedPackets)/(float)(m_packetBudget) - 1.0f), 2.0f); #pragma omp parallel for for (int uP = 0; uP < m_usedPackets; uP++) if ((!m_packet[m_usedPacket[uP]].use3rd) && (!m_packet[m_usedPacket[uP]].toDelete)) @@ -1231,7 +1221,7 @@ void Packets::AdvectWavePackets(float dTime) m_packet[i1].E = a1*a1*(area*0.5f*(DENSITY*GRAVITY + SIGMA*k*k)); } } - m_packet[i1].ampOld = min(a1, m_packet[i1].ampOld + m_packet[i1].dAmp); // smoothly increase amplitude from last timestep + m_packet[i1].ampOld = min(a1, m_packet[i1].ampOld + m_packet[i1].dAmp); // smoothly increase amplitude from last timestep // update variables needed for packet display Vector2f posMidNew = 0.5f*(m_packet[i1].pos1 + m_packet[i1].pos2); Vector2f posMidOld = 0.5f*(m_packet[i1].pOld1 + m_packet[i1].pOld2); @@ -1252,7 +1242,7 @@ void Packets::AdvectWavePackets(float dTime) int i1 = m_usedGhost[uG]; m_ghostPacket[i1].pos += m_elapsedTime*m_ghostPacket[i1].speed*m_ghostPacket[i1].dir; m_ghostPacket[i1].phase += m_ghostPacket[i1].dPhase; - m_ghostPacket[i1].ampOld = max(0.0f, m_ghostPacket[i1].ampOld - m_softDampFactor*m_ghostPacket[i1].dAmp); // decrease amplitude to let this wave disappear (take budget-based softdamping into account) + m_ghostPacket[i1].ampOld = max(0.0f, m_ghostPacket[i1].ampOld - m_softDampFactor*m_ghostPacket[i1].dAmp); // decrease amplitude to let this wave disappear (take budget-based softdamping into account) } // delete all ghost packets if they traveled long enough (important: NO parallelization here!) for (int uG = 0; uG < m_usedGhosts; uG++) diff --git a/Packets.h b/Packets.h index 92c62cf..89bc55e 100644 --- a/Packets.h +++ b/Packets.h @@ -4,7 +4,10 @@ #include "constants.h" #include +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wint-in-bool-context" #include +#pragma GCC diagnostic pop using namespace Eigen; using namespace std; diff --git a/constants.h b/constants.h index 1fe4a38..8aba5a6 100644 --- a/constants.h +++ b/constants.h @@ -40,5 +40,6 @@ #define WAVEMESH_HEIGHT_FACTOR 4 // the fine wave mesh compared to screen resolution #define AA_OVERSAMPLE_FACTOR 4 // anti aliasing applied in BOTH X and Y directions {1,2,4,8} - - +// UI consts +#define MAX_PACKET_BUDGET 100000 +#define MIN_PACKET_BUDGET 1000 diff --git a/inf2705.h b/inf2705.h index 55d5fb6..b9e819f 100644 --- a/inf2705.h +++ b/inf2705.h @@ -1994,6 +1994,9 @@ static GLfloat idata[12][3] = {-Z, -X, 0} }; +#undef X +#undef Z + static int connectivity[20][3] = { {0, 4, 1}, diff --git a/makefile b/makefile index eb17631..0c45e11 100644 --- a/makefile +++ b/makefile @@ -1,33 +1,54 @@ -CONTEXT=sdl2 -ifeq "$(shell uname)" "Darwin" - CONTEXT=glfw3 - LDFLAGS += -lobjc -framework Foundation -framework OpenGL -framework Cocoa -endif +# Source http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ -CXXFLAGS += -g -W -Wall -Wno-unused-parameter -Wno-deprecated-declarations -CXXFLAGS += $(shell pkg-config --cflags glew) -CXXFLAGS += $(shell pkg-config --cflags $(CONTEXT)) +SRCDIR := . +#LIBDIR := ../nas2d-core/build/lib +BUILDDIR := . +OBJDIR := $(BUILDDIR)/obj +DEPDIR := $(BUILDDIR)/deps +#EXE := $(BINDIR)/OPHD +EXE := ripple -LDFLAGS += -g -LDFLAGS += $(shell pkg-config --libs glew) -LDFLAGS += $(shell pkg-config --libs $(CONTEXT)) +CFLAGS := -std=c++11 -g -Wall -Wno-unknown-pragmas -I/usr/include/glm -I/usr/include/eigen3 $(shell pkg-config --cflags glew) +CFLAGS += $(shell pkg-config --cflags sdl2) +LDFLAGS := -lstdc++ -lm -lglfw -lGLEW -lGL +LDFLAGS += $(shell pkg-config --libs sdl2) -TP="tp3" -SRC=ripple +DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPDIR)/$*.Td -exe : $(SRC).exe -run : exe - optirun ./$(SRC).exe -$(SRC).exe : $(SRC).cpp *.h - $(CXX) $(CXXFLAGS) -o$@ $(SRC).cpp $(LDFLAGS) +COMPILE.cpp = $(CXX) $(DEPFLAGS) $(CFLAGS) $(TARGET_ARCH) -c +POSTCOMPILE = @mv -f $(DEPDIR)/$*.Td $(DEPDIR)/$*.d && touch $@ -sol : ; make SRC=$(SRC)Solution exe -runs : ; make SRC=$(SRC)Solution run +SRCS := $(shell find $(SRCDIR) -name '*.cpp') +OBJS := $(patsubst $(SRCDIR)/%.cpp,$(OBJDIR)/%.o,$(SRCS)) +OBJS := $(filter-out $(OBJDIR)/glm/% $(OBJDIR)/glew/% $(OBJDIR)/glfw/% $(OBJDIR)/ObjParser/Global% $(OBJDIR)/ObjParser/Main%,$(OBJS)) # Filter ui_builder +FOLDERS := $(sort $(dir $(SRCS))) -clean : - rm -rf *.o *.exe *.exe.dSYM +all: $(EXE) -remise zip : - make clean - rm -f remise_$(TP).zip - zip -r remise_$(TP).zip *.cpp *.h *.glsl makefile *.txt textures +$(EXE): $(OBJS) + @mkdir -p ${@D} + $(CXX) $^ $(LDFLAGS) -o $@ + +$(OBJS): $(OBJDIR)/%.o : $(SRCDIR)/%.cpp $(DEPDIR)/%.d | build-folder + $(COMPILE.cpp) $(OUTPUT_OPTION) $< + $(POSTCOMPILE) + +.PHONY:build-folder +build-folder: + @mkdir -p $(patsubst $(SRCDIR)/%,$(OBJDIR)/%, $(FOLDERS)) + @mkdir -p $(patsubst $(SRCDIR)/%,$(DEPDIR)/%, $(FOLDERS)) + +$(DEPDIR)/%.d: ; +.PRECIOUS: $(DEPDIR)/%.d + +include $(wildcard $(patsubst $(SRCDIR)/%.cpp,$(DEPDIR)/%.d,$(SRCS))) + +.PHONY:clean, clean-deps, clean-all +clean: + -rm -fr $(OBJDIR) + -rm -fr $(DEPDIR) + -rm -f $(EXE) +clean-deps: + -rm -fr $(DEPDIR) +clean-all: + -rm -rf $(BUILDDIR) diff --git a/ripple.cpp b/ripple.cpp index 46e1dc0..81c133a 100644 --- a/ripple.cpp +++ b/ripple.cpp @@ -1,10 +1,9 @@ -// Prénoms, noms et matricule des membres de l'équipe: -// - Prénom1 NOM1 (matricule1) -// - Prénom2 NOM2 (matricule2) - #include #include #include "inf2705.h" +#include "constants.h" +#include "FBO.h" +#include "Packets.h" #define SOL 1 @@ -56,6 +55,14 @@ bool enmouvement = false; // le modèle est en mouvement/rotation automatiqu bool afficheAxes = true; // indique si on affiche les axes GLenum modePolygone = GL_FILL; // comment afficher les polygones +// FBOs +FBO *posFBO; +FBO *heightFBO; +FBO *aaFBO; + +// Wave Packets +Packets *packets; + //////////////////////////////////////// // déclaration des variables globales // //////////////////////////////////////// @@ -349,6 +356,11 @@ void initialiser() phiCam = 0.0; distCam = 30.0; + // Create FBOs + posFBO = new FBO(); + heightFBO = new FBO(); + aaFBO = new FBO(); + // couleur de l'arrière-plan glClearColor( 0.4, 0.2, 0.0, 1.0 ); @@ -463,6 +475,9 @@ void initialiser() tore = new FormeTore( 0.4, 0.8, 32, 32 ); cylindre = new FormeCylindre( 0.3, 0.3, 3.0, 32, 32 ); cone = new FormeCylindre( 0.0, 0.5, 3.0, 32, 32 ); + + // Update display mesh and FBOs + // redimensionner(); } void conclure() @@ -477,6 +492,9 @@ void conclure() delete tore; delete cylindre; delete cone; + delete posFBO; + delete heightFBO; + delete aaFBO; } void afficherModele() @@ -529,7 +547,7 @@ void afficherModele() glBindVertexArray( 0 ); break; case 2: - tore->afficher(); + tore->afficher(); break; case 3: sphere->afficher(); @@ -679,7 +697,16 @@ void FenetreTP::afficherScene() // fonction de redimensionnement de la fenêtre graphique void FenetreTP::redimensionner( GLsizei w, GLsizei h ) { + std::cout << "Resizing to " << w << "×" << h << std::endl; + /* FIXME Is this function called on program start ? */ glViewport( 0, 0, w, h ); + /* TODO Create/resize display mesh */ + posFBO->Liberer(); + posFBO->Init(WAVETEX_WIDTH_FACTOR * w, WAVETEX_HEIGHT_FACTOR * h); + heightFBO->Liberer(); + heightFBO->Init(WAVETEX_WIDTH_FACTOR * w, WAVETEX_HEIGHT_FACTOR * h); + aaFBO->Liberer(); + aaFBO->Init(AA_OVERSAMPLE_FACTOR * w, AA_OVERSAMPLE_FACTOR * h); } static void echoEtats( )