00001
00008 #include <sstream>
00009 #include "Error.h"
00010 #include "Matrix.h"
00011 #include "RTVolumeRenderer.h"
00012
00013 extern const char *volVertexShaderSource;
00014 extern const char *volPixelShaderSource;
00015
00016 #include "../Shaders/vol.vs"
00017 #include "../Shaders/vol.ps"
00018
00019
00020 const float PROJ_NEAR = 1.0f;
00021 const float PROJ_FAR = 100.0f;
00022
00023 const float ROTATION_MULTIPLIER = 0.5f;
00024 const float ZOOM_MULTIPLIER = 25.0f;
00025
00026 const float DELAY_DRAW_AMOUNT = 0.5f;
00027
00028 static int glOptions[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 32, 0 };
00029
00030 BEGIN_EVENT_TABLE(RTVolumeRenderer, wxGLCanvas)
00031 EVT_MOTION (RTVolumeRenderer::MouseMove)
00032 EVT_LEFT_UP (RTVolumeRenderer::MouseLeftUp)
00033 EVT_LEFT_DOWN (RTVolumeRenderer::MouseLeftDown)
00034 EVT_MOUSEWHEEL(RTVolumeRenderer::MouseWheel)
00035 EVT_KEY_DOWN (RTVolumeRenderer::KeyDown)
00036 END_EVENT_TABLE()
00037
00038
00039 RTVolumeRenderer::RTVolumeRenderer(wxWindow *parent, int w, int h)
00040 :
00041 wxGLCanvas(parent, wxID_ANY, wxDefaultPosition, wxSize(w, h), 0, wxT("Volume Renderer"), glOptions),
00042 drawCube(false),
00043 drawOutline(true),
00044 drawPlanes(true),
00045 useTexture(false),
00046 redraw(true),
00047 viewChanged(true),
00048 quickRendering(false),
00049 attachPlanesToView(true),
00050 delayDrawTimer(0.0f),
00051 mouseDown(false),
00052 lastMouseX(0),
00053 lastMouseY(0),
00054 dt(0.0f),
00055 width(w),
00056 height(h)
00057 {
00058 Show(true);
00059 SetCurrent();
00060
00061 InitOpenGL();
00062 ResizeRenderer(w, h);
00063
00064 cube.Init();
00065
00066 camera.SetMinRadius(1.0f);
00067
00068 shader.LoadFromMemory(volVertexShaderSource, volPixelShaderSource);
00069
00070 shader.SetTexture(0, "volTex");
00071 shader.SetTexture(1, "transferFunc");
00072
00073 SetLightDirection(Vector3f(0.0f, 0.0f, 1.0f));
00074 SetLightDiffuseColor(Colors::White);
00075
00076 shader.SetVector(0.1f, 0.1f, 0.1f, "Ambient");
00077
00078 CubeDef c;
00079 c.c = Point3f(0.0f, 0.0f, 0.0f);
00080 c.dim = 2.0f;
00081 frame = CreateFrame(c);
00082 }
00083
00084
00085 void RTVolumeRenderer::ResizeRenderer(int w, int h)
00086 {
00087 width = w;
00088 height = h;
00089
00090 SetMinSize(wxSize(w, h));
00091 SetMaxSize(wxSize(w, h));
00092 SetSize(w, h);
00093
00094 glViewport(0, 0, (float)width, (float)height);
00095
00096 Matrixf proj;
00097 proj.MakePerspective((float)width, (float)height, PROJ_NEAR, PROJ_FAR);
00098
00099 float glMat[16];
00100 proj.GetOpenGLMatrix(glMat);
00101
00102 glMatrixMode(GL_PROJECTION);
00103 glLoadIdentity();
00104 glMultMatrixf(glMat);
00105
00106 redraw = true;
00107 }
00108
00109
00110 void RTVolumeRenderer::InitOpenGL()
00111 {
00112
00113 GLenum err = glewInit();
00114 if(err != GLEW_OK)
00115 {
00116 std::stringstream s;
00117 s << "Glew could not be initialized: " << glewGetErrorString(err);
00118
00119 ErrorAndExit(s.str().c_str(), 1);
00120 }
00121
00122 if(!GLEW_VERSION_2_0)
00123 {
00124 std::stringstream s;
00125 s << "OpenGL 2.0 support is required to run this program.\n";
00126
00127 ErrorAndExit(s.str().c_str(), 1);
00128 }
00129
00130 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00131
00132 float glMat[16];
00133 camera.GetViewMatrix().GetOpenGLMatrix(glMat);
00134
00135 glMatrixMode(GL_MODELVIEW);
00136 glLoadIdentity();
00137 glMultMatrixf(glMat);
00138
00139 glEnable(GL_BLEND);
00140 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00141
00142 glEnable(GL_TEXTURE_3D);
00143 }
00144
00145
00146 void RTVolumeRenderer::SetLightDirection(const Vector3f &dir)
00147 {
00148 shader.SetVector(dir.x, dir.y, dir.z, "LDir");
00149 redraw = true;
00150 }
00151
00152
00153 void RTVolumeRenderer::SetLightDiffuseColor(const Color4f &c)
00154 {
00155 shader.SetVector(c.r, c.g, c.b, "LDiffuse");
00156 redraw = true;
00157 }
00158
00159
00160 void RTVolumeRenderer::ShouldDrawCube(bool yn)
00161 {
00162 drawCube = yn;
00163 redraw = true;
00164 }
00165
00166
00167 void RTVolumeRenderer::ShouldDrawCubeOutline(bool yn)
00168 {
00169 drawOutline = yn;
00170 redraw = true;
00171 }
00172
00173
00174 void RTVolumeRenderer::ShouldDrawPlanes(bool yn)
00175 {
00176 drawPlanes = yn;
00177 redraw = true;
00178 }
00179
00180
00181 void RTVolumeRenderer::UseVolumeTexture(bool yn)
00182 {
00183 useTexture = yn;
00184 redraw = true;
00185 }
00186
00187
00188 void RTVolumeRenderer::SetPlanes(int n)
00189 {
00190 cube.SetNumberOfPlanes(n);
00191 redraw = true;
00192 }
00193
00194
00195 void RTVolumeRenderer::SetBackgroundColor(const Color4f &c)
00196 {
00197 glClearColor(c.r, c.g, c.b, 0.0f);
00198 redraw = true;
00199 }
00200
00201
00202 void RTVolumeRenderer::SetCubeColor(const Color4f &c)
00203 {
00204 cube.SetCubeColor(c);
00205 redraw = true;
00206 }
00207
00208
00209 void RTVolumeRenderer::SetOutlineColor(const Color4f &c)
00210 {
00211 cube.SetOutlineColor(c);
00212 redraw = true;
00213 }
00214
00215
00216 void RTVolumeRenderer::SetPlaneColor(const Color4f &c)
00217 {
00218 cube.SetPlaneColor(c);
00219 redraw = true;
00220 }
00221
00222
00223 void RTVolumeRenderer::Clear()
00224 {
00225 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00226 }
00227
00228
00229 bool RTVolumeRenderer::LoadVolumeDataSet(const char *name, const char *path, VTInfo &info)
00230 {
00231 redraw = true;
00232 return volTex.Load(name, path, &info);
00233 }
00234
00235
00236 void RTVolumeRenderer::MouseMove(wxMouseEvent &m)
00237 {
00238 if(m.ButtonIsDown(wxMOUSE_BTN_LEFT))
00239 {
00240 float dx = (lastMouseX - m.m_x) * dt * ROTATION_MULTIPLIER;
00241 float dy = (lastMouseY - m.m_y) * dt * ROTATION_MULTIPLIER;
00242
00243 camera.RotateUp(dy);
00244 camera.RotateRight(dx);
00245
00246 lastMouseX = m.m_x;
00247 lastMouseY = m.m_y;
00248
00249 viewChanged = true;
00250 redraw = true;
00251 }
00252 }
00253
00254
00255 void RTVolumeRenderer::MouseLeftUp(wxMouseEvent &m)
00256 {
00257 mouseDown = false;
00258 redraw = true;
00259 }
00260
00261
00262 void RTVolumeRenderer::MouseLeftDown(wxMouseEvent &m)
00263 {
00264 lastMouseX = m.m_x;
00265 lastMouseY = m.m_y;
00266
00267 mouseDown = true;
00268 redraw = true;
00269
00270
00271 m.Skip();
00272 }
00273
00274
00275 void RTVolumeRenderer::MouseWheel(wxMouseEvent &m)
00276 {
00277 float amt = m.GetWheelRotation() / (float)m.GetWheelDelta();
00278 camera.Zoom(dt*amt*ZOOM_MULTIPLIER);
00279
00280 delayDrawTimer = DELAY_DRAW_AMOUNT;
00281 redraw = true;
00282 }
00283
00284
00285 void RTVolumeRenderer::TransferPlotChanged(TransferFunctionPlot *plot)
00286 {
00287 plot->UpdateTexture(&transferFunc);
00288 redraw = true;
00289 }
00290
00291
00292 void RTVolumeRenderer::KeyDown(wxKeyEvent &k)
00293 {
00294 int key = k.GetKeyCode();
00295 switch(key)
00296 {
00297 case 'A':
00298 camera.RotateRight(-10.0f * dt * ROTATION_MULTIPLIER);
00299 break;
00300
00301 case 'D':
00302 camera.RotateRight(10.0f * dt * ROTATION_MULTIPLIER);
00303 break;
00304
00305 case 'W':
00306 camera.RotateUp(-10.0f * dt * ROTATION_MULTIPLIER);
00307 break;
00308
00309 case 'S':
00310 camera.RotateUp(10.0f * dt * ROTATION_MULTIPLIER);
00311 break;
00312
00313 case 'Z':
00314 camera.Zoom(dt * ZOOM_MULTIPLIER);
00315 break;
00316
00317 case 'X':
00318 camera.Zoom(-dt * ZOOM_MULTIPLIER);
00319 break;
00320
00321 default:
00322 return;
00323 };
00324
00325 delayDrawTimer = DELAY_DRAW_AMOUNT;
00326
00327 viewChanged = true;
00328 redraw = true;
00329 }
00330
00331
00332 void RTVolumeRenderer::Draw()
00333 {
00334 float glMat[16];
00335 camera.GetViewMatrix().GetOpenGLMatrix(glMat);
00336
00337 glMatrixMode(GL_MODELVIEW);
00338 glLoadIdentity();
00339 glMultMatrixf(glMat);
00340
00341 if(quickRendering)
00342 {
00343 if(!redraw)
00344 return;
00345
00346 if(mouseDown || delayDrawTimer > 0.0f)
00347 {
00348 delayDrawTimer = std::max(0.0f, delayDrawTimer - dt);
00349
00350 Clear();
00351
00352 if(drawCube)
00353 cube.Draw();
00354 cube.DrawOutline();
00355
00356 SwapBuffers();
00357 return;
00358 }
00359 }
00360
00361 Clear();
00362
00363 if(attachPlanesToView && viewChanged)
00364 {
00365 cube.SetViewDirection(camera.ViewDirection());
00366 viewChanged = false;
00367 }
00368
00369 if(drawPlanes)
00370 {
00371 if(useTexture)
00372 {
00373 volTex.Bind(0);
00374 transferFunc.Bind(1);
00375 shader.Attach();
00376 cube.DrawPlanes();
00377 shader.Detach();
00378 transferFunc.UnBind();
00379 volTex.UnBind();
00380 }
00381 else
00382 {
00383 cube.DrawPlanes();
00384 }
00385 }
00386
00387 if(drawCube)
00388 cube.Draw();
00389 if(drawOutline)
00390 cube.DrawOutline();
00391
00392 SwapBuffers();
00393
00394 redraw = false;
00395 }