00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <QApplication>
00019 #include <QWidget>
00020 #include "mitkGPGPU.h"
00021
00022 #include <iostream>
00023
00024 #define GPGPU_INFO MITK_INFO("mitk.gpgpu")
00025 #define GPGPU_ERROR MITK_ERROR("mitk.gpgpu")
00026 #define GPGPU_CHECKGLERR MITK_ERROR(glGetError()!=GL_NO_ERROR)("mitk.gpgpu") << "GL ERROR @ "
00027
00028
00029 #define OPERATING_TEXTURE GL_TEXTURE15
00030
00031 static GLint convertTextureFormatToInternalFormatGL(mitk::GPGPU::TextureFormat format)
00032 {
00033 switch(format)
00034 {
00035 case mitk::GPGPU::FLOAT32_LUMINANCE: return GL_LUMINANCE_FLOAT32_ATI;
00036 case mitk::GPGPU::FLOAT32_LUMINANCE_ALPHA: return GL_LUMINANCE_ALPHA_FLOAT32_ATI;
00037 case mitk::GPGPU::FLOAT32_RGBA: return GL_RGBA32F_ARB;
00038 case mitk::GPGPU::UINT8_RGBA: return GL_RGBA8;
00039 }
00040 return 0;
00041 }
00042
00043 static GLint convertTextureFormatToFormatGL(mitk::GPGPU::TextureFormat format)
00044 {
00045 switch(format)
00046 {
00047 case mitk::GPGPU::FLOAT32_LUMINANCE: return GL_LUMINANCE;
00048 case mitk::GPGPU::FLOAT32_LUMINANCE_ALPHA: return GL_LUMINANCE_ALPHA;
00049 case mitk::GPGPU::FLOAT32_RGBA: return GL_RGBA;
00050 case mitk::GPGPU::UINT8_RGBA: return GL_RGBA;
00051 }
00052 return 0;
00053 }
00054
00055 static GLint convertTextureFormatToTypeGL(mitk::GPGPU::TextureFormat format)
00056 {
00057 switch(format)
00058 {
00059 case mitk::GPGPU::FLOAT32_LUMINANCE: return GL_FLOAT;
00060 case mitk::GPGPU::FLOAT32_LUMINANCE_ALPHA: return GL_FLOAT;
00061 case mitk::GPGPU::FLOAT32_RGBA: return GL_FLOAT;
00062 case mitk::GPGPU::UINT8_RGBA: return GL_UNSIGNED_BYTE;
00063 }
00064 return 0;
00065 }
00066
00067
00068 int mitk::GPGPU::Texture::GetWidth(){return myWidth;}
00069 int mitk::GPGPU::Texture::GetHeigth(){return myHeight;}
00070 int mitk::GPGPU::Texture::GetDepth(){return myDepth;}
00071
00072
00073 mitk::GPGPU::Texture::Texture(mitk::GPGPU::TextureFormat format,int width,int height,int depth)
00074 {
00075 if(depth==0)
00076 glTarget=GL_TEXTURE_2D;
00077 else
00078 glTarget=GL_TEXTURE_3D;
00079
00080 myFormat=format;
00081 myWidth=width;
00082 myHeight=height;
00083 myDepth=depth;
00084
00085 GLuint handle;
00086
00087 glGenTextures(1,&handle);
00088 glTextureHandle = handle;
00089 glActiveTexture(OPERATING_TEXTURE);
00090 glBindTexture(glTarget,glTextureHandle);
00091
00092 GPGPU_CHECKGLERR << "allocating texture handle";
00093
00094 if(glTarget==GL_TEXTURE_2D)
00095 {
00096 glTexImage2D(GL_TEXTURE_2D,0,convertTextureFormatToInternalFormatGL(myFormat),width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,0);
00097
00098
00099 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_R,GL_CLAMP_TO_EDGE);
00100 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
00101
00102 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
00103 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
00104
00105
00106 }
00107 else
00108 {
00109 glTexImage3D(GL_TEXTURE_3D,0,convertTextureFormatToInternalFormatGL(myFormat),width,height,depth,0,GL_RGBA,GL_UNSIGNED_BYTE,0);
00110
00111
00112 glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_R,GL_CLAMP_TO_EDGE);
00113 glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
00114 glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
00115
00116 glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
00117 glTexParameteri(GL_TEXTURE_3D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
00118
00119 }
00120
00121 GPGPU_CHECKGLERR << "declaring texture format&dimensions";
00122
00123 glGenFramebuffers(1,&handle);
00124 glFBOHandle = handle;
00125
00126 GPGPU_CHECKGLERR << "allocating framebuffer object";
00127 }
00128
00129 mitk::GPGPU::Texture::~Texture()
00130 {
00131 GLuint handle;
00132
00133 handle=glFBOHandle;
00134 glDeleteFramebuffers(1,&handle);
00135 GPGPU_CHECKGLERR << "deleting framebufferobject";
00136
00137 handle=glTextureHandle;
00138 glDeleteTextures(1,&handle);
00139 GPGPU_CHECKGLERR << "deleting texture handle";
00140 }
00141
00142 void mitk::GPGPU::Texture::ActivateAsSource(int unit)
00143 {
00144 glActiveTexture(GL_TEXTURE0 + unit);
00145 glBindTexture(glTarget,glTextureHandle);
00146
00147 GPGPU_CHECKGLERR << "binding texture to unit";
00148 }
00149
00150 void mitk::GPGPU::Texture::ActivateAsDestination()
00151 {
00152
00153 static GLenum buffers[5][4] =
00154 {
00155 { GL_NONE, GL_NONE, GL_NONE, GL_NONE },
00156 { GL_COLOR_ATTACHMENT0, GL_NONE, GL_NONE, GL_NONE },
00157 { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_NONE, GL_NONE },
00158 { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_NONE },
00159 { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 },
00160 };
00161
00162
00163 glBindFramebuffer( GL_FRAMEBUFFER, glFBOHandle );
00164 glDrawBuffers(4, buffers[1]);
00165 glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, glTarget,glTextureHandle,0);
00166
00167 GPGPU_CHECKGLERR << "associating texture to framebufferobject";
00168
00169 int error = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
00170 switch(error)
00171 {
00172 case GL_FRAMEBUFFER_COMPLETE_EXT:
00173 break;
00174 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
00175 GPGPU_ERROR << "Incomplete attachment\n";break;
00176 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
00177 GPGPU_ERROR << "Missing attachment\n";break;
00178 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
00179 GPGPU_ERROR << "Incomplete dimensions\n";break;
00180 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
00181 GPGPU_ERROR << "Incomplete formats\n";break;
00182 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
00183 GPGPU_ERROR << "Incomplete draw buffer\n";break;
00184 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
00185 GPGPU_ERROR << "Incomplete read buffer\n";break;
00186 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
00187 GPGPU_ERROR << "Framebufferobjects unsupported\n";break;
00188 default:
00189 GPGPU_ERROR << "unknown framebuffer status\n";break;
00190 }
00191
00192 glViewport(0,0,myWidth,myHeight);
00193
00194 GPGPU_CHECKGLERR << "setting viewport";
00195 }
00196
00197 void mitk::GPGPU::Texture::Upload(TextureFormat inputformat,const void *src)
00198 {
00199 glActiveTexture(OPERATING_TEXTURE);
00200 glBindTexture(glTarget,glTextureHandle);
00201
00202 if(glTarget==GL_TEXTURE_2D)
00203 {
00204 glTexSubImage2D(GL_TEXTURE_2D,0,0,0,myWidth,myHeight,convertTextureFormatToFormatGL(inputformat),convertTextureFormatToTypeGL(inputformat),src);
00205 }
00206 else
00207 {
00208 glTexSubImage3D(GL_TEXTURE_3D,0,0,0,0,myWidth,myHeight,myDepth,convertTextureFormatToFormatGL(inputformat),convertTextureFormatToTypeGL(inputformat),src);
00209
00210 }
00211
00212 GPGPU_CHECKGLERR << "texture upload to gpu";
00213
00214 }
00215
00216 void mitk::GPGPU::Texture::Download(TextureFormat inputformat,void *dst)
00217 {
00218 glActiveTexture(OPERATING_TEXTURE);
00219 glBindTexture(glTarget,glTextureHandle);
00220
00221 if(glTarget==GL_TEXTURE_2D)
00222 {
00223 glGetTexImage( GL_TEXTURE_2D,0,convertTextureFormatToFormatGL(inputformat),convertTextureFormatToTypeGL(inputformat),dst);
00224 GPGPU_CHECKGLERR << "texture download to cpu";
00225 }
00226 else
00227 {
00228 }
00229 }
00230
00231 static char stubVertexShader[] =
00232 "void main() { gl_Position = vec4( 2*gl_Vertex.xy-1,0,1 ); }\n";
00233
00234
00235 mitk::GPGPU::Shader::Shader(char *source)
00236 {
00237
00238
00239 glHandleVertex = glCreateShader(GL_VERTEX_SHADER);
00240 glHandleFragment = glCreateShader(GL_FRAGMENT_SHADER);
00241 glHandleProgram = glCreateProgram();
00242
00243 GLchar *src[2];
00244
00245 src[0] = stubVertexShader;
00246 src[1] = 0;
00247
00248 glShaderSource(glHandleVertex,1,(const GLchar **)src,0);
00249
00250 src[0] = source;
00251 src[1] = 0;
00252
00253 glShaderSource(glHandleFragment,1,(const GLchar **)src,0);
00254
00255 bool failed=false;
00256
00257 GLint _sv,_sf,_sl;
00258
00259 glCompileShader( glHandleVertex );
00260 GPGPU_CHECKGLERR << "compiling vertex shader";
00261 glGetShaderiv( glHandleVertex, GL_COMPILE_STATUS, &_sv);
00262 if( !_sv)
00263 {
00264 GPGPU_ERROR << "vertex shader compilation failed\n";
00265 failed=true;
00266 }
00267
00268 glCompileShader( glHandleFragment );
00269 GPGPU_CHECKGLERR << "compiling fragment shader";
00270 glGetShaderiv( glHandleFragment, GL_COMPILE_STATUS, &_sf);
00271 if( !_sf)
00272 {
00273 GPGPU_ERROR << "fragment shader compilation failed\n";
00274 failed=true;
00275 }
00276
00277 glAttachShader( glHandleProgram,glHandleVertex );
00278 glAttachShader( glHandleProgram,glHandleFragment );
00279 glLinkProgram( glHandleProgram );
00280 GPGPU_CHECKGLERR << "linking shader program";
00281 glGetProgramiv( glHandleProgram, GL_LINK_STATUS, &_sl);
00282 if( !_sl)
00283 {
00284 GPGPU_ERROR << "shader linkage failed\n";
00285 failed=true;
00286 }
00287
00288 if(failed)
00289 {
00290 int infologLength = 0;
00291 int charsWritten = 0;
00292 char *infoLog;
00293
00294 glGetProgramiv(glHandleProgram, GL_INFO_LOG_LENGTH,&infologLength);
00295
00296 if (infologLength > 0)
00297 {
00298 infoLog = (char *)malloc(infologLength);
00299 glGetProgramInfoLog(glHandleProgram, infologLength, &charsWritten, infoLog);
00300 GPGPU_ERROR << "SHADER CREATION FAILED INFOLOG:\n" << infoLog;
00301 free(infoLog);
00302 }
00303 }
00304
00305 }
00306
00307 mitk::GPGPU::Shader::~Shader()
00308 {
00309 glDeleteProgram( glHandleProgram);
00310 glDeleteShader( glHandleVertex );
00311 glDeleteShader( glHandleFragment );
00312 }
00313
00314 void mitk::GPGPU::Shader::Activate()
00315 {
00316 glUseProgram( glHandleProgram );
00317 GPGPU_CHECKGLERR << "activating shader";
00318 }
00319
00320 int mitk::GPGPU::Shader::GetUniformLocation(char *name)
00321 {
00322 return glGetUniformLocation(glHandleProgram,name);
00323 }
00324
00325
00326 void mitk::GPGPU::Shader::SetUniform(char *name,int i0)
00327 {
00328 glUniform1i( GetUniformLocation(name) , i0);
00329
00330 GPGPU_CHECKGLERR << "setting uniform";
00331 }
00332
00333 void mitk::GPGPU::Shader::SetUniform(char *name,int i0,int i1)
00334 {
00335 GLint i[2];
00336 i[0]=i0;
00337 i[1]=i1;
00338 glUniform2iv( GetUniformLocation(name) , 1 , i );
00339 GPGPU_CHECKGLERR << "setting uniform";
00340 }
00341
00342 void mitk::GPGPU::Shader::SetUniform(char *name,int i0,int i1,int i2)
00343 {
00344 GLint i[3];
00345 i[0]=i0;
00346 i[1]=i1;
00347 i[2]=i2;
00348 glUniform3iv( GetUniformLocation(name) , 1 , i );
00349 GPGPU_CHECKGLERR << "setting uniform";
00350 }
00351
00352 void mitk::GPGPU::Shader::SetUniform(char *name,int i0,int i1,int i2,int i3)
00353 {
00354 GLint i[4];
00355 i[0]=i0;
00356 i[1]=i1;
00357 i[2]=i2;
00358 i[3]=i3;
00359 glUniform4iv( GetUniformLocation(name) , 1 , i );
00360 GPGPU_CHECKGLERR << "setting uniform";
00361 }
00362
00363 void mitk::GPGPU::Shader::SetUniform(char *name,float i0)
00364 {
00365 GLint location = GetUniformLocation(name);
00366 glUniform1f(location,i0);
00367 GPGPU_CHECKGLERR << "setting uniform";
00368 }
00369
00370 void mitk::GPGPU::Shader::SetUniform(char *name,float i0,float i1)
00371 {
00372 GLfloat i[2];
00373 i[0]=i0;
00374 i[1]=i1;
00375 glUniform2fv(GetUniformLocation(name),1,i);
00376 GPGPU_CHECKGLERR << "setting uniform";
00377 }
00378
00379 void mitk::GPGPU::Shader::SetUniform(char *name,float i0,float i1,float i2)
00380 {
00381 GLfloat i[3];
00382 i[0]=i0;
00383 i[1]=i1;
00384 i[2]=i2;
00385 glUniform3fv(GetUniformLocation(name),1,i);
00386 GPGPU_CHECKGLERR << "setting uniform";
00387 }
00388
00389 void mitk::GPGPU::Shader::SetUniform(char *name,float i0,float i1,float i2,float i3)
00390 {
00391 GLfloat i[4];
00392 i[0]=i0;
00393 i[1]=i1;
00394 i[2]=i2;
00395 i[3]=i3;
00396 glUniform4fv(GetUniformLocation(name),1,i);
00397 GPGPU_CHECKGLERR << "setting uniform";
00398 }
00399
00400 #ifdef _WIN32
00401 LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
00402 {
00403 switch(msg)
00404 {
00405 case WM_CLOSE:
00406 DestroyWindow(hwnd);
00407 break;
00408 case WM_DESTROY:
00409 PostQuitMessage(0);
00410 break;
00411 default:
00412 return DefWindowProc(hwnd, msg, wParam, lParam);
00413 }
00414 return 0;
00415 }
00416 #endif
00417
00418 mitk::GPGPU::GPGPU()
00419 {
00420
00421 #ifdef _WIN32
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 HWND desktopWindow=QApplication::topLevelWidgets().at(0)->winId();
00467
00468 windowsContext = GetDC(desktopWindow);
00469
00470 if(windowsContext==0)
00471 std::cout << "failed getting window device context\n";
00472
00473 static PIXELFORMATDESCRIPTOR pfd =
00474 {
00475 sizeof(PIXELFORMATDESCRIPTOR),
00476 1,
00477 PFD_DRAW_TO_WINDOW |
00478 PFD_SUPPORT_OPENGL |
00479 PFD_DOUBLEBUFFER |
00480 PFD_SWAP_EXCHANGE ,
00481 PFD_TYPE_RGBA,
00482 24,
00483 0, 0, 0, 0, 0, 0,
00484 0,
00485 0,
00486 0,
00487 0, 0, 0, 0,
00488 0,
00489 0,
00490 0,
00491 PFD_MAIN_PLANE,
00492 0,
00493 0, 0, 0
00494 };
00495
00496
00497
00498 int iFormat = ChoosePixelFormat(windowsContext,&pfd);
00499 SetPixelFormat(windowsContext,iFormat,&pfd);
00500
00501
00502 openGLContext = wglCreateContext(windowsContext);
00503
00504 int errw=GetLastError();
00505
00506 if(openGLContext==0)
00507 std::cout << "failed creating openGL context "<<errw<<"\n";
00508
00509 #else
00510
00511 X_display = XOpenDisplay(NULL);
00512
00513 GPGPU_ERROR( !X_display ) << "cant open X display";
00514
00515 GLX_drawable = QApplication::topLevelWidgets().at(0)->winId();
00516
00517 GPGPU_ERROR( !GLX_drawable ) << "cant get toplevel widget from QT";
00518
00519 static int visAttributes[] = {
00520 GLX_RGBA,
00521 GLX_RED_SIZE, 1,
00522 GLX_GREEN_SIZE, 1,
00523 GLX_BLUE_SIZE, 1,
00524 GLX_DOUBLEBUFFER,
00525 None
00526 };
00527
00528 XVisualInfo *visinfo = glXChooseVisual(X_display, 0, visAttributes);
00529
00530 GPGPU_ERROR(!visinfo) << "Unable to choose specified visual!";
00531
00532 openGLContext = glXCreateContext(X_display, visinfo, 0, true);
00533
00534 if(visinfo)
00535 XFree(visinfo);
00536
00537 GPGPU_ERROR(!openGLContext) << "cant create GLX context";
00538
00539 #endif
00540
00541 Activate();
00542
00543 GPGPU_INFO << "initializing glew";
00544
00545 int err=glewInit();
00546
00547 GPGPU_CHECKGLERR << "initializing glew";
00548 GPGPU_ERROR(GLEW_OK != err) << "glewInit() fails with " << err << " as text: " << glewGetErrorString(err);
00549
00550 glMatrixMode(GL_PROJECTION);
00551 glLoadIdentity();
00552 glOrtho(0,1,0,1,-1,1);
00553 glMatrixMode(GL_MODELVIEW);
00554 glLoadIdentity();
00555
00556 GPGPU_CHECKGLERR << "intializing projection&modelview matrix";
00557
00558 glDisable(GL_CULL_FACE);
00559 glShadeModel(GL_SMOOTH);
00560 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00561 glClearDepth(1.0f);
00562 glDisable(GL_DEPTH_TEST);
00563 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
00564 glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
00565 glDepthMask(false);
00566
00567 GPGPU_CHECKGLERR << "setting up openGL context";
00568 }
00569
00570 mitk::GPGPU::~GPGPU()
00571 {
00572 #ifdef _WIN32
00573
00574 wglDeleteContext( openGLContext );
00575
00576 #else
00577
00578 if(openGLContext)
00579 glXDestroyContext(X_display,openGLContext);
00580
00581 if(X_display)
00582 XCloseDisplay(X_display);
00583
00584 #endif
00585
00586 }
00587
00588 void mitk::GPGPU::Activate()
00589 {
00590
00591 #ifdef _WIN32
00592 wglMakeCurrent(windowsContext,openGLContext);
00593 #else
00594 glXMakeCurrent(X_display, GLX_drawable, openGLContext);
00595 #endif
00596
00597 GPGPU_CHECKGLERR << "activating openGL context";
00598 }
00599
00600 void mitk::GPGPU::Deactivate()
00601 {
00602 }
00603
00604 void mitk::GPGPU::Run()
00605 {
00606 glBegin( GL_TRIANGLE_STRIP );
00607 glVertex2f( 0,0 );
00608 glVertex2f( 0,1 );
00609 glVertex2f( 1,0 );
00610 glVertex2f( 1,1 );
00611 glEnd();
00612
00613 GPGPU_CHECKGLERR << "running a shader";
00614 }
00615
00616 void mitk::GPGPU::Run(float start,float end)
00617 {
00618 glBegin( GL_TRIANGLE_STRIP );
00619 glVertex2f( 0,start );
00620 glVertex2f( 0,end );
00621 glVertex2f( 1,start );
00622 glVertex2f( 1,end );
00623 glEnd();
00624
00625 GPGPU_CHECKGLERR << "running a shader";
00626 }
00627
00628