00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #include "GLContext.h"
00047
00048 #include "Image/ByteImage.h"
00049
00050 #include <stdio.h>
00051 #include <memory.h>
00052
00053
00054
00055 #ifdef WIN32
00056
00057 CGLContext::CGLContext()
00058 {
00059 m_hDC = NULL;
00060 m_hBmp = NULL;
00061 m_hBmpOld = NULL;
00062 m_hGLRC = NULL;
00063
00064 m_nWidth = 0;
00065 m_nHeight = 0;
00066 m_pPixels = NULL;
00067 }
00068 CGLContext::~CGLContext()
00069 {
00070 DeleteContext();
00071 }
00072
00073 bool CGLContext::CreateContext(int width, int height, void *shareContext)
00074 {
00075 m_hDC = CreateCompatibleDC(NULL);
00076 if (!m_hDC)
00077 {
00078 printf("ERROR: couldn't allocate DC\n");
00079
00080 return false;
00081 }
00082
00083 BITMAPINFO bminfo;
00084
00085 bminfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00086 bminfo.bmiHeader.biWidth = width;
00087 bminfo.bmiHeader.biHeight = height;
00088 bminfo.bmiHeader.biPlanes = 1;
00089 bminfo.bmiHeader.biBitCount = 24;
00090 bminfo.bmiHeader.biCompression = BI_RGB;
00091 bminfo.bmiHeader.biSizeImage = 0;
00092 bminfo.bmiHeader.biXPelsPerMeter = 1;
00093 bminfo.bmiHeader.biYPelsPerMeter = 1;
00094 bminfo.bmiHeader.biClrUsed = 0;
00095 bminfo.bmiHeader.biClrImportant = 0;
00096
00097 m_hBmp = CreateDIBSection(m_hDC, &bminfo, DIB_RGB_COLORS, (void**)&m_pPixels, NULL, 0);
00098 if (!m_hBmp)
00099 {
00100 printf("ERROR: couldn't allocate Bitmap\n");
00101
00102 DeleteDC(m_hDC);
00103 m_hDC = NULL;
00104
00105 return false;
00106 }
00107
00108 m_hBmpOld = (HBITMAP)SelectObject(m_hDC, m_hBmp);
00109
00110 PIXELFORMATDESCRIPTOR pfd = {
00111 sizeof(PIXELFORMATDESCRIPTOR),
00112 1,
00113 PFD_DRAW_TO_BITMAP |
00114 PFD_SUPPORT_OPENGL,
00115 PFD_TYPE_RGBA,
00116 24,
00117 0, 0, 0, 0, 0, 0,
00118 0,
00119 0,
00120 0,
00121 0, 0, 0, 0,
00122 32,
00123 0,
00124 0,
00125 PFD_MAIN_PLANE,
00126 0,
00127 0, 0, 0
00128 };
00129
00130 int iPixelFormat;
00131
00132
00133 iPixelFormat = ChoosePixelFormat(m_hDC, &pfd);
00134
00135
00136 BOOL bResult = SetPixelFormat(m_hDC, iPixelFormat, &pfd);
00137 if (!bResult)
00138 {
00139 printf("ERROR: SetPixelFormat failed\n");
00140
00141 SelectObject(m_hDC, m_hBmpOld);
00142 DeleteObject(m_hBmp);
00143 DeleteDC(m_hDC);
00144 m_hDC = NULL;
00145
00146 return false;
00147 }
00148
00149 m_hGLRC = wglCreateContext(m_hDC);
00150 if (!m_hGLRC)
00151 {
00152 printf("ERROR: couldn't allocate HGLRC\n");
00153
00154 SelectObject(m_hDC, m_hBmpOld);
00155 DeleteObject(m_hBmp);
00156 DeleteDC(m_hDC);
00157 m_hDC = NULL;
00158
00159 return NULL;
00160 }
00161
00162 wglMakeCurrent(m_hDC, m_hGLRC);
00163
00164 m_nWidth = width;
00165 m_nHeight = height;
00166
00167 return true;
00168 }
00169
00170 void CGLContext::DeleteContext()
00171 {
00172 if (m_hDC != NULL)
00173 {
00174 wglMakeCurrent(NULL, NULL);
00175
00176 wglDeleteContext(m_hGLRC);
00177 m_hGLRC = NULL;
00178
00179 SelectObject(m_hDC, m_hBmpOld);
00180 m_hBmpOld = NULL;
00181
00182 DeleteObject(m_hBmp);
00183 m_hBmp = NULL;
00184
00185 DeleteDC(m_hDC);
00186 m_hDC = NULL;
00187 }
00188 }
00189
00190 void CGLContext::MakeCurrent()
00191 {
00192 if (m_hDC != NULL)
00193 wglMakeCurrent(m_hDC, m_hGLRC);
00194 }
00195
00196 void CGLContext::DoneCurrent()
00197 {
00198 wglMakeCurrent(NULL, NULL);
00199 }
00200
00201 bool CGLContext::GetImage(CByteImage *pImage)
00202 {
00203 if (m_hDC == NULL)
00204 return false;
00205
00206 if (pImage->width != m_nWidth || pImage->height != m_nHeight)
00207 {
00208 printf("ERROR: CGLContext::GetImage: Image dimensions do not match (%d, %d) vs. (%d, %d)\n", pImage->width, pImage->height, m_nWidth, m_nHeight);
00209 return false;
00210 }
00211
00212 glFlush();
00213
00214 if (pImage->type == CByteImage::eRGB24)
00215 {
00216 unsigned char *in = m_pPixels + 3 * m_nWidth * (m_nHeight-1);
00217 unsigned char *out = pImage->pixels;
00218
00219 for (int y = 0; y < m_nHeight; y++, in -= 2*3*m_nWidth)
00220 {
00221 for (int x = 0; x < m_nWidth; x++, out += 3, in += 3)
00222 {
00223
00224 out[0] = in[2];
00225 out[1] = in[1];
00226 out[2] = in[0];
00227 }
00228 }
00229 }
00230 else
00231 {
00232 unsigned char *in = m_pPixels + 3 * m_nWidth * (m_nHeight-1);
00233 unsigned char *out = pImage->pixels;
00234
00235 for (int y = 0; y < m_nHeight; y++, in -= 2*3*m_nWidth)
00236 {
00237 for (int x = 0; x < m_nWidth; x++, out += 3, in += 3)
00238 {
00239 *out = (in[0] + in[1] + in[2]) / 3;
00240 }
00241 }
00242 }
00243
00244 return true;
00245 }
00246
00247 #endif
00248
00249
00250
00251 #ifdef USE_QTGUI
00252
00253 #include <qapplication.h>
00254 #include <qpixmap.h>
00255
00256 #include "Helpers/helpers.h"
00257
00258
00259 class MyQGLContext : public QGLContext
00260 {
00261 public:
00262 MyQGLContext(const QGLFormat &format, QPaintDevice *device)
00263 : QGLContext(format, device)
00264 {
00265 }
00266 virtual ~MyQGLContext()
00267 {
00268 }
00269
00270 void clearCurrent()
00271 {
00272 doneCurrent();
00273 }
00274 };
00275
00276 CGLContext::CGLContext()
00277 : m_pApp(NULL), m_pPixmap(NULL), m_pGLContext(NULL)
00278 {
00279 }
00280 CGLContext::~CGLContext()
00281 {
00282 DeleteContext();
00283 }
00284
00285 static char app_name[] = "IVT_APPLICATION\0";
00286 static int my_argc = 1;
00287 static char *my_argv[2] = { app_name, NULL};
00288
00289 bool CGLContext::CreateContext(int width, int height, void *shareContext)
00290 {
00291 #ifdef USE_OPENGL
00292 if (qApp == NULL)
00293 {
00294 m_pApp = new QApplication(my_argc, my_argv);
00295 }
00296
00297 m_pPixmap = new QPixmap(width, height);
00298
00299 QGLFormat f = QGLFormat::defaultFormat();
00300
00301
00302 m_pGLContext = new MyQGLContext(f, m_pPixmap);
00303
00304 m_pGLContext->create((QGLContext*)shareContext);
00305 if (!m_pGLContext->isValid())
00306 {
00307 printf("ERROR: CGLContext::CreateContext: couldn't create GLContext!\n");
00308 return false;
00309 }
00310
00311 if (shareContext != NULL && !m_pGLContext->isSharing())
00312 {
00313 printf("WARNING: CGLContext::CreateContext: sharing of GLContext failed!\n");
00314 }
00315
00316 m_pGLContext->makeCurrent();
00317
00318 return true;
00319 #else
00320 return false;
00321 #endif
00322 }
00323
00324 void CGLContext::DeleteContext()
00325 {
00326 #ifdef USE_OPENGL
00327 DoneCurrent();
00328
00329 if (m_pGLContext)
00330 {
00331 delete m_pGLContext;
00332 m_pGLContext = NULL;
00333 }
00334
00335 if (m_pPixmap)
00336 {
00337 delete m_pPixmap;
00338 m_pPixmap = NULL;
00339 }
00340
00341 if (m_pApp)
00342 {
00343 delete m_pApp;
00344 m_pApp = NULL;
00345 }
00346 #endif
00347 }
00348
00349 void CGLContext::MakeCurrent()
00350 {
00351 #ifdef USE_OPENGL
00352 if (m_pGLContext)
00353 m_pGLContext->makeCurrent();
00354 #endif
00355 }
00356
00357 void CGLContext::DoneCurrent()
00358 {
00359 #ifdef USE_OPENGL
00360 if (m_pGLContext)
00361 m_pGLContext->clearCurrent();
00362 #endif
00363 }
00364
00365 bool CGLContext::GetImage(CByteImage *pImage)
00366 {
00367 #ifdef USE_OPENGL
00368 if (!m_pGLContext)
00369 return false;
00370
00371 int width = m_pPixmap->width();
00372 int height = m_pPixmap->height();
00373
00374 if (pImage->width != width || pImage->height != height)
00375 {
00376 printf("ERROR: CGLContext::GetImage: Image dimensions do not match (%d, %d) vs. (%d, %d)\n", pImage->width, pImage->height, width, height);
00377 return false;
00378 }
00379
00380 glFlush();
00381 m_pGLContext->swapBuffers();
00382
00383 if (pImage->type == CByteImage::eRGB24)
00384 {
00385 glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pImage->pixels);
00386
00387 unsigned char *tmp = new unsigned char[3*width];
00388
00389 for (int i = 0; i < (height/2); i++)
00390 {
00391 memcpy(tmp, &pImage->pixels[3*i*width], 3*width);
00392 memcpy(&pImage->pixels[3*i*width], &pImage->pixels[3*(height - i - 1)*width], 3*width);
00393 memcpy(&pImage->pixels[3*(height - i - 1)*width], tmp, 3*width);
00394 }
00395
00396 delete [] tmp;
00397 }
00398 else
00399 {
00400 glReadPixels(0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, pImage->pixels);
00401
00402 unsigned char *tmp = new unsigned char[width];
00403
00404 for (int i = 0; i < (height/2); i++)
00405 {
00406 memcpy(tmp, &pImage->pixels[i*width], width);
00407 memcpy(&pImage->pixels[i*width], &pImage->pixels[(height - i - 1)*width], width);
00408 memcpy(&pImage->pixels[(height - i - 1)*width], tmp, width);
00409 }
00410
00411 delete [] tmp;
00412 }
00413
00414 return true;
00415 #else
00416 return false;
00417 #endif
00418 }
00419
00420 #endif
00421
00422
00423
00424 #ifdef USE_COCOAGUI
00425
00426
00427
00428 extern "C"
00429 {
00430 void* CocoaCreateGLContext(int width, int height, unsigned char* buffer);
00431 void CocoaDeleteGLContext(void* ptr);
00432 void CocoaMakeCurrentGLContext(void* ptr);
00433 void CocoaDoneCurrentGLContext(void* ptr);
00434 void CocoaSwapBuffersGLContext(void* ptr);
00435 }
00436
00437 CGLContext::CGLContext()
00438 : m_pGLContext(NULL), m_pBuffer(NULL)
00439 {
00440 }
00441 CGLContext::~CGLContext()
00442 {
00443 DeleteContext();
00444 }
00445
00446 bool CGLContext::CreateContext(int width, int height, void *shareContext)
00447 {
00448 #ifdef USE_OPENGL
00449 m_nWidth = width;
00450 m_nHeight = height;
00451
00452
00453 m_pBuffer = new unsigned char[width*height*4];
00454
00455 m_pGLContext = CocoaCreateGLContext(width, height, m_pBuffer);
00456 if (!m_pGLContext)
00457 {
00458 delete [] m_pBuffer;
00459 m_pBuffer = NULL;
00460
00461 return false;
00462 }
00463
00464 return true;
00465 #else
00466 return false;
00467 #endif
00468 }
00469
00470 void CGLContext::DeleteContext()
00471 {
00472 #ifdef USE_OPENGL
00473 if (m_pGLContext)
00474 {
00475 CocoaDeleteGLContext(m_pGLContext);
00476 m_pGLContext = NULL;
00477
00478 delete [] m_pBuffer;
00479 m_pBuffer = NULL;
00480 }
00481 #endif
00482 }
00483
00484 void CGLContext::MakeCurrent()
00485 {
00486 #ifdef USE_OPENGL
00487 if (m_pGLContext)
00488 CocoaMakeCurrentGLContext(m_pGLContext);
00489 #endif
00490 }
00491
00492 void CGLContext::DoneCurrent()
00493 {
00494 #ifdef USE_OPENGL
00495 if (m_pGLContext)
00496 CocoaDoneCurrentGLContext(m_pGLContext);
00497 #endif
00498 }
00499
00500 bool CGLContext::GetImage(CByteImage *pImage)
00501 {
00502 #ifdef USE_OPENGL
00503 if (!m_pGLContext)
00504 return false;
00505
00506 if (pImage->width != m_nWidth || pImage->height != m_nHeight)
00507 {
00508 printf("error: CGLContext::GetImage: image dimensions do not match dimensions of the GL context!\n");
00509 return false;
00510 }
00511
00512 glFlush();
00513 CocoaSwapBuffersGLContext(m_pGLContext);
00514
00515 if (pImage->type == CByteImage::eRGB24)
00516 {
00517 glReadPixels(0, 0, m_nWidth, m_nHeight, GL_RGB, GL_UNSIGNED_BYTE, pImage->pixels);
00518
00519 unsigned char *pixels = pImage->pixels;
00520 unsigned char *tmp = new unsigned char[3*m_nWidth];
00521
00522 for (int i = 0; i < (m_nHeight/2); i++)
00523 {
00524 memcpy(tmp, &pixels[3*i*m_nWidth], 3*m_nWidth);
00525 memcpy(&pixels[3*i*m_nWidth], &pixels[3*(m_nHeight - i - 1)*m_nWidth], 3*m_nWidth);
00526 memcpy(&pixels[3*(m_nHeight - i - 1)*m_nWidth], tmp, 3*m_nWidth);
00527 }
00528
00529 delete [] tmp;
00530 }
00531 else
00532 {
00533 glReadPixels(0, 0, m_nWidth, m_nHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, pImage->pixels);
00534
00535 unsigned char *tmp = new unsigned char[m_nWidth];
00536
00537 for (int i = 0; i < (m_nHeight/2); i++)
00538 {
00539 memcpy(tmp, &pImage->pixels[i*m_nWidth], m_nWidth);
00540 memcpy(&pImage->pixels[i*m_nWidth], &pImage->pixels[(m_nHeight - i - 1)*m_nWidth], m_nWidth);
00541 memcpy(&pImage->pixels[(m_nHeight - i - 1)*m_nWidth], tmp, m_nWidth);
00542 }
00543
00544 delete [] tmp;
00545 }
00546
00547 return true;
00548 #else
00549 return false;
00550 #endif
00551 }
00552
00553
00554 #endif
00555
00556
00557 #ifdef USE_GTKGUI
00558
00559 CGLContext::CGLContext()
00560 : m_pXDisplay(NULL), m_glxpixmap(0), m_glxcontext(0)
00561 {
00562 }
00563 CGLContext::~CGLContext()
00564 {
00565 DeleteContext();
00566 }
00567
00568 bool CGLContext::CreateContext(int width, int height, void *shareContext)
00569 {
00570 #ifdef USE_OPENGL
00571 m_pXDisplay = XOpenDisplay(NULL);
00572 if (!m_pXDisplay)
00573 {
00574 printf("CGLContext::CreateContext: couldn't open XServer connection.\n");
00575 return false;
00576 }
00577
00578 if (glXQueryExtension(m_pXDisplay, NULL, NULL) == False)
00579 {
00580 printf("CGLContext::CreateContext: no OpenGL support.\n");
00581 return false;
00582 }
00583
00584 m_nWidth = width;
00585 m_nHeight = height;
00586
00587 int attrlist[] = {GLX_RGBA, GLX_DOUBLEBUFFER, GLX_DEPTH_SIZE, 16, None};
00588
00589 XVisualInfo *vi = glXChooseVisual(m_pXDisplay, DefaultScreen(m_pXDisplay), attrlist);
00590 if (!vi)
00591 {
00592 printf("CGLContext::CreateContext: couldn't find a suitable Visual\n");
00593 return false;
00594 }
00595
00596 m_pFrontBuffer = XCreatePixmap(m_pXDisplay, RootWindow(m_pXDisplay, vi->screen), m_nWidth, m_nHeight, vi->depth);
00597 if (!m_pFrontBuffer)
00598 {
00599 XFree(vi);
00600 DeleteContext();
00601 printf("CGLContext::CreateContext: XCreatePixmap failed.\n");
00602 return false;
00603 }
00604
00605 m_glxpixmap = glXCreateGLXPixmap(m_pXDisplay, vi, m_pFrontBuffer);
00606 if (m_glxpixmap == None)
00607 {
00608 XFree(vi);
00609 DeleteContext();
00610 printf("CGLContext::CreateContext: glXCreateGLXPixmap failed.\n");
00611 return false;
00612 }
00613
00614 if (shareContext)
00615 m_glxcontext = glXCreateContext(m_pXDisplay, vi, (GLXContext)shareContext, False);
00616 else
00617 m_glxcontext = glXCreateContext(m_pXDisplay, vi, 0, False);
00618
00619 if (m_glxcontext == NULL)
00620 {
00621 XFree(vi);
00622 DeleteContext();
00623 printf("CGLContext::CreateContext: glXCreateContext failed.\n");
00624 return false;
00625 }
00626
00627 XFree(vi);
00628
00629 return true;
00630 #else
00631 return false;
00632 #endif
00633 }
00634
00635 void CGLContext::DeleteContext()
00636 {
00637 #ifdef USE_OPENGL
00638 if (!m_glxcontext)
00639 return;
00640
00641 glFinish();
00642 glXWaitX();
00643
00644 if (m_glxcontext == glXGetCurrentContext())
00645 glXMakeCurrent(m_pXDisplay, None, NULL);
00646
00647 if (m_glxpixmap != None) {
00648 glXDestroyGLXPixmap(m_pXDisplay, m_glxpixmap);
00649 glXWaitGL();
00650 m_glxpixmap = None;
00651 }
00652
00653 if (m_pFrontBuffer) {
00654 XFreePixmap(m_pXDisplay, m_pFrontBuffer);
00655 glXWaitX();
00656 m_pFrontBuffer = 0;
00657 }
00658
00659 if (m_glxcontext)
00660 {
00661 glXDestroyContext(m_pXDisplay, m_glxcontext);
00662 m_glxcontext = NULL;
00663 }
00664
00665 if (m_pXDisplay)
00666 {
00667 XCloseDisplay(m_pXDisplay);
00668 m_pXDisplay = NULL;
00669 }
00670 #endif
00671 }
00672
00673 void CGLContext::MakeCurrent()
00674 {
00675 #ifdef USE_OPENGL
00676 if (m_glxcontext)
00677 {
00678 if (m_glxcontext != glXGetCurrentContext())
00679 glXMakeCurrent(m_pXDisplay, m_glxpixmap, m_glxcontext);
00680 }
00681 #endif
00682 }
00683
00684 void CGLContext::DoneCurrent()
00685 {
00686 #ifdef USE_OPENGL
00687 glXMakeCurrent(m_pXDisplay, None, NULL);
00688 #endif
00689 }
00690
00691 bool CGLContext::GetImage(CByteImage *pImage)
00692 {
00693 #ifdef USE_OPENGL
00694 if (!m_glxcontext)
00695 return false;
00696
00697 if (pImage->width != m_nWidth || pImage->height != m_nHeight)
00698 {
00699 printf("ERROR: CGLContext::GetImage: Image dimensions do not match (%d, %d) vs. (%d, %d)\n", pImage->width, pImage->height, m_nWidth, m_nHeight);
00700 return false;
00701 }
00702
00703 glFlush();
00704 glXSwapBuffers(m_pXDisplay, m_glxpixmap);
00705
00706 if (pImage->type == CByteImage::eRGB24)
00707 {
00708 glReadPixels(0, 0, m_nWidth, m_nHeight, GL_RGB, GL_UNSIGNED_BYTE, pImage->pixels);
00709
00710 unsigned char *tmp = new unsigned char[3*m_nWidth];
00711
00712 for (int i = 0; i < (m_nHeight/2); i++)
00713 {
00714 memcpy(tmp, &pImage->pixels[3*i*m_nWidth], 3*m_nWidth);
00715 memcpy(&pImage->pixels[3*i*m_nWidth], &pImage->pixels[3*(m_nHeight - i - 1)*m_nWidth], 3*m_nWidth);
00716 memcpy(&pImage->pixels[3*(m_nHeight - i - 1)*m_nWidth], tmp, 3*m_nWidth);
00717 }
00718
00719 delete [] tmp;
00720 }
00721 else
00722 {
00723 glReadPixels(0, 0, m_nWidth, m_nHeight, GL_LUMINANCE, GL_UNSIGNED_BYTE, pImage->pixels);
00724
00725 unsigned char *tmp = new unsigned char[m_nWidth];
00726
00727 for (int i = 0; i < (m_nHeight/2); i++)
00728 {
00729 memcpy(tmp, &pImage->pixels[i*m_nWidth], m_nWidth);
00730 memcpy(&pImage->pixels[i*m_nWidth], &pImage->pixels[(m_nHeight - i - 1)*m_nWidth], m_nWidth);
00731 memcpy(&pImage->pixels[(m_nHeight - i - 1)*m_nWidth], tmp, m_nWidth);
00732 }
00733
00734 delete [] tmp;
00735 }
00736
00737 return true;
00738 #else
00739 return false;
00740 #endif
00741 }
00742
00743 #endif