Commit 28617cff authored by bader's avatar bader

added OpenGL Visualisation for SWE - all classes

parent 92e9df5b
// =====================================================================
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Tobias Schnabel
//
// SWE_CUDA is free software: you can redristribute 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_CUDA 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_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
#include "camera.h"
#include <sstream>
/**
Constructor
@param view_distance initial view distance from the origin
@param window_title title of the current window
*/
Camera::Camera(float view_distance, const char* window_title) {
// Initialize member variables
cameraX = -0.3f;
cameraY = 1.0f;
cameraZ = 2.0f;
objectX = 0.0f;
objectY = 0.0f;
objectZ = 0.0f;
angleX = 0.0f;
angleY = 0.0f;
zoomfactor = 0.85f*view_distance;
win_title = window_title;
frames = 0;
lastTime = 0;
oldMouseX = 0;
oldMouseY = 0;
// Reset framebuffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
/**
Set the camera via gluLookAt and set the light position afterwards
*/
void Camera::setCamera() {
// Clear our buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Set camera position, center of scene and up vector
gluLookAt(cameraX*zoomfactor, cameraY*zoomfactor, cameraZ*zoomfactor,
0,0,0, // center of scene
0, 1, 0); // up vector
// Translate and rotate our object
glTranslated(objectX, objectY, objectZ);
this->rotateObject();
glScalef(1.0f, 1.0f, -1.0f);
// Position the light source
// Note: Coordinates are multiplied by current modelview-matrix
// by OpenGL
GLfloat LightPosition[]= { 1.0f, 1.0f, 0.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_POSITION,LightPosition);
}
/**
Rotate camera
*/
void Camera::rotateObject() {
glRotatef(angleX, 1.0, 0.0f, 0.0f);
glRotatef(angleY, 0.0f, 1.0f, 0.0f);
}
/**
Increment viewing orientation of the camera
@param angle_dX angle relative to the x-axis
@param angle_dY angle relative to the rotated y-axis
*/
void Camera::orient( float angle_dX, float angle_dY )
{
angleX += angle_dX;
angleY += angle_dY;
}
/**
Zoom in
@param scaleFactor factor which is used for zooming
*/
void Camera::zoomIn( float scaleFactor )
{
if (zoomfactor > 3.0f) {
zoomfactor /= scaleFactor;
}
}
/**
Zoom out
@param scaleFactor factor which is used for zooming
*/
void Camera::zoomOut( float scaleFactor )
{
zoomfactor *= scaleFactor;
}
/**
Calculates the current framerate, updates the window title and
swaps framebuffers to display the new image
*/
void Camera::displayImage() {
// Set up stringstream for window title
std::stringstream ss;
ss.setf(std::ios::fixed, std::ios::floatfield);
ss.setf(std::ios::showpoint);
ss.precision(1);
// Calculate framerate
float fps;
frames++;
if (lastTime == 0) {
lastTime = SDL_GetTicks();
} else if( (SDL_GetTicks() - lastTime) >= 500) {
fps = (float)frames/(SDL_GetTicks() - lastTime)*1000.0f;
ss << win_title << " (" << fps << " fps)";
SDL_WM_SetCaption(ss.str().c_str(), NULL);
frames = 0;
lastTime = SDL_GetTicks();
}
// Swap frame buffer
SDL_GL_SwapBuffers();
}
/**
User starts dragging.
Remember the old mouse coordinates.
*/
void Camera::startPanning(int xPos, int yPos) {
oldMouseX = xPos;
oldMouseY = yPos;
}
/**
User drags our object.
Transform screen coordinates into world coordinates
and update the objects position
*/
void Camera::panning(int newX, int newY) {
GLint viewport[4];
GLdouble modelview[16];
GLdouble projection[16];
GLfloat winX, winY, winZ;
GLdouble posX, posY, posZ;
GLdouble pos2X, pos2Y, pos2Z;
GLdouble dX, dY, dZ;
// Draw invisible fake plane
setCamera();
glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
GLfloat dim = 100000.0f;
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 0.3f);
glVertex3f( dim,0.0f, dim);
glVertex3f(-dim,0.0f, dim);
glVertex3f(-dim,0.0f, -dim);
glVertex3f( dim,0.0f, -dim);
glEnd();
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
// Get projection matrices
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
glGetDoublev( GL_PROJECTION_MATRIX, projection );
glGetIntegerv( GL_VIEWPORT, viewport );
// Get drag positions in object coordinates
winX = (GLfloat)newX;
winY = (GLfloat)viewport[3] - (GLfloat)newY;
glReadPixels( newX, GLint(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
winX = (GLfloat)oldMouseX;
winY = (GLfloat)viewport[3] - (GLfloat)oldMouseY;
glReadPixels( oldMouseX, GLint(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
gluUnProject( winX, winY, winZ, modelview, projection, viewport, &pos2X, &pos2Y, &pos2Z);
glClear(GL_DEPTH_BUFFER_BIT);
// Calculate drag distances
dX = (posX-pos2X);
dY = (posY-pos2Y);
dZ = (posZ-pos2Z);
// Convert drag distances to world coordinates
glPushMatrix();
glLoadIdentity();
rotateObject();
glScalef(1.0f, 1.0f, -1.0f);
glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
GLdouble x = modelview[0]*dX + modelview[4]*dY + modelview[8]*dZ;
GLdouble y = modelview[1]*dX + modelview[5]*dY + modelview[9]*dZ;
GLdouble z = modelview[2]*dX + modelview[6]*dY + modelview[10]*dZ;
glPopMatrix();
// Set the new world coordinates of our object
objectX += x;
objectY += y;
objectZ += z;
// Save our current mouse position
oldMouseX = newX;
oldMouseY = newY;
}
\ No newline at end of file
#ifndef CAMERA_H
#define CAMERA_H
// =====================================================================
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Tobias Schnabel
//
// SWE_CUDA is free software: you can redristribute 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_CUDA 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_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
#include <SDL.h>
#include <SDL_opengl.h>
class Camera {
public:
Camera(float view_distance, const char* window_title);
// Set modelview matrix
void setCamera ();
// Change viewing properties
void orient( float angX, float angY );
void zoomIn( float scaleFactor );
void zoomOut( float scaleFactor );
void startPanning(int xPos, int yPos);
void panning(int newX, int newY);
// Update framebuffer
void displayImage();
private:
// Position of the camera
float cameraX;
float cameraY;
float cameraZ;
// Position of the object
GLdouble objectX;
GLdouble objectY;
GLdouble objectZ;
// Zoom factor
float zoomfactor;
float angleX, angleY;
// Helper variables
unsigned int frames;
unsigned int lastTime;
unsigned int oldMouseX, oldMouseY;
unsigned int newMouseX, newMouseY;
// Window title
const char* win_title;
void rotateObject();
};
#endif
\ No newline at end of file
// =====================================================================
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Tobias Schnabel
//
// SWE_CUDA is free software: you can redristribute 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_CUDA 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_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
#include "controller.h"
#include "../scenarios/SWE_simple_scenarios_vis.h"
/**
Constructor
@param sim instance of simulation class
@param vis instance of visualization class
*/
Controller::Controller(Simulation* sim, Visualization* vis) {
simulation = sim;
visualization = vis;
isActive = true;
done = false;
paused = false;
allowStep = false;
}
/**
Process all user events in a loop
Returns true, when user wants to quit
*/
bool Controller::handleEvents() {
// Handle events
SDL_Event event;
allowStep = false;
while ( SDL_PollEvent(&event) )
{
switch( event.type )
{
case SDL_MOUSEMOTION:
if (event.motion.state & SDL_BUTTON(SDL_BUTTON_LEFT)) {
// Left mouse button dragging
visualization->camera->orient(0.5f*event.motion.yrel, 0.5f*event.motion.xrel);
}
else if (event.motion.state & SDL_BUTTON(SDL_BUTTON_RIGHT)) {
// Panning happens here
visualization->camera->panning(event.motion.x, event.motion.y);
}
break;
case SDL_MOUSEBUTTONDOWN:
// Scroll wheel down
if ( event.button.button == SDL_BUTTON_WHEELDOWN ) {
// Zoom out
visualization->camera->zoomOut(1.2f);
} else if (event.button.button == SDL_BUTTON_RIGHT) {
visualization->camera->startPanning(event.button.x, event.button.y);
}
break;
case SDL_MOUSEBUTTONUP:
// Scroll wheel up
if ( event.button.button == SDL_BUTTON_WHEELUP ) {
// Zoom in
visualization->camera->zoomIn(1.15f);
}
break;
case SDL_ACTIVEEVENT:
// Don't draw anything if we're getting minimized
if ( event.active.state & SDL_APPACTIVE ) {
isActive = (event.active.gain != 0);
}
break;
case SDL_VIDEORESIZE:
// Our window was resized
visualization->resizeWindow(event.resize.w, event.resize.h);
break;
case SDL_KEYDOWN:
// User has pressed a key
done = handleKeyPress( &event.key.keysym);
break;
case SDL_QUIT:
// Window close request
done = true;
break;
default:
break;
}
}
return done;
}
/**
Returns true, when window has focus
*/
bool Controller::hasFocus() {
return isActive && !done;
}
/**
Return whether program is currently paused
*/
bool Controller::isPaused() {
return paused && !allowStep;
}
/**
Process single keyboard event
@param *keysym pointer to the sdl keyevent structure
*/
bool Controller::handleKeyPress( SDL_keysym *keysym) {
switch ( keysym->sym ) {
case SDLK_ESCAPE:
// ESC key was pressed -> exit
return true;
break;
case SDLK_r:
// Restart simulation
allowStep = paused;
simulation->restart();
break;
case SDLK_w:
// Switch rendering mode
visualization->toggleRenderingMode();
break;
case SDLK_s:
// Save simulation data to file
simulation->saveToFile();
break;
case SDLK_RIGHT:
// Advance single timestep when paused
allowStep = paused;
break;
case SDLK_SPACE:
// Pause/Resume
paused = !paused;
break;
case SDLK_1:
// Load scenario 1
{
allowStep = paused;
SWE_RadialDamBreakScenarioVisInfo*
newScene = new SWE_RadialDamBreakScenarioVisInfo();
SWE_VisInfo* visInfo = newScene;
// define grid size and initial time step
float dx = (newScene->getBoundaryPos(BND_RIGHT) - newScene->getBoundaryPos(BND_LEFT) )/SWE_Block::getNx();
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, visInfo);
visualization->updateBathymetryVBO(simulation);
}
break;
case SDLK_2:
// Load scenario 2
{
allowStep = paused;
SWE_Scenario* newScene = new SWE_BathymetryDamBreakScenario;
// define grid size and initial time step
float dx = (newScene->getBoundaryPos(BND_RIGHT) - newScene->getBoundaryPos(BND_LEFT) )/SWE_Block::getNx();
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);
}
break;
case SDLK_3:
// Load scenario 3
{
allowStep = paused;
SWE_SplashingPoolScenarioVisInfo*
newScene = new SWE_SplashingPoolScenarioVisInfo;
// define grid size and initial time step
float dx = (newScene->getBoundaryPos(BND_RIGHT) - newScene->getBoundaryPos(BND_LEFT) )/SWE_Block::getNx();
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, newScene);
visualization->updateBathymetryVBO(simulation);
}
break;
default:
break;
}
return false;
}
#ifndef CONTROLLER_H
#define CONTROLLER_H
// =====================================================================
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Tobias Schnabel
//
// SWE_CUDA is free software: you can redristribute 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_CUDA 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_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
#include <SDL.h>
#include "simulation.h"
#include "visualization.h"
class Controller {
public:
Controller(Simulation* sim, Visualization* vis);
// Process new events
bool handleEvents();
// Return if window is enabled
bool hasFocus();
// Return if program is paused
bool isPaused();
private:
// Internal functions
bool isActive;
bool done;
bool paused;
bool allowStep;
// References to other classes
Simulation* simulation;
Visualization* visualization;
// Handle keyboard events
bool handleKeyPress( SDL_keysym *keysym);
};
#endif
\ No newline at end of file
// =====================================================================
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Tobias Schnabel
//
// SWE_CUDA is free software: you can redristribute 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_CUDA 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_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
varying vec3 V;
varying vec3 N;
varying vec4 ambient;
/* Shading of water surfaces with fresnel effect */
void main()
{
// Helper variable for color
vec4 color = ambient;
// Get normal and view vector
vec3 view = normalize(V);
vec3 normal = normalize(N); ;
if (!gl_FrontFacing) {
// Handle backface rendering
normal = -normal;
}
// Compute fresnel factor
float fresnelFactor = 0.1+0.1*pow(1+dot(normal,view), 3.0);
// Combine color with fresnel factor
color += gl_LightSource[0].specular * fresnelFactor;
color = mix(color, vec4(0.2, 0.4, 0.9, 1.0), 0.2);
// Set constant transparency
gl_FragColor = vec4(color.xyz, 0.7);
}
// =====================================================================
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Tobias Schnabel
//
// SWE_CUDA is free software: you can redristribute 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_CUDA 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_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
#include "shader.h"
/**
Constructor.
Check whether shaders are supported. If yes, load vertex and fragment
shader from textfile into memory and compile
@param vertexShaderFile name of the text file containing the vertex
shader code
@param fragmentShaderFile name of the text file containing the fragment
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");
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;
fragmentShaderSource = NULL;
readSuccess = readShaderFile(vertexShaderFile, vertexShaderSource, vertexShaderLength);
readSuccess &= readShaderFile(fragmentShaderFile, fragmentShaderSource, fragmentShaderLength);
// Check if reading was completed
if (readSuccess) {
// Create Vertex-Shader
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, const_cast<GLchar const **>(&vertexShaderSource), &vertexShaderLength);
glCompileShader(vertexShader);
// Create Fragment-Shader
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, const_cast<GLchar const **>(&fragmentShaderSource), &fragmentShaderLength);
glCompileShader(fragmentShader);
if (isShaderCompiled(vertexShader, "Vertex-Shader")
&& isShaderCompiled(fragmentShader, "Fragment-Shader"))
{
// Create Shader program
program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
shdrLoaded = true;
} else {
// Errors while compiling shaders
shdrSupport = false;
glDeleteShader(vertexShader);
delete[] vertexShaderSource;
glDeleteShader(fragmentShader);
delete[] fragmentShaderSource;
}
} else {
if (vertexShaderSource != NULL) delete[] vertexShaderSource;
if (fragmentShaderSource != NULL) delete[] fragmentShaderSource;
}
}
}
/**
Destructor.
Unload shaders and free resources.
*/
Shader::~Shader() {
// Unload Shaders
if (shdrLoaded) {
glUseProgram(0);
glDeleteProgram(program);
glDetachShader(program, vertexShader);
glDeleteShader(vertexShader);
delete[] vertexShaderSource;
glDetachShader(program, fragmentShader);
glDeleteShader(fragmentShader);
delete[] fragmentShaderSource;
}
}
/**
Replaces OpenGL shaders by our custom shaders
*/
void Shader::enableShader() {
if (shdrLoaded) {
glUseProgram(program);
}
}
/**
Restores OpenGL default shaders
*/
void Shader::disableShader() {
if (shdrLoaded) {
glUseProgram(0);
}
}
/**
Returns, whether shaders are supported by graphics hardware
*/
bool Shader::shadersSupported() {
return shdrSupport;
}
/**
Returns, whether shaders could by loaded successfully
*/
bool Shader::shadersLoaded() {
return shdrLoaded;
}
/**
Returns, whether a special extension is supported by the current
graphics card
@param szTargetExtention string describing the extension to look for
*/
bool Shader::isExtensionSupported(const char* szTargetExtension )
{
const unsigned char *pszExtensions = NULL;
const unsigned char *pszStart;
unsigned char *pszWhere, *pszTerminator;
// Extension names should not have spaces
pszWhere = (unsigned char *) strchr( szTargetExtension, ' ' );
if( pszWhere || *szTargetExtension == '\0' )
return false;
// Get Extensions String
pszExtensions = glGetString( GL_EXTENSIONS );
// Search The Extensions String For An Exact Copy
pszStart = pszExtensions;
for(;;)
{
pszWhere = (unsigned char *) strstr( (const char *) pszStart, szTargetExtension );
if( !pszWhere )
break;
pszTerminator = pszWhere + strlen( szTargetExtension );
if( pszWhere == pszStart || *( pszWhere - 1 ) == ' ' )
if( *pszTerminator == ' ' || *pszTerminator == '\0' )
return true;
pszStart = pszTerminator;
}
return false;
}
/**
Returns, whether a special extension is supported by the current
graphics card
@param filename shader file
@return shaderSource file content
@return length length of the file
@returns bool true, if file has been read successfully
*/
bool Shader::readShaderFile(char const * filename, GLchar * & shaderSource, GLint & length)
{
using namespace std;
string fullFileName = "";
// On unix: determine directory of exec
#ifdef __unix__
// Code taken from:
// http://www.gamedev.net/community/forums/topic.asp?topic_id=459511
std::string path = "";
pid_t pid = getpid();
char buf[20] = {0};
sprintf(buf,"%d",pid);
std::string _link = "/proc/";
_link.append( buf );
_link.append( "/exe");
char proc[512];
int ch = readlink(_link.c_str(),proc,512);
if (ch != -1) {
proc[ch] = 0;
path = proc;
std::string::size_type t = path.find_last_of("/");
path = path.substr(0,t);
}
fullFileName = path + string("/");
#endif
fullFileName.append(filename);
ifstream file(fullFileName.c_str(), ios::in);
length = 0;
if (!file.good())
{
return false;
}
file.seekg(0, ios::end);
length = file.tellg();
file.seekg(ios::beg);
if (length == 0 )
{
return false;
}
shaderSource = new GLchar[length];
if (shaderSource == 0)
{
return false;
}
memset(shaderSource, 0, length);
file.read(shaderSource, length);
file.close();
return true;
}
/**
Returns, whether a shader has been compiled with success
@param shader shader id
@param prefix custom error message
*/
bool Shader::isShaderCompiled(GLuint shader, char const * prefix)
{
using namespace std;
GLint compiled(0);
glGetObjectParameterivARB(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled)
{
GLint maxLength(0);
glGetShaderiv(shader, GL_INFO_LOG_LENGTH , &maxLength);
cerr << prefix
<< " -- Compiler Log: "
<< endl
;
if (maxLength > 1)
{
GLchar * log = new GLchar[maxLength];
glGetShaderInfoLog(shader, maxLength, 0, log);
cerr << log
;
delete[] log;
}
}
return (compiled != 0);
}
/**
Returns, whether a shader has been linked with success
@param shader shader id
@param prefix custom error message
*/
bool Shader::isProgramLinked(GLuint program, char const * prefix)
{
using namespace std;
GLint linked(0);
glGetObjectParameterivARB(program, GL_LINK_STATUS, &linked);
if (!linked)
{
GLint maxLength(0);
glGetShaderiv(program, GL_INFO_LOG_LENGTH , &maxLength);
cerr << prefix
<< " -- Linker Log: "
<< endl
;
if (maxLength > 1)
{
GLchar * log = new GLchar[maxLength];
glGetProgramInfoLog(program, maxLength, 0, log);
cerr << log
;
delete[] log;
}
}
return (linked != 0);
}
#ifndef SHADER_H
#define SHADER_H
// =====================================================================
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Tobias Schnabel
//
// SWE_CUDA is free software: you can redristribute 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_CUDA 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_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
#include <SDL.h>
#include <SDL_opengl.h>
#include <iostream>
#include <fstream>
class Shader {
public:
// Constructor and Destructor
// Load vertex shader file and fragment shader file
Shader(char const * vertexShaderFile, char const * fragmentShaderFile) ;
~Shader();
// Check if shaders are supported
bool shadersSupported();
bool shadersLoaded();
// Shader control
void enableShader();
void disableShader();
private:
// State flags
bool shdrSupport;
bool shdrLoaded;
// Helper functions
bool readShaderFile(char const * filename, GLchar * & shaderSource, GLint & length);
bool isExtensionSupported(const char* szTargetExtension );
bool isShaderCompiled(GLuint shader, char const * prefix);
bool isProgramLinked(GLuint program, char const * prefix);
// Vertex-Shader
GLuint vertexShader;
GLchar * vertexShaderSource;
GLint vertexShaderLength;
// Fragment-Shader
GLuint fragmentShader;
GLchar * fragmentShaderSource;
GLint fragmentShaderLength;
// Shaders id
GLuint program;
// Shader extension function pointers
PFNGLCREATESHADERPROC glCreateShader;
PFNGLCREATEPROGRAMPROC glCreateProgram;
PFNGLATTACHSHADERPROC glAttachShader;
PFNGLCOMPILESHADERPROC glCompileShader;
PFNGLUSEPROGRAMPROC glUseProgram;
PFNGLDETACHSHADERPROC glDetachShader;
PFNGLDELETESHADERPROC glDeleteShader;
PFNGLLINKPROGRAMPROC glLinkProgram;
PFNGLSHADERSOURCEPROC glShaderSource;
PFNGLDELETEPROGRAMPROC glDeleteProgram;
// Shader objects extension pointers
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
PFNGLGETSHADERIVPROC glGetShaderiv;
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
};
#endif
This diff is collapsed.
#ifndef SIMULATION_H
#define SIMULATION_H
// =====================================================================
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Michael Bader, Kaveh Rahnema, Tobias Schnabel
//
// SWE_CUDA is free software: you can redristribute 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_CUDA 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_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
#include <math.h>
#include <cuda_runtime.h>
#include "../SWE_BlockCUDA.hh"
#include "../scenarios/SWE_Scenario.h"
#include "../scenarios/SWE_VisInfo.h"
void checkCUDAError(const char *msg);
class Simulation {
public:
// Constructor + Destructor
Simulation (int nx, int ny, float dx, float dy,
SWE_Scenario* scene, SWE_VisInfo* visInfo, SWE_BlockCUDA* init_splash);
~Simulation();
// Restart simulation
void restart();
// Load new scenario after initialization
void loadNewScenario(SWE_Scenario* scene, SWE_VisInfo* visInfo);
// Save simulation state to file
void saveToFile();
// Return the bathymetry data
void setBathBuffer(float* output);
// Simulate single timestep on graphics card
void runCuda(struct cudaGraphicsResource **vbo_resource, struct cudaGraphicsResource **vbo_normals);
// Debugging
void writeDebugOutput(float3* destBuffer = NULL);
protected:
// Instance of SWE_BlockCUDA
SWE_BlockCUDA* splash;
// Current scenario
SWE_Scenario* myScenario;
// Current simulation time
float curTime;
// Is this our first simulation step?
int isFirstStep;
// Maximum of cell sizes
float maxCellSize;
// Scaling factors used by visualization
float bOffset, bScale, wOffset, wScale, bAverage, wAverage;
// Initalize boundaries defined by the scene
void initBoundaries(SWE_Scenario* scene);
// Initalize boundaries defined by an input file
int fileNumber;
// Use file input as boundary data
bool useFileInput;
// Holds maximum dimension
int maxDim;
// Compute new water surface
void calculateWaterSurface(float3* destBuffer);
// Compute normals of the water surface for shading
void calculateNormals(float3* vertexBuffer, float3* destBuffer);
void getScalingApproximation(const Float2D& h, const Float2D& b);
void updateVisBuffer(float3* _visBuffer);
void debugVisBuffer(float3* _visBuffer);
/**
Scale function used for visualization
*/
__device__ __host__
static float scaleFunction(float val, float average, float scale, float offset) {
return (val - average)*scale + offset;
}
static void calculateNormal(float fVert1[], float fVert2[],
float fVert3[], float fNormal[]);
};
#endif
This diff is collapsed.
#ifndef VISUALIZATION_H
#define VISUALIZATION_H
// =====================================================================
// This file is part of SWE_CUDA (see file SWE_Block.cu for details).
//
// Copyright (C) 2010,2011 Tobias Schnabel
//
// SWE_CUDA is free software: you can redristribute 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_CUDA 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_CUDA. If not, see <http://www.gnu.org/licenses/>.
// =====================================================================
#include <SDL.h>
#include <SDL_opengl.h>
#include <cuda_runtime.h>
#include <cuda_gl_interop.h>
#include "camera.h"
#include "simulation.h"
#include "shader.h"
void checkCUDAError(const char *msg);
typedef enum RenderMode {
SHADED, WIREFRAME, WATERSHADER
} RenderMode;
class Visualization {
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 cleanUp();
Camera* camera;
// Access to CUDA VBO pointers
cudaGraphicsResource** getCudaNormalsPtr();
cudaGraphicsResource** getCudaWaterSurfacePtr();
// Main rendering function
void renderDisplay();
// Helper functions
void setRenderingMode(RenderMode mode);
void updateBathymetryVBO(Simulation* sim);
void toggleRenderingMode();
int resizeWindow(int newWidth, int newHeight);
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 );
// Drawing functions
void DrawWaterSurface(GLuint vboID, GLuint vboNormals, GLuint verticesIndex);
void DrawBathymetry(GLuint vboID, GLuint verticesIndex);
void DrawBottom();
int grid_xsize;
int grid_ysize;
// Vertex Buffer objects
GLuint vboBathymetry;
GLuint verticesIndex;
GLuint vboWaterSurface;
GLuint vboNormals;
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,
unsigned int vbo_res_flags);
void deleteVBO(GLuint* vbo);
void deleteVBO(GLuint* vbo, struct cudaGraphicsResource *vbo_res);
// Rendering mode
RenderMode renderMode;
// Shader helper class
Shader* shaders;
// 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
};
#endif
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