Refactoring + new color map for bathymetry

parent f5435947
......@@ -55,8 +55,8 @@ else:
for i in sourceFiles:
env.src_files.append(env.Object(i))
# SWE_Block is used in every implementation
sourceFiles = ['SWE_Block.cpp']
# SWE_Block and Logger is used in every implementation
sourceFiles = ['SWE_Block.cpp', 'tools/Logger.cpp']
# OpenGL CPU-files
if env['openGL'] == True:
......@@ -66,7 +66,9 @@ if env['openGL'] == True:
sourceFiles.append( ['opengl/controller.cpp'] )
sourceFiles.append( ['opengl/shader.cpp'] )
sourceFiles.append( ['opengl/visualization.cpp'] )
sourceFiles.append( ['opengl/text.cpp'] )
sourceFiles.append( ['opengl/vbo.cpp'] )
if env['openGL_instr'] == True:
sourceFiles.append( ['opengl/text.cpp'] )
# Asagi scenario
if env['asagi'] == True:
......
......@@ -31,13 +31,9 @@
#include "SWE_WavePropagationBlockCuda_kernels.hh"
#include <cassert>
#ifndef STATICLOGGER
#define STATICLOGGER
#include "tools/Logger.hpp"
static tools::Logger s_sweLogger;
#endif
#include <cassert>
// CUDA-C includes
#include <cuda.h>
......@@ -146,7 +142,7 @@ SWE_WavePropagationBlockCuda::~SWE_WavePropagationBlockCuda() {
cudaFree(hvNetUpdatesAboveD);
// reset the cuda device
s_sweLogger.printString("Resetting the CUDA devices");
tools::Logger::logger.printString("Resetting the CUDA devices");
cudaDeviceReset();
}
......
......@@ -37,8 +37,8 @@
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
// Number of nodes (not cells) of grid
#define GRID_XSIZE 401
#define GRID_YSIZE 401
#define GRID_XSIZE 801
#define GRID_YSIZE 801
#define WINDOW_TITLE "Shallow Water Equations v1.2"
/**
......@@ -81,7 +81,6 @@ int main(int argc, char *argv[])
// Initialize scenario:
SWE_Scenario* scene = NULL;
SWE_VisInfo* visInfo = NULL;
SWE_BlockCUDA* splash = NULL;
// If input file specified, then read from VTK file:
......@@ -89,7 +88,6 @@ int main(int argc, char *argv[])
SWE_VtkScenarioVisInfo* newScene = SWE_VtkScenarioVisInfo::readVtkFile(argv[1]);
// NOTE: Simulation uses a fixed resolution (independent of VTK file)
scene = newScene;
visInfo = newScene;
printf("Scenario read from input file %s\n\n", argv[1]);
};
......@@ -113,9 +111,9 @@ int main(int argc, char *argv[])
// Initialize simulation
printf("Init simulation\n\n");
Simulation sim(nx,ny,dx,dy, scene, visInfo, splash);
Simulation sim(nx,ny,dx,dy, scene, splash);
printf("Init visualisation\n\n");
visualization.init(&sim);
visualization.init(sim);
// Initialize controller
Controller controller(&sim, &visualization);
......
......@@ -23,6 +23,7 @@
#include "../scenarios/SWE_simple_scenarios_vis.h"
#ifdef ASAGI
#include "../scenarios/SWE_AsagiScenario.hpp"
#include "../scenarios/SWE_AsagiScenario_vis.hpp"
#endif // ASAGI
/**
......@@ -172,6 +173,14 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
// Pause/Resume
paused = !paused;
break;
case SDLK_PLUS:
// Increase water scaling
visualization->modifyWaterScaling(1.5);
break;
case SDLK_MINUS:
// Decrease water scaling
visualization->modifyWaterScaling(1/1.5);
break;
case SDLK_1:
// Load scenario 1
{
......@@ -187,8 +196,8 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
float dy = (newScene->getBoundaryPos(BND_TOP) - newScene->getBoundaryPos(BND_BOTTOM) )/SWE_Block::getNy();
SWE_Block::initGridData(SWE_Block::getNx(),SWE_Block::getNy(),dx,dy);
simulation->loadNewScenario(newScene, NULL);
visualization->updateBathymetryVBO(simulation);
simulation->loadNewScenario(newScene);
visualization->init(*simulation);
}
break;
case SDLK_2:
......@@ -208,8 +217,8 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
float dy = (newScene->getBoundaryPos(BND_TOP) - newScene->getBoundaryPos(BND_BOTTOM) )/SWE_Block::getNy();
SWE_Block::initGridData(SWE_Block::getNx(),SWE_Block::getNy(),dx,dy);
simulation->loadNewScenario(newScene, visInfos[1]);
visualization->updateBathymetryVBO(simulation);
simulation->loadNewScenario(newScene);
visualization->init(*simulation, visInfos[1]);
}
break;
case SDLK_3:
......@@ -227,8 +236,8 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
float dy = (newScene->getBoundaryPos(BND_TOP) - newScene->getBoundaryPos(BND_BOTTOM) )/SWE_Block::getNy();
SWE_Block::initGridData(SWE_Block::getNx(),SWE_Block::getNy(),dx,dy);
simulation->loadNewScenario(newScene, NULL);
visualization->updateBathymetryVBO(simulation);
simulation->loadNewScenario(newScene);
visualization->init(*simulation);
}
break;
#ifdef ASAGI
......@@ -257,8 +266,8 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
float dy = (newScene->getBoundaryPos(BND_TOP) - newScene->getBoundaryPos(BND_BOTTOM) )/SWE_Block::getNy();
SWE_Block::initGridData(SWE_Block::getNx(),SWE_Block::getNy(),dx,dy);
simulation->loadNewScenario(newScene, NULL);
visualization->updateBathymetryVBO(simulation);
simulation->loadNewScenario(newScene);
visualization->init(*simulation);
}
break;
case SDLK_5:
......@@ -277,6 +286,8 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
ASAGI_INPUT_DIR "tohoku_gebco_ucsb3_500m_hawaii_bath.nc",
ASAGI_INPUT_DIR "tohoku_gebco_ucsb3_500m_hawaii_displ.nc",
(float) 28800., simulationArea);
visInfos[4] = new SWE_AsagiJapanSmallVisInfo();
}
SWE_Scenario* newScene = scenarios[4];
......@@ -286,8 +297,8 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
float dy = (newScene->getBoundaryPos(BND_TOP) - newScene->getBoundaryPos(BND_BOTTOM) )/SWE_Block::getNy();
SWE_Block::initGridData(SWE_Block::getNx(),SWE_Block::getNy(),dx,dy);
simulation->loadNewScenario(newScene, NULL);
visualization->updateBathymetryVBO(simulation);
simulation->loadNewScenario(newScene);
visualization->init(*simulation, visInfos[4]);
}
break;
case SDLK_6:
......@@ -315,8 +326,8 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
float dy = (newScene->getBoundaryPos(BND_TOP) - newScene->getBoundaryPos(BND_BOTTOM) )/SWE_Block::getNy();
SWE_Block::initGridData(SWE_Block::getNx(),SWE_Block::getNy(),dx,dy);
simulation->loadNewScenario(newScene, NULL);
visualization->updateBathymetryVBO(simulation);
simulation->loadNewScenario(newScene);
visualization->init(*simulation);
}
break;
case SDLK_7:
......@@ -344,8 +355,8 @@ bool Controller::handleKeyPress( SDL_keysym *keysym) {
float dy = (newScene->getBoundaryPos(BND_TOP) - newScene->getBoundaryPos(BND_BOTTOM) )/SWE_Block::getNy();
SWE_Block::initGridData(SWE_Block::getNx(),SWE_Block::getNy(),dx,dy);
simulation->loadNewScenario(newScene, NULL);
visualization->updateBathymetryVBO(simulation);
simulation->loadNewScenario(newScene);
visualization->init(*simulation);
}
break;
#endif // ASAGI
......
......@@ -2,8 +2,9 @@
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Tobias Schnabel
// Copyright (C) 2012 Sebastian Rettenberger
//
// SWE_CUDA is free software: you can redristribute it and/or modify
// SWE_CUDA is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
......@@ -19,6 +20,8 @@
#include "shader.h"
#include "../tools/Logger.hpp"
/**
Constructor.
Check whether shaders are supported. If yes, load vertex and fragment
......@@ -30,30 +33,43 @@
shader code
*/
Shader::Shader(char const * vertexShaderFile, char const * fragmentShaderFile) {
shdrSupport = isExtensionSupported("GL_ARB_vertex_shader")
&& isExtensionSupported("GL_ARB_shader_objects")
&& isExtensionSupported("GL_ARB_fragment_shader");
Shader::Shader(char const * vertexShaderFile, char const * fragmentShaderFile)
{
if (!shdrSupport) {
// Shaders are either not supported or we did not try yet
// This if-statement makes sure, we only load the extensions once
shdrSupport = isExtensionSupported("GL_ARB_vertex_shader")
&& isExtensionSupported("GL_ARB_shader_objects")
&& isExtensionSupported("GL_ARB_fragment_shader");
if (shdrSupport) {
tools::Logger::logger.printString("Shaders supported!");
// Load extensions
glCreateShader = (PFNGLCREATESHADERPROC) SDL_GL_GetProcAddress("glCreateShader");
glCreateProgram = (PFNGLCREATEPROGRAMPROC) SDL_GL_GetProcAddress("glCreateProgram");
glAttachShader = (PFNGLATTACHSHADERPROC)SDL_GL_GetProcAddress("glAttachShader");
glCompileShader = (PFNGLCOMPILESHADERPROC)SDL_GL_GetProcAddress("glCompileShader");
glUseProgram = (PFNGLUSEPROGRAMPROC)SDL_GL_GetProcAddress("glUseProgram");
glDetachShader = (PFNGLDETACHSHADERPROC)SDL_GL_GetProcAddress("glDetachShader");
glDeleteShader = (PFNGLDELETESHADERPROC) SDL_GL_GetProcAddress("glDeleteShader");
glLinkProgram = (PFNGLLINKPROGRAMPROC)SDL_GL_GetProcAddress("glLinkProgram");
glShaderSource = (PFNGLSHADERSOURCEPROC)SDL_GL_GetProcAddress("glShaderSource");
glDeleteProgram = (PFNGLDELETEPROGRAMPROC)SDL_GL_GetProcAddress("glDeleteProgram");
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) SDL_GL_GetProcAddress("glGetUniformLocation");
glUniform1f = (PFNGLUNIFORM1FPROC) SDL_GL_GetProcAddress("glUniform1f");
glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterivARB");
glGetShaderiv = (PFNGLGETSHADERIVPROC) SDL_GL_GetProcAddress("glGetShaderiv");
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) SDL_GL_GetProcAddress("glGetShaderInfoLog");
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) SDL_GL_GetProcAddress("glGetProgramInfoLog");
} else
tools::Logger::logger.printString("Shaders are NOT supported! Normal rendering mode");
}
shdrLoaded = false;
if (shdrSupport) {
// Load extensions
glCreateShader = (PFNGLCREATESHADERPROC) SDL_GL_GetProcAddress("glCreateShader");
glCreateProgram = (PFNGLCREATEPROGRAMPROC) SDL_GL_GetProcAddress("glCreateProgram");
glAttachShader = (PFNGLATTACHSHADERPROC)SDL_GL_GetProcAddress("glAttachShader");
glCompileShader = (PFNGLCOMPILESHADERPROC)SDL_GL_GetProcAddress("glCompileShader");
glUseProgram = (PFNGLUSEPROGRAMPROC)SDL_GL_GetProcAddress("glUseProgram");
glDetachShader = (PFNGLDETACHSHADERPROC)SDL_GL_GetProcAddress("glDetachShader");
glDeleteShader = (PFNGLDELETESHADERPROC) SDL_GL_GetProcAddress("glDeleteShader");
glLinkProgram = (PFNGLLINKPROGRAMPROC)SDL_GL_GetProcAddress("glLinkProgram");
glShaderSource = (PFNGLSHADERSOURCEPROC)SDL_GL_GetProcAddress("glShaderSource");
glDeleteProgram = (PFNGLDELETEPROGRAMPROC)SDL_GL_GetProcAddress("glDeleteProgram");
glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC) SDL_GL_GetProcAddress("glGetObjectParameterivARB");
glGetShaderiv = (PFNGLGETSHADERIVPROC) SDL_GL_GetProcAddress("glGetShaderiv");
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) SDL_GL_GetProcAddress("glGetShaderInfoLog");
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) SDL_GL_GetProcAddress("glGetProgramInfoLog");
// Read shader files
bool readSuccess = false;
vertexShaderSource = NULL;
......@@ -84,7 +100,6 @@ Shader::Shader(char const * vertexShaderFile, char const * fragmentShaderFile)
shdrLoaded = true;
} else {
// Errors while compiling shaders
shdrSupport = false;
glDeleteShader(vertexShader);
delete[] vertexShaderSource;
glDeleteShader(fragmentShader);
......@@ -135,13 +150,6 @@ void Shader::disableShader() {
}
}
/**
Returns, whether shaders are supported by graphics hardware
*/
bool Shader::shadersSupported() {
return shdrSupport;
}
/**
Returns, whether shaders could by loaded successfully
......@@ -333,3 +341,23 @@ bool Shader::isProgramLinked(GLuint program, char const * prefix)
return (linked != 0);
}
bool Shader::shdrSupport = false;
PFNGLCREATESHADERPROC Shader::glCreateShader;
PFNGLCREATEPROGRAMPROC Shader::glCreateProgram;
PFNGLATTACHSHADERPROC Shader::glAttachShader;
PFNGLCOMPILESHADERPROC Shader::glCompileShader;
PFNGLUSEPROGRAMPROC Shader::glUseProgram;
PFNGLDETACHSHADERPROC Shader::glDetachShader;
PFNGLDELETESHADERPROC Shader::glDeleteShader;
PFNGLLINKPROGRAMPROC Shader::glLinkProgram;
PFNGLSHADERSOURCEPROC Shader::glShaderSource;
PFNGLDELETEPROGRAMPROC Shader::glDeleteProgram;
PFNGLGETUNIFORMLOCATIONPROC Shader::glGetUniformLocation;
PFNGLUNIFORM1FPROC Shader::glUniform1f;
PFNGLGETOBJECTPARAMETERIVARBPROC Shader::glGetObjectParameterivARB;
PFNGLGETSHADERIVPROC Shader::glGetShaderiv;
PFNGLGETSHADERINFOLOGPROC Shader::glGetShaderInfoLog;
PFNGLGETPROGRAMINFOLOGPROC Shader::glGetProgramInfoLog;
......@@ -4,8 +4,9 @@
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Tobias Schnabel
// Copyright (C) 2012 Sebastian Rettenberger
//
// SWE_CUDA is free software: you can redristribute it and/or modify
// SWE_CUDA is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
......@@ -30,17 +31,35 @@ public:
Shader(char const * vertexShaderFile, char const * fragmentShaderFile) ;
~Shader();
// Check if shaders are supported
bool shadersSupported();
// Check if shaders are loaded
bool shadersLoaded();
// Shader control
void enableShader();
void disableShader();
/**
* @return Location of the uniform variable
*/
GLint getUniformLocation(const char* name)
{
if (!shdrLoaded)
return -1;
return glGetUniformLocation(program, name);
}
/**
* Set a uniform variable in the shader
*/
void setUniform(GLint location, GLfloat value)
{
if (location < 0)
return;
glUniform1f(location, value);
}
private:
// State flags
bool shdrSupport;
bool shdrLoaded;
// Helper functions
......@@ -62,23 +81,27 @@ private:
// Shaders id
GLuint program;
/** Are shaders supported */
static bool shdrSupport;
// Shader extension function pointers
PFNGLCREATESHADERPROC glCreateShader;
PFNGLCREATEPROGRAMPROC glCreateProgram;
PFNGLATTACHSHADERPROC glAttachShader;
PFNGLCOMPILESHADERPROC glCompileShader;
PFNGLUSEPROGRAMPROC glUseProgram;
PFNGLDETACHSHADERPROC glDetachShader;
PFNGLDELETESHADERPROC glDeleteShader;
PFNGLLINKPROGRAMPROC glLinkProgram;
PFNGLSHADERSOURCEPROC glShaderSource;
PFNGLDELETEPROGRAMPROC glDeleteProgram;
static PFNGLCREATESHADERPROC glCreateShader;
static PFNGLCREATEPROGRAMPROC glCreateProgram;
static PFNGLATTACHSHADERPROC glAttachShader;
static PFNGLCOMPILESHADERPROC glCompileShader;
static PFNGLUSEPROGRAMPROC glUseProgram;
static PFNGLDETACHSHADERPROC glDetachShader;
static PFNGLDELETESHADERPROC glDeleteShader;
static PFNGLLINKPROGRAMPROC glLinkProgram;
static PFNGLSHADERSOURCEPROC glShaderSource;
static PFNGLDELETEPROGRAMPROC glDeleteProgram;
static PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
static PFNGLUNIFORM1FPROC glUniform1f;
// Shader objects extension pointers
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
PFNGLGETSHADERIVPROC glGetShaderiv;
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
static PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
static PFNGLGETSHADERIVPROC glGetShaderiv;
static PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
static PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
};
#endif
......@@ -18,7 +18,7 @@
// along with SWE_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
#include "simulation.h"
#include <stdlib.h>
#include <cstring>
#include "../SWE_BlockCUDA.hh"
// Taken form FWaveCuda.h
......@@ -37,14 +37,13 @@ const float dryTol = 100.;
*/
Simulation::Simulation (int nx, int ny, float dx, float dy,
SWE_Scenario* scene, SWE_VisInfo* visInfo,
SWE_BlockCUDA* _splash)
SWE_Scenario* scene, SWE_BlockCUDA* _splash)
: maxDim( (nx > ny) ? nx : ny ),
maxCellSize( (dx > dy) ? dx : dy ),
splash(_splash),
fileNumber(0)
{
loadNewScenario(scene, visInfo);
loadNewScenario(scene);
}
/**
......@@ -53,19 +52,12 @@ Simulation::Simulation (int nx, int ny, float dx, float dy,
Simulation::~Simulation () {
}
void Simulation::loadNewScenario(SWE_Scenario* scene, SWE_VisInfo* visInfo) {
void Simulation::loadNewScenario(SWE_Scenario* scene) {
myScenario = scene;
curTime = 0.0f;
isFirstStep = 1;
useFileInput = false;
Simulation::initBoundaries(myScenario);
if (visInfo != NULL) {
wScale = visInfo->waterVerticalScaling();
bScale = visInfo->bathyVerticalScaling();
bOffset = visInfo->bathyVerticalOffset();
} else {
getScalingApproximation(splash->getWaterHeight(), splash->getBathymetry());
}
initBoundaries(myScenario);
}
/**
......@@ -79,7 +71,7 @@ void Simulation::runCuda(struct cudaGraphicsResource **vbo_resource, struct cuda
{
// map OpenGL buffer object for writing from CUDA
float3 *dptr, *dptr2;
size_t num_bytes, num_bytes2;
std::size_t num_bytes, num_bytes2;
cudaGraphicsMapResources(1, vbo_resource, 0);
cudaGraphicsResourceGetMappedPointer((void **)&dptr, &num_bytes,
......@@ -155,7 +147,7 @@ void Simulation::setBathBuffer(float* bath) {
for (int j=0; j<ny+1;j++) {
for (int i=0;i<nx+1;i++) {
bath[(j*(ny+1) + i)*6] = (float) i;
bath[(j*(ny+1) + i)*6 + 1]= bScale * 0.25f * (b[i][j]+b[i+1][j]+b[i][j+1]+b[i+1][j+1]) + bOffset;
bath[(j*(ny+1) + i)*6 + 1]= 0.25f * (b[i][j]+b[i+1][j]+b[i][j+1]+b[i+1][j+1]);
bath[(j*(ny+1) + i)*6 + 2] = (float) j;
bath[(j*(ny+1) + i)*6 + 3] = 0.0f;
bath[(j*(ny+1) + i)*6 + 4] = 0.0f;
......@@ -248,11 +240,12 @@ void Simulation::calculateWaterSurface(float3* destBuffer) {
Gets called before simulation starts and determines the average,
mininimum and maximum values of the bathymetry and water surface data.
Uses latter values to estimate the scaling factors.
@param h Fload2D array that holds water height
@param b Fload2D array that holds bathymetry data
*/
void Simulation::getScalingApproximation(const Float2D& h, const Float2D& b)
void Simulation::getScalingApproximation(float &bScale, float &bOffset, float &wScale)
{
const Float2D &h = splash->getWaterHeight();
const Float2D &b = splash->getBathymetry();
// Minimum values
float minB, minH;
// Maximum values
......@@ -282,7 +275,7 @@ void Simulation::getScalingApproximation(const Float2D& h, const Float2D& b)
}
}
bOffset = 0; // This should be !=0 only in some artificial scenarios
bScale = -50/minB;
bScale = -100/minB;
cout << "Scaling of bathymetry: " << bScale << endl;
if ((maxH - minH) < 0.0001f) {
......@@ -290,7 +283,7 @@ void Simulation::getScalingApproximation(const Float2D& h, const Float2D& b)
} else {
wScale = 1.0f;
}
wScale = (maxDim/40.0)*wScale;
wScale = (maxDim/50.0)*wScale;
cout << "Scaling of water level: " << wScale << endl;
}
......@@ -353,7 +346,7 @@ float scaleFunction(float val, float scale) {
*/
__global__
void kernelCalcVisBuffer(float3* visBuffer, const float* hd, const float* bd,
int nx, int ny, float scale)
int nx, int ny)
{
int i = TILE_SIZE*blockIdx.x + threadIdx.x;
int j = TILE_SIZE*blockIdx.y + threadIdx.y;
......@@ -368,7 +361,7 @@ void kernelCalcVisBuffer(float3* visBuffer, const float* hd, const float* bd,
else
visBuffer[j*(ny+1) + i] = make_float3(
i,
scale * 0.25 * (
0.25 * (
hd[index]+hd[index + 1]+ hd[index2] + hd[index2 + 1] +
bd[index]+bd[index + 1]+ bd[index2] + bd[index2 + 1]),
j);
......@@ -397,7 +390,7 @@ void Simulation::updateVisBuffer(float3* _visBuffer) {
// Interpolate cell centered h-values
dim3 dimBlock(TILE_SIZE,TILE_SIZE);
dim3 dimGrid((nx+TILE_SIZE)/TILE_SIZE,(ny+TILE_SIZE)/TILE_SIZE);
kernelCalcVisBuffer<<<dimGrid,dimBlock>>>(_visBuffer, hd, bd, nx, ny, wScale);
kernelCalcVisBuffer<<<dimGrid,dimBlock>>>(_visBuffer, hd, bd, nx, ny);
}
/**
Function used for debugging. Outputs the current visBuffer
......
......@@ -33,13 +33,13 @@ class Simulation {
public:
// Constructor + Destructor
Simulation (int nx, int ny, float dx, float dy,
SWE_Scenario* scene, SWE_VisInfo* visInfo, SWE_BlockCUDA* init_splash);
SWE_Scenario* scene, SWE_BlockCUDA* init_splash);
~Simulation();
// Restart simulation
void restart();
// Load new scenario after initialization
void loadNewScenario(SWE_Scenario* scene, SWE_VisInfo* visInfo);
void loadNewScenario(SWE_Scenario* scene);
// Save simulation state to file
void saveToFile();
// Return the bathymetry data
......@@ -51,6 +51,7 @@ class Simulation {
void writeDebugOutput(float3* destBuffer = NULL);
protected:
public:
// Instance of SWE_BlockCUDA
SWE_BlockCUDA* splash;
......@@ -63,8 +64,6 @@ class Simulation {
int isFirstStep;
// Maximum of cell sizes
float maxCellSize;
// Scaling factors used by visualization
float bScale, bOffset, wScale;
// Initialize boundaries defined by the scene
void initBoundaries(SWE_Scenario* scene);
// Initialize boundaries defined by an input file
......@@ -79,7 +78,7 @@ class Simulation {
// Compute normals of the water surface for shading
void calculateNormals(float3* vertexBuffer, float3* destBuffer);
void getScalingApproximation(const Float2D& h, const Float2D& b);
void getScalingApproximation(float &bScale, float &bOffset, float &wScale);
void updateVisBuffer(float3* _visBuffer);
void debugVisBuffer(float3* _visBuffer);
......
......@@ -89,7 +89,7 @@ public:
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, 4, surf->w, surf->h, 0, GL_BGRA,
GL_UNSIGNED_BYTE, surf->pixels );
GL_UNSIGNED_BYTE, surf->pixels);
/* GL_NEAREST looks horrible, if scaled... */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
......
/**
* @file
* This file is part of SWE.
*
* @author Sebastian Rettenberger (rettenbs AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Sebastian_Rettenberger,_M.Sc.)
*
* @section LICENSE
*
* SWE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SWE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SWE. If not, see <http://www.gnu.org/licenses/>.
*/
#include "vbo.h"
#include "visualization.h"
void VBO::init()
{
if (glGenBuffers == 0L) {
// Load vbo extension
// Check OpenGL extension(s)
if (!Visualization::isExtensionSupported("GL_ARB_vertex_buffer_object")) {
tools::Logger::logger.printString("Vertex Buffer Objects Extension not supported! Exit..\n");
SDL_Quit();
exit(1);
}
// Load Vertex Buffer Extension
glGenBuffers = (PFNGLGENBUFFERSARBPROC) SDL_GL_GetProcAddress("glGenBuffersARB");
glBindBuffer = (PFNGLBINDBUFFERARBPROC) SDL_GL_GetProcAddress("glBindBufferARB");
glBufferData = (PFNGLBUFFERDATAARBPROC) SDL_GL_GetProcAddress("glBufferDataARB");
glDeleteBuffers = (PFNGLDELETEBUFFERSARBPROC) SDL_GL_GetProcAddress("glDeleteBuffersARB");
}
glGenBuffers(1, &name);
}
PFNGLGENBUFFERSARBPROC VBO::glGenBuffers = 0L;
PFNGLBINDBUFFERARBPROC VBO::glBindBuffer = 0L;
PFNGLBUFFERDATAARBPROC VBO::glBufferData = 0L;
PFNGLDELETEBUFFERSARBPROC VBO::glDeleteBuffers = 0L;
/**
* @file
* This file is part of SWE.
*
* @author Sebastian Rettenberger (rettenbs AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Sebastian_Rettenberger,_M.Sc.)
*
* @section LICENSE
*
* SWE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SWE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SWE. If not, see <http://www.gnu.org/licenses/>.
*
*
* @section DESCRIPTION
*
* Handles a VertexBufferObject.
*/
#ifndef VBO_H
#define VBO_H
#include "../tools/Logger.hpp"
#include <SDL_opengl.h>
class VBO
{
private:
/** OpenGL name of the object */
GLuint name;
public:
VBO()
: name(0)
{}
/**
* Initializes the object
*/
void init();
/**
* @return The OpenGL name of the buffer
*/
GLuint getName()
{
return name;
}
void setBufferData(GLsizei size, const void* data,
GLenum target = GL_ARRAY_BUFFER,
GLenum usage = GL_STATIC_DRAW)
{
glBindBuffer(target, name);
glBufferData(target, size, data, usage);
glBindBuffer(target, 0);
}
void bindBuffer(GLenum target = GL_ARRAY_BUFFER)
{
glBindBuffer(target, name);
}
/**
* Frees all associated memory
*/
void finialize()
{
if (name) {
glDeleteBuffers(1, &name);
name = 0;
}
}
private:
// VBO Extension Function Pointers
static PFNGLGENBUFFERSARBPROC glGenBuffers; // VBO Name Generation Procedure
static PFNGLBINDBUFFERARBPROC glBindBuffer; // VBO Bind Procedure
static PFNGLBUFFERDATAARBPROC glBufferData; // VBO Data Loading Procedure
static PFNGLDELETEBUFFERSARBPROC glDeleteBuffers; // VBO Deletion Procedure
};
#endif // VBO_H
......@@ -18,6 +18,7 @@
// along with SWE_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
uniform float scale = 10;
varying vec3 N;
varying vec4 ambient;
varying vec4 worldCoordinates;
......@@ -34,7 +35,7 @@ void main()
N = normalize(gl_NormalMatrix * gl_Normal);
// Save world coordinates
worldCoordinates = gl_Vertex;
worldCoordinates = gl_Vertex * scale;
// Compute vertex position via internal transform function
gl_Position = ftransform();
......
......@@ -20,6 +20,8 @@
#include "visualization.h"
#include "../tools/Logger.hpp"
/**
Constructor. All dimensions are node-based, this means a grid consisting of
2x2 cells would have 3x3 nodes.
......@@ -38,6 +40,9 @@ Visualization::Visualization(int windowWidth, int windowHeight, const char* wind
grid_ysize = _grid_ysize;
renderMode = SHADED;
cuda_vbo_watersurface = 0L;
cuda_vbo_normals = 0L;
// Initialize rendering
initSDL(windowWidth, windowHeight);
initGLWindow(windowWidth, windowHeight);
......@@ -49,18 +54,23 @@ Visualization::Visualization(int windowWidth, int windowHeight, const char* wind
// Load camera and shaders
camera = new Camera(_grid_xsize*1.5f, window_title);
shaders = new Shader("vertex.glsl", "fragment.glsl");
if (shaders->shadersSupported()) {
printf("Shaders supported!\n");
} else {
printf("Shaders are NOT supported! Normal rendering mode\n");
}
if (shaders->shadersLoaded()) {
printf("Shaders successfully loaded!\n");
waterShader = new Shader("vertex.glsl", "fragment.glsl");
if (waterShader->shadersLoaded()) {
tools::Logger::logger.printString("Water shaders successfully loaded!");
renderMode = WATERSHADER;
} else {
printf("Shaders error while loading shaders\n");
}
} else
tools::Logger::logger.printString("Error while loading water shaders");
wScaleLocation = waterShader->getUniformLocation("scale");
// Create openGL buffers
vboBathymetry.init();
vboVerticesIndex.init();
vboWaterSurface.init();
vboNormals.init();
vboBathColor.init();
createIndicesVBO(grid_xsize, grid_ysize);
}
/**
......@@ -68,24 +78,47 @@ Visualization::Visualization(int windowWidth, int windowHeight, const char* wind
*/
Visualization::~Visualization() {
delete camera;
delete shaders;
delete waterShader;
#ifdef USESDLTTF
delete text;
#endif // USESDLTTF
SDL_Quit();
}
/**
Allocates memory for vertices and other geometry data.
@param sim instance of the simulation class
*/
void Visualization::init(Simulation &sim, SWE_VisInfo *visInfo) {
updateBathymetryVBO(sim);
createVertexVBO(vboWaterSurface, cuda_vbo_watersurface, cudaGraphicsMapFlagsNone);
createVertexVBO(vboNormals, cuda_vbo_normals, cudaGraphicsMapFlagsWriteDiscard);
if (visInfo == 0L) {
sim.getScalingApproximation(bScale, bOffset, wScale);
} else {
bScale = visInfo->bathyVerticalScaling();
bOffset = visInfo->bathyVerticalOffset();
wScale = visInfo->waterVerticalScaling();
}
}
/**
Frees all memory we used for geometry data
Needs to be called before destructor gets called
in order to work correctly
*/
void Visualization::cleanUp() {
deleteVBO(&vboWaterSurface, cuda_vbo_watersurface);
deleteVBO(&vboNormals, cuda_vbo_normals);
deleteVBO(&verticesIndex);
deleteVBO(&vboBathymetry);
deleteCudaResource(cuda_vbo_watersurface);
deleteCudaResource(cuda_vbo_normals);
vboBathymetry.finialize();
vboVerticesIndex.finialize();
vboWaterSurface.finialize();
vboNormals.finialize();
vboBathColor.finialize();
}
......@@ -100,10 +133,10 @@ void Visualization::renderDisplay() {
// Draw Scene
//DrawBottom();
DrawBathymetry(vboBathymetry, verticesIndex);
DrawBathymetry();
// Shaded pass
DrawWaterSurface(vboWaterSurface, vboNormals, verticesIndex);
DrawWaterSurface();
#ifdef USESDLTTF
text->startTextMode();
......@@ -122,6 +155,8 @@ void Visualization::renderDisplay() {
location.y -= location.h;
text->showText(" r: Restart scenario", location);
location.y -= location.h;
text->showText(" +/-: Scale wave height", location);
location.y -= location.h;
text->showText("Mouse:", location);
location.y -= location.h;
text->showText(" Left button: rotate", location);
......@@ -137,33 +172,31 @@ void Visualization::renderDisplay() {
// Update framebuffer
camera->displayImage();
int errCode = glGetError();
// Check for errors
if (glGetError() != GL_NO_ERROR) {
printf("OpenGL error occured..\n");
if (errCode != GL_NO_ERROR) {
printf("OpenGL error occured: %s\n", gluErrorString(errCode));
}
}
/**
Draws the water surface geometry (triangles)
@param vboID id of the vertex buffer object storing
the vertex positions
@param vboID id of the array buffer object storing
the corresponding normals for each vertex
@param verticesIndex id of the array buffer object storing the
vertex indices in rendering sequence
*/
void Visualization::DrawWaterSurface(GLuint vboID, GLuint vboNormals, GLuint verticesIndex) {
*/
void Visualization::DrawWaterSurface()
{
if (renderMode == WATERSHADER) {
// Depth pass first
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
renderMode = SHADED;
DrawWaterSurface(vboID, vboNormals, verticesIndex);
DrawWaterSurface();
renderMode = WATERSHADER;
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
// Now render all visible geometry
shaders->enableShader();
waterShader->enableShader();
// Set shader parameter
waterShader->setUniform(wScaleLocation, wScale);
glEnable(GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
......@@ -180,15 +213,16 @@ void Visualization::DrawWaterSurface(GLuint vboID, GLuint vboNormals, GLuint ver
glEnableClientState(GL_VERTEX_ARRAY);
// Set rendering to VBO mode
glBindBuffer(GL_ARRAY_BUFFER,vboNormals);
vboNormals.bindBuffer();
glNormalPointer(GL_FLOAT, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
vboWaterSurface.bindBuffer();
glVertexPointer(3, GL_FLOAT, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, verticesIndex);
vboVerticesIndex.bindBuffer(GL_ELEMENT_ARRAY_BUFFER);
// Enable VBO access and render triangles
glPushMatrix();
glTranslatef(-(grid_xsize-1)/2.0f,0.0f,-(grid_ysize-1)/2.0f);
glTranslatef(-(grid_xsize-1)/2.0f, 0.0f, -(grid_ysize-1)/2.0f);
glScalef(1.0f, wScale, 1.0f);
glColor3f(0.3f*1.2f, 0.45f*1.2f, 0.9f*1.2f);
if (renderMode == WIREFRAME)
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
......@@ -201,22 +235,17 @@ void Visualization::DrawWaterSurface(GLuint vboID, GLuint vboNormals, GLuint ver
glDisableClientState(GL_NORMAL_ARRAY);
glDisable(GL_LIGHTING);
glDisable(GL_BLEND);
shaders->disableShader();
waterShader->disableShader();
}
/**
Draws the bathymetry geometry
*/
@param vboID id of the vertex buffer object storing
the vertex positions
@param verticesIndex id of the array buffer object storing the
vertex indices in rendering sequence
*/
void Visualization::DrawBathymetry(GLuint vboID, GLuint verticesIndex) {
void Visualization::DrawBathymetry() {
GLsizei stride = 6*sizeof(float);
// Enable lighting
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
......@@ -224,19 +253,23 @@ void Visualization::DrawBathymetry(GLuint vboID, GLuint verticesIndex) {
// Enable array rendering
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
// Bind buffers
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, verticesIndex);
vboBathymetry.bindBuffer();
vboVerticesIndex.bindBuffer(GL_ELEMENT_ARRAY_BUFFER);
// Set VBO pointers
const GLvoid* normalOffset = (GLvoid*) 12;
glNormalPointer(GL_FLOAT, stride, normalOffset);
glVertexPointer(3, GL_FLOAT, stride, 0);
vboBathColor.bindBuffer();
glColorPointer(3, GL_FLOAT, 0, 0);
// Render triangles
glPushMatrix();
glTranslatef(-(grid_xsize-1)/2.0f,0.0f,-(grid_ysize-1)/2.0f);
glTranslatef(-(grid_xsize-1)/2.0f, bOffset, -(grid_ysize-1)/2.0f);
glScalef(1.0f, bScale, 1.0f);
glColor3f(0.4f*1.1f, 0.36f*1.1f, 0.3f*1.1f);
glDrawElements(GL_TRIANGLES, 6*(grid_xsize - 1)*(grid_ysize - 1), GL_UNSIGNED_INT, NULL);
glPopMatrix();
......@@ -244,6 +277,7 @@ void Visualization::DrawBathymetry(GLuint vboID, GLuint verticesIndex) {
// Disable array rendering
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisable(GL_LIGHTING);
}
......@@ -266,22 +300,6 @@ void Visualization::DrawBottom()
/**
Allocates memory for vertices and other geometry data.
@param sim instance of the simulation class
*/
void Visualization::init(Simulation* sim) {
// Create VBOs
createBathymetryVBO(&vboBathymetry, grid_xsize * grid_ysize * 6 * sizeof(float), sim);
createIndicesVBO(&verticesIndex, grid_xsize, grid_ysize);
createVertexVBO(&vboWaterSurface, grid_xsize * grid_ysize * 3 * sizeof(float),
&cuda_vbo_watersurface, cudaGraphicsMapFlagsNone);
createVertexVBO(&vboNormals ,grid_xsize * grid_ysize * 3 * sizeof(float),
&cuda_vbo_normals, cudaGraphicsMapFlagsWriteDiscard);
}
/**
Returns a pointer to the cuda memory object holding the
vertex normals
......@@ -304,7 +322,7 @@ cudaGraphicsResource** Visualization::getCudaWaterSurfacePtr() {
@param szTargetExtention string describing the extension to look for
*/
bool Visualization::IsExtensionSupported(const char* szTargetExtension )
bool Visualization::isExtensionSupported(const char* szTargetExtension )
{
const unsigned char *pszExtensions = NULL;
const unsigned char *pszStart;
......@@ -360,18 +378,6 @@ void Visualization::initSDL(int windowWidth, int windowHeight) {
SDL_Quit();
exit(2);
}
// Check OpenGL extension(s)
if (!IsExtensionSupported( "GL_ARB_vertex_buffer_object" )) {
printf("Vertex Buffer Objects Extension not supported! Exit..\n");
SDL_Quit();
exit(1);
}
// Load Vertex Buffer Extension
glGenBuffers = (PFNGLGENBUFFERSARBPROC) SDL_GL_GetProcAddress("glGenBuffersARB");
glBindBuffer = (PFNGLBINDBUFFERARBPROC) SDL_GL_GetProcAddress("glBindBufferARB");
glBufferData = (PFNGLBUFFERDATAARBPROC) SDL_GL_GetProcAddress("glBufferDataARB");
glDeleteBuffers = (PFNGLDELETEBUFFERSARBPROC) SDL_GL_GetProcAddress("glDeleteBuffersARB");
}
......@@ -479,54 +485,6 @@ int Visualization::coord(int x, int y, int width) {
return (y*width + x);
}
/**
Creates a vertex buffer object in OpenGL
@param size size in bytes to allocate
@return vboID pointer to an integer depicting the id of the
new vertex buffer object
*/
void Visualization::createVertexVBO(GLuint* vboID, int size)
{
// Create 1 buffer object
glGenBuffers(1, vboID);
glBindBuffer(GL_ARRAY_BUFFER, *vboID);
// Initialize buffer object
glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_DYNAMIC_DRAW);
// Switch to default buffer
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
/**
Creates a vertex buffer object in OpenGL and loads it with the bathymetry
data from simulation
@param size size in bytes to allocate
@param sim pointer to an instance of the simulation class
@return vboID pointer to an integer depicting the id of the
new vertex buffer object
*/
void Visualization::createBathymetryVBO(GLuint* vboID, int size, Simulation* sim) {
GLfloat* vBathy = new GLfloat[size/sizeof(GLfloat)];
// Create buffer object for vertex indices
glGenBuffers(1, vboID);
glBindBuffer(GL_ARRAY_BUFFER, *vboID);
// Initialize buffer object
sim->setBathBuffer(vBathy);
glBufferData(GL_ARRAY_BUFFER, size, vBathy, GL_STATIC_DRAW);
// Switch to default buffer
glBindBuffer(GL_ARRAY_BUFFER, 0);
delete[] vBathy;
}
/**
Updates vertex buffer object with new bathymetry
data from simulation
......@@ -534,36 +492,45 @@ void Visualization::createBathymetryVBO(GLuint* vboID, int size, Simulation* sim
@param sim pointer to an instance of the simulation class
*/
void Visualization::updateBathymetryVBO(Simulation* sim) {
int size = grid_xsize * grid_ysize * 6 * sizeof(float);
GLfloat* vBathy = new GLfloat[size/sizeof(GLfloat)];
void Visualization::updateBathymetryVBO(Simulation &sim) {
int size = grid_xsize * grid_ysize * 6;
// Select buffer
glBindBuffer(GL_ARRAY_BUFFER, vboBathymetry);
GLfloat* vBathy = new GLfloat[size];
sim.setBathBuffer(vBathy);
// Update buffer object
sim->setBathBuffer(vBathy);
glBufferData(GL_ARRAY_BUFFER, size, vBathy, GL_STATIC_DRAW);
vboBathymetry.setBufferData(size * sizeof(GLfloat), vBathy);
// Switch to default buffer
glBindBuffer(GL_ARRAY_BUFFER, 0);
delete[] vBathy;
const Float2D &bathymetry = sim.splash->getBathymetry();
GLfloat* color = new GLfloat[grid_xsize*grid_ysize*3];
for (int i = 0; i < grid_xsize; i++) {
for (int j = 0; j < grid_ysize; j++) {
height2Color(bathymetry[i][j], &color[((j*grid_ysize)+i)*3]);
}
}
vboBathColor.setBufferData(grid_xsize*grid_ysize*3*sizeof(GLfloat), color);
delete[] color;
}
/**
Creates a vertex buffer object in OpenGL and an associated CUDA resource
@param vbo Vertex buffer object
@param size size in bytes to allocate
@param vbo_res_flags cuda flags for memory access
@return vboID pointer to an integer depicting the id of the
new vertex buffer object
@param vbo_res_flags cuda flags for memory access
@return vbo_res cuda structure created by this function
*/
void Visualization::createVertexVBO(GLuint* vboID, int size, struct cudaGraphicsResource **vbo_res,
void Visualization::createVertexVBO(VBO &vbo, struct cudaGraphicsResource *&vbo_res,
unsigned int vbo_res_flags)
{
createVertexVBO(vboID, size);
cudaGraphicsGLRegisterBuffer(vbo_res, *vboID, vbo_res_flags);
deleteCudaResource(vbo_res);
vbo.setBufferData(grid_xsize * grid_ysize * 3 * sizeof(float), 0L,
GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW);
cudaGraphicsGLRegisterBuffer(&vbo_res, vbo.getName(), vbo_res_flags);
checkCUDAError("Couldn't register GL buffer");
}
......@@ -574,13 +541,10 @@ void Visualization::createVertexVBO(GLuint* vboID, int size, struct cudaGraphics
This array buffer object therefore describes how single grid points (nodes)
get transformed into a triangle mesh (tesselation).
@param vbo pointer to an integer depicting the id of a
vertex buffer object
@param xsize number of grid nodes (in x-direction)
@params ysize number of grid nodes (in y-direction)
@return void
*/
void Visualization::createIndicesVBO(GLuint* vboID, int xsize, int ysize)
void Visualization::createIndicesVBO(int xsize, int ysize)
{
// Create an array describing the vertex indices to be drawn
......@@ -604,45 +568,24 @@ void Visualization::createIndicesVBO(GLuint* vboID, int xsize, int ysize)
}
}
// Create buffer object for vertex indices
glGenBuffers(1, vboID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, *vboID);
// Initialize buffer object
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint)*noVertices, vIndices, GL_STATIC_DRAW);
vboVerticesIndex.setBufferData(noVertices * sizeof(GLuint), vIndices,
GL_ELEMENT_ARRAY_BUFFER, GL_STATIC_DRAW);
// Switch to default buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
delete[] vIndices;
}
/**
Frees memory used by a vertex buffer object
@param vbo pointer to an integer depicting the id of a
vertex buffer object
*/
void Visualization::deleteVBO(GLuint* vbo)
{
if (vbo) {
glBindBuffer(1, *vbo);
glDeleteBuffers(1, vbo);
*vbo = 0;
}
}
/**
Frees memory used by a vertex buffer object and a CUDA resource
@param vbo pointer to an integer depicting the id of a
vertex buffer object
@param vbo_res pointer to a CUDA resource structure
*/
void Visualization::deleteVBO(GLuint* vbo, struct cudaGraphicsResource *vbo_res)
void Visualization::deleteCudaResource(struct cudaGraphicsResource *&vbo_res)
{
if (vbo) {
if (vbo_res != 0L) {
cudaGraphicsUnregisterResource(vbo_res);
deleteVBO(vbo);
vbo_res = 0L;
}
}
......@@ -660,13 +603,18 @@ void Visualization::initCUDA() {
printf("CUDA Driver Version: %d, Runtime Version: %d\n", driver, runtime);
// Select GPU for CUDA and OpenGL
memset( &prop, 0, sizeof( cudaDeviceProp ) );
memset(&prop, 0, sizeof(cudaDeviceProp));
prop.major = 1;
prop.minor = 0;
cudaChooseDevice( &dev, &prop );
cudaGLSetGLDevice( dev ) ;
}
void Visualization::modifyWaterScaling(float factor)
{
wScale *= factor;
}
/**
Sets current rendering mode
......@@ -689,7 +637,7 @@ void Visualization::toggleRenderingMode() {
break;
case WIREFRAME:
// Skip watershader if shaders not loaded
if (shaders->shadersLoaded()) {
if (waterShader->shadersLoaded()) {
renderMode = WATERSHADER;
} else {
renderMode = SHADED;
......@@ -701,3 +649,51 @@ void Visualization::toggleRenderingMode() {
}
}
void Visualization::height2Color(float height, GLfloat *color)
{
// Workaround "wrong" offset in colormap
height += 150;
if (height < -9000.0) {
color[0] = 0.0;
color[1] = 0.0;
color[2] = 0.2;
} else if (height < -8525.07) {
color[0] = 0.0;
color[1] = 0.0;
color[2] = mix(0.2, 1.0, (-9000-height)/(-9000+8525.07));
} else if (height < 189) {
color[0] = 0;
color[1] = mix(0.0, 1.0, (-8525.07-height)/(-8525.07-189));
color[2] = 1;
} else if (height < 190) {
float factor = (189-height)/(189-190);
color[0] = 0.0;
color[1] = mix(1.0, 0.4, factor);
color[2] = mix(1.0, 0.2, factor);
} else if (height < 1527.7) {
float factor = (190-height)/(190-1527.7);
color[0] = mix(0.0, 0.952941, factor);
color[1] = mix(0.4, 0.847059, factor);
color[2] = mix(0.2, 0.415686, factor);
} else if (height < 4219) {
float factor = (1527.7-height)/(1527.7-4219);
color[0] = mix(0.952941, 0.419577, factor);
color[1] = mix(0.847059, 0.184253, factor);
color[2] = mix(0.415686, 0.00648508, factor);
} else if (height < 4496.04) {
float factor = (4219-height)/(4219-4496.04);
color[0] = mix(0.419577, 0.983413, factor);
color[1] = mix(0.184253, 0.9561, factor);
color[2] = mix(0.00648508, 0.955749, factor);
} else if (height < 6000) {
float factor = (4496.04-height)/(4496.04-6000);
color[0] = mix(0.983413, 1.0, factor);
color[1] = mix(0.9561, 1.0, factor);
color[2] = mix(0.955749, 1.0, factor);
} else {
color[0] = 1.0;
color[1] = 1.0;
color[2] = 1.0;
}
}
......@@ -26,6 +26,8 @@
#include "camera.h"
#include "simulation.h"
#include "shader.h"
#include "vbo.h"
#include "../scenarios/SWE_VisInfo.h"
#ifdef USESDLTTF
#include "text.h"
#endif // USESDLTTF
......@@ -40,7 +42,8 @@ public:
// Constructor and Destructor
Visualization(int windowWidth, int windowHeight, const char* window_title, int _grid_xsize, int _grid_ysize);
~Visualization();
void init(Simulation* sim);
void init(Simulation &sim, SWE_VisInfo *visInfo = 0L);
void cleanUp();
Camera* camera;
......@@ -51,49 +54,60 @@ public:
// Main rendering function
void renderDisplay();
// Rescale water
void modifyWaterScaling(float factor);
// Helper functions
void setRenderingMode(RenderMode mode);
void updateBathymetryVBO(Simulation* sim);
void toggleRenderingMode();
int resizeWindow(int newWidth, int newHeight);
static bool isExtensionSupported(const char* szTargetExtension );
private:
// Init helper functions
void initSDL(int windowWidth, int windowHeight);
void initGLWindow(int width, int height);
void initGLDefaults();
void initCUDA();
bool IsExtensionSupported(const char* szTargetExtension );
void updateBathymetryVBO(Simulation &sim);
// Drawing functions
void DrawWaterSurface(GLuint vboID, GLuint vboNormals, GLuint verticesIndex);
void DrawBathymetry(GLuint vboID, GLuint verticesIndex);
void DrawWaterSurface();
void DrawBathymetry();
void DrawBottom();
int grid_xsize;
int grid_ysize;
// Vertex Buffer objects
GLuint vboBathymetry;
GLuint verticesIndex;
GLuint vboWaterSurface;
GLuint vboNormals;
VBO vboBathymetry;
VBO vboVerticesIndex;
VBO vboWaterSurface;
VBO vboNormals;
// Bathymetry color
VBO vboBathColor;
struct cudaGraphicsResource* cuda_vbo_watersurface;
struct cudaGraphicsResource* cuda_vbo_normals;
// VBO management functions
void createIndicesVBO(GLuint* vboID, int xsize, int ysize);
void createVertexVBO(GLuint* vboID, int size);
void createBathymetryVBO(GLuint* vboID, int size, Simulation* sim);
void createVertexVBO(GLuint* vboID, int size, struct cudaGraphicsResource **vbo_res,
void createIndicesVBO(int xsize, int ysize);
void createVertexVBO(VBO &vbo, struct cudaGraphicsResource *&vbo_res,
unsigned int vbo_res_flags);
void deleteVBO(GLuint* vbo);
void deleteVBO(GLuint* vbo, struct cudaGraphicsResource *vbo_res);
void deleteCudaResource(struct cudaGraphicsResource *&vbo_res);
// Rendering mode
RenderMode renderMode;
// Shader helper class
Shader* shaders;
// Water/Bathymetry scaling/offset
float wScale, bScale, bOffset;
/** Location of the water scaling in the shader */
GLint wScaleLocation;
// Shaders
Shader* waterShader;
#ifdef USESDLTTF
// Text helper class
......@@ -104,10 +118,10 @@ private:
// Helper function
int coord(int x, int y, int width = -1);
// VBO Extension Function Pointers
PFNGLGENBUFFERSARBPROC glGenBuffers; // VBO Name Generation Procedure
PFNGLBINDBUFFERARBPROC glBindBuffer; // VBO Bind Procedure
PFNGLBUFFERDATAARBPROC glBufferData; // VBO Data Loading Procedure
PFNGLDELETEBUFFERSARBPROC glDeleteBuffers; // VBO Deletion Procedure
static void height2Color(float height, GLfloat *color);
static GLfloat mix(GLfloat a, GLfloat b, float factor)
{
return a * (1-factor) + b * factor;
}
};
#endif
/**
* @file
* This file is part of SWE.
*
* @author Sebastian Rettenberger (rettenbs AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Sebastian_Rettenberger,_M.Sc.)
*
* @section LICENSE
*
* SWE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SWE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SWE. If not, see <http://www.gnu.org/licenses/>.
*
*
* @section DESCRIPTION
*
* Rescale water height in small Japan scenario
*/
#ifndef SWEASAGISCENARIO_VIS_HPP_
#define SWEASAGISCENARIO_VIS_HPP_
#include "SWE_VisInfo.h"
class SWE_AsagiJapanSmallVisInfo : public SWE_VisInfo
{
public:
virtual float waterVerticalScaling() { return 4.0f; };
virtual float bathyVerticalScaling() { return 0.010313f; };
};
#endif // SWEASAGISCENARIO_VIS_HPP_
......@@ -28,7 +28,8 @@
* Set bathymetry offset hence it is visible in the screen
*/
class SWE_BathymetryDamBreakVisInfo : public SWE_VisInfo {
float bathyVerticalOffset() { return 2500.0f; };
public:
float bathyVerticalOffset() { return 2450.0f; };
};
#endif
/**
* @file
* This file is part of SWE.
*
* @author Sebastian Rettenberger (rettenbs AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Sebastian_Rettenberger,_M.Sc.)
*
* @section LICENSE
*
* SWE is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* SWE is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SWE. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Logger.hpp"
tools::Logger tools::Logger::logger;
......@@ -3,6 +3,7 @@
* This file is part of SWE.
*
* @author Alexander Breuer (breuera AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Dipl.-Math._Alexander_Breuer)
* @author Sebastian Rettenberger (rettenbs AT in.tum.de, http://www5.in.tum.de/wiki/index.php/Sebastian_Rettenberger,_M.Sc.)
*
* @section LICENSE
*
......@@ -152,7 +153,7 @@ class tools::Logger {
* @param i_largeDelimiter definition of the large delimiter.
* @param i_indentation definition of the indentation (used in all messages, except welcome, start and finish).
*/
Logger( const int i_processRank = 0,
Logger( const int i_processRank = -1,
const std::string i_programName = "SWE",
const std::string i_welcomeMessage = "Welcome to",
const std::string i_copyRights = "\n\nSWE Copyright (C) 2012\n"
......@@ -180,9 +181,13 @@ class tools::Logger {
//set time to zero
cpuTime = cpuCommTime = wallClockTime = 0.;
#ifndef USEMPI
printWelcomeMessage();
#endif
#ifdef USEMPI
// determine local MPI rank
MPI_Comm_rank(MPI_COMM_WORLD, &processRank);
#else
processRank = 0;
printWelcomeMessage();
#endif
}
/**
......@@ -503,6 +508,10 @@ class tools::Logger {
<< i_cpuCommunicationTimeMessage << ": "
<< cpuCommTime << " seconds"<< std::endl;
}
public:
/** The logger all classes shoud use */
static Logger logger;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment