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 #include <OpenGlDevice.h>
00027 #include <OPS_Globals.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <stdio.h>
00031
00032 #ifdef _GLX
00033 #define _PNG
00034 #include <png.h>
00035 #endif
00036
00037
00038 int OpenGlDevice::numWindows(0);
00039
00040
00041
00042 #ifdef _WGL
00043 LONG WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
00044 {
00045 LONG lRet = 1;
00046 PAINTSTRUCT ps;
00047
00048 switch(uMsg) {
00049 case WM_CREATE:
00050 break;
00051
00052 case WM_DESTROY:
00053 break;
00054
00055 case WM_PAINT:
00056 BeginPaint(hWnd, &ps);
00057 EndPaint(hWnd, &ps);
00058 break;
00059
00060 default:
00061 lRet = DefWindowProc (hWnd, uMsg, wParam, lParam);
00062 break;
00063 }
00064
00065 return lRet;
00066 }
00067
00068
00069
00070
00071
00072 int oglSetPixelFormat(HDC hDC, BYTE type, DWORD flags)
00073 {
00074 int pf;
00075 PIXELFORMATDESCRIPTOR pfd;
00076
00077
00078 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00079 pfd.nVersion = 1;
00080 pfd.dwFlags = flags |
00081 PFD_SUPPORT_OPENGL;
00082 pfd.iPixelType = type;
00083 pfd.cColorBits = 24;
00084 pfd.cRedBits = 8;
00085 pfd.cGreenBits = 8;
00086 pfd.cBlueBits = 8;
00087 pfd.cDepthBits = 16;
00088
00089
00090
00091 pf = ChoosePixelFormat(hDC, &pfd);
00092 if (pf == 0) {
00093 MessageBox(NULL,
00094 "ChoosePixelFormat() failed: Cannot find format specified.",
00095 "Error", MB_OK);
00096 return 0;
00097 }
00098
00099
00100 if (SetPixelFormat(hDC, pf, &pfd) == FALSE) {
00101 MessageBox(NULL,
00102 "SetPixelFormat() failed: Cannot set format specified.",
00103 "Error", MB_OK);
00104 return 0;
00105 }
00106
00107 return pf;
00108 }
00109
00110
00111
00112
00113
00114 HWND oglCreateWindow(char* title, int x, int y, int width, int height,
00115 HGLRC *hRC, HDC *hDC)
00116 {
00117 WNDCLASS wc;
00118 HWND hWnd;
00119 HINSTANCE hInstance;
00120
00121
00122 hInstance = GetModuleHandle(NULL);
00123
00124
00125 wc.style = CS_HREDRAW | CS_VREDRAW;
00126 wc.lpfnWndProc = (WNDPROC)WndProc;
00127 wc.cbClsExtra = 0;
00128 wc.cbWndExtra = 0;
00129 wc.hInstance = hInstance;
00130 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
00131 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
00132 wc.hbrBackground = NULL;
00133 wc.lpszMenuName = NULL;
00134 wc.lpszClassName = title;
00135
00136
00137 if (!RegisterClass(&wc)) {
00138 MessageBox(NULL,
00139 "RegisterClass() failed: Cannot register window class,",
00140 "Error", MB_OK);
00141 return NULL;
00142 }
00143
00144
00145 hWnd = CreateWindow(title,
00146 title,
00147 WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
00148 x, y, width, height,
00149 NULL,
00150 NULL,
00151 hInstance,
00152 NULL);
00153
00154
00155 if (hWnd == NULL) {
00156 MessageBox(NULL,
00157 "CreateWindow() failed: Cannot create a window.",
00158 "Error", MB_OK);
00159 return NULL;
00160 }
00161
00162
00163 ShowWindow(hWnd, SW_SHOW);
00164
00165
00166 UpdateWindow(hWnd);
00167
00168
00169 *hDC = GetDC(hWnd);
00170
00171
00172 if (oglSetPixelFormat(*hDC, PFD_TYPE_RGBA,
00173 PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER) == 0)
00174 exit(1);
00175
00176
00177 *hRC = wglCreateContext(*hDC);
00178 wglMakeCurrent(*hDC, *hRC);
00179 glClearColor(1.0f,1.0f,1.0f,1.0f);
00180 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00181 glViewport(0, 0, (GLsizei)width, (GLsizei)height);
00182 glMatrixMode(GL_PROJECTION);
00183 glLoadIdentity();
00184 gluOrtho2D(0.0, (GLdouble)width, 0.0, (GLdouble)height);
00185 glFlush();
00186
00187 return hWnd;
00188 }
00189
00190
00191
00192
00193
00194 int oglDestroyWindow(char* title, HWND hWnd, HGLRC hRC, HDC hDC)
00195 {
00196 HINSTANCE hInstance;
00197
00198
00199 hInstance = GetModuleHandle(NULL);
00200
00201
00202
00203
00204
00205 wglMakeCurrent(NULL, NULL);
00206 ReleaseDC(hWnd, hDC);
00207 wglDeleteContext(hRC);
00208 DestroyWindow(hWnd);
00209
00210
00211 if (!UnregisterClass(title, hInstance)) {
00212 MessageBox(NULL,
00213 "UnregisterClass() failed: Cannot unregister window class,",
00214 "Error", MB_OK);
00215 return -1;
00216 }
00217
00218 return 0;
00219 }
00220
00221
00222
00223
00224
00225 int oglCreateBitmap(int width, int height, HGLRC *hRC, HDC *hDC,
00226 HBITMAP *theBitmap, BITMAPINFO *info, GLubyte **bits)
00227 {
00228
00229 *hDC = CreateCompatibleDC(NULL);
00230
00231
00232
00233
00234 GLint Width = width;
00235 GLint Height = height;
00236
00237 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
00238 info->bmiHeader.biPlanes = 1;
00239 info->bmiHeader.biBitCount = 24;
00240 info->bmiHeader.biCompression = BI_RGB;
00241 info->bmiHeader.biXPelsPerMeter = 11808;
00242 info->bmiHeader.biYPelsPerMeter = 11808;
00243 info->bmiHeader.biClrUsed = 0;
00244 info->bmiHeader.biClrImportant = 0;
00245 info->bmiHeader.biWidth = width;
00246 info->bmiHeader.biHeight = height;
00247
00248
00249
00250
00251
00252
00253
00254 void *theBits = *bits;
00255
00256
00257 *theBitmap = CreateDIBSection(*hDC, info, DIB_RGB_COLORS, &theBits, NULL, 0);
00258 *bits = (GLubyte *)theBits;
00259
00260 SelectObject(*hDC, *theBitmap);
00261
00262 if (oglSetPixelFormat(*hDC, PFD_TYPE_RGBA, PFD_DRAW_TO_BITMAP) == 0)
00263 exit(1);
00264
00265
00266 *hRC = wglCreateContext(*hDC);
00267
00268 return 0;
00269 }
00270
00271
00272
00273
00274
00275 int oglDestroyBitmap(HBITMAP *theBitmap, HGLRC hRC, HDC hDC)
00276 {
00277
00278
00279
00280
00281 wglMakeCurrent(NULL, NULL);
00282 wglDeleteContext(hRC);
00283 DeleteObject(theBitmap);
00284
00285
00286 return 0;
00287 }
00288
00289 #elif _GLX
00290
00291 static int attributeListSgl[] = {
00292 GLX_RGBA,
00293 GLX_RED_SIZE, 1,
00294 GLX_GREEN_SIZE, 1,
00295 GLX_BLUE_SIZE, 1,
00296 None };
00297
00298 static int attributeListDbl[] = {
00299 GLX_RGBA,
00300 GLX_DOUBLEBUFFER,
00301 GLX_RED_SIZE, 1,
00302 GLX_GREEN_SIZE, 1,
00303 GLX_BLUE_SIZE, 1,
00304 None };
00305
00306 static Bool WaitForNotify(Display *d, XEvent *e, char *arg) {
00307 return (e->type == MapNotify) && (e->xmap.window == (Window)arg);
00308 }
00309
00310 static const char *FontName = "fixed";
00311
00312
00313
00314 #else
00315
00316 #endif
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 OpenGlDevice::OpenGlDevice()
00328 :FontBase(0), winOpen(1), width(0), height(0), windowTitle(0)
00329 {
00330
00331 #ifdef _WGL
00332
00333 #elif _GLX
00334 fontInfo = 0;
00335 #else
00336
00337 #endif
00338
00339
00340 if (numWindows == 0)
00341 this->initWindow();
00342
00343 numWindows++;
00344 }
00345
00346 OpenGlDevice::~OpenGlDevice()
00347 {
00348 numWindows--;
00349
00350 #ifdef _WGL
00351 if (winOpen == 0) {
00352 oglDestroyWindow(windowTitle,theWND, theHRC, theHDC);
00353 }
00354
00355 if (FontBase != 0) {
00356 glDeleteLists(FontBase, 256);
00357 }
00358 #elif _GLX
00359
00360 if (fontInfo != 0) {
00361 Font id;
00362 unsigned int first, last;
00363
00364 id = fontInfo->fid;
00365 first = fontInfo->min_char_or_byte2;
00366 last = fontInfo->max_char_or_byte2;
00367
00368 glDeleteLists(FontBase, (GLuint) last + 1);
00369 XFreeFont(theDisplay, fontInfo);
00370 }
00371
00372 if (winOpen == 0) {
00373 XFreeGC(theDisplay, theGC);
00374 XDestroyWindow(theDisplay, theWindow);
00375 XCloseDisplay(theDisplay);
00376 }
00377
00378 if (windowTitle != 0)
00379 delete [] windowTitle;
00380
00381 #else
00382
00383 #endif
00384
00385 }
00386
00387 void
00388 OpenGlDevice::WINOPEN(const char *_title, int _xLoc, int _yLoc, int _width, int _height)
00389 {
00390 if (windowTitle != 0)
00391 delete [] windowTitle;
00392
00393 windowTitle = new char[strlen(_title)+1];
00394 strcpy(windowTitle, _title);
00395
00396 width = _width;
00397 height = _height;
00398
00399 #ifdef _WGL
00400 xLoc = _xLoc;
00401 yLoc = _yLoc;
00402
00403 if (winOpen == 0)
00404 oglDestroyWindow(windowTitle,theWND, theHRC, theHDC);
00405
00406 theWND = oglCreateWindow(windowTitle, _xLoc, _yLoc, _width, _height, &theHRC, &theHDC);
00407 if (theWND == NULL)
00408 exit(1);
00409 winOpen = 0;
00410 wglMakeCurrent(theHDC, theHRC);
00411
00412 FontBase = glGenLists((GLuint) 256);
00413 if (!FontBase) {
00414 printf("Error: unable to allocate display lists\n");
00415 exit(0);
00416 }
00417
00418 wglUseFontBitmaps(theHDC, 0, 256, FontBase);
00419
00420 #elif _GLX
00421
00422 theDisplay = XOpenDisplay("");
00423 if (theDisplay == 0) {
00424 opserr << "OpenGlDevice::initX11() - could not connect to display\n";
00425 exit(-1);
00426 }
00427
00428 theScreen = DefaultScreen(theDisplay);
00429
00430
00431 XSetWindowAttributes swa;
00432 swap_flag = GL_FALSE;
00433
00434
00435
00436
00437 if (winOpen == 0) {
00438 XFreeGC(theDisplay, theGC);
00439 XDestroyWindow(theDisplay, theWindow);
00440 }
00441
00442
00443 visual = glXChooseVisual(theDisplay, theScreen, attributeListDbl);
00444 swap_flag = GL_TRUE;
00445 if (visual == NULL) {
00446 visual = glXChooseVisual(theDisplay, theScreen, attributeListSgl);
00447 swap_flag = GL_FALSE;
00448 }
00449
00450 if(visual == NULL) {
00451 opserr << "OpenGlDevice::WINOPEN - unable to get visual\n";
00452 exit(2);
00453 }
00454
00455
00456
00457
00458
00459
00460 swa.colormap = XCreateColormap(theDisplay, RootWindow(theDisplay, visual->screen),
00461 visual->visual, AllocNone);
00462
00463 swa.border_pixel = 0;
00464 swa.event_mask = StructureNotifyMask;
00465
00466 unsigned long mask;
00467 mask = CWBackPixel|CWBorderPixel|CWColormap|CWEventMask;
00468 theWindow = XCreateWindow(theDisplay, RootWindow(theDisplay, visual->screen),
00469 _xLoc, _yLoc, _width, _height,
00470 0, visual->depth, InputOutput, visual->visual,
00471 mask, &swa);
00472
00473 if (theWindow == 0) {
00474 opserr << "OpenGlDevice::WINOPEN() - could not open a window\n";
00475 exit(-1);
00476 }
00477
00478
00479 hints.x = _xLoc;
00480 hints.y = _yLoc;
00481 hints.width = _width;
00482 hints.height = _height;
00483 hints.flags = PPosition | PSize;
00484 XSetNormalHints(theDisplay, theWindow, &hints);
00485 XSetStandardProperties(theDisplay, theWindow, windowTitle, windowTitle, None, 0, 0, &hints);
00486
00487
00488 cx = glXCreateContext(theDisplay, visual, NULL, GL_TRUE);
00489 if (cx == 0) {
00490 opserr << "OpenGlDevice::WINOPEN() - could not create a glx context\n";
00491 exit(-1);
00492 }
00493
00494
00495 XMapWindow(theDisplay, theWindow);
00496
00497
00498 glXMakeCurrent(theDisplay, theWindow, cx);
00499
00500
00501 theGC = XCreateGC(theDisplay, theWindow, 0, 0);
00502 winOpen = 0;
00503
00504 XVisualInfo visual;
00505 visual.visual = 0;
00506 int depth = DefaultDepth(theDisplay, theScreen);
00507
00508 XMapWindow(theDisplay,theWindow);
00509 XClearWindow(theDisplay, theWindow);
00510 XFlush(theDisplay);
00511
00512 Font id;
00513 unsigned int first, last;
00514
00515 fontInfo = XLoadQueryFont(theDisplay, FontName);
00516 if (!fontInfo) {
00517 printf("Error: font %s not found\n", FontName);
00518 exit(0);
00519 }
00520
00521 id = fontInfo->fid;
00522 first = fontInfo->min_char_or_byte2;
00523 last = fontInfo->max_char_or_byte2;
00524
00525 FontBase = glGenLists((GLuint) last + 1);
00526 if (!FontBase) {
00527 printf("Error: unable to allocate display lists\n");
00528 exit(0);
00529 }
00530
00531 glXUseXFont(id, first, last - first + 1, FontBase + first);
00532
00533 #else
00534
00535 #endif
00536
00537
00538 }
00539
00540
00541
00542
00543 void
00544
00545 OpenGlDevice::CLEAR()
00546 {
00547 #ifdef _WGL
00548 wglMakeCurrent(theHDC, theHRC);
00549
00550 #elif _GLX
00551 glXMakeCurrent(theDisplay, theWindow, cx);
00552 #else
00553
00554 #endif
00555
00556 }
00557
00558 void
00559 OpenGlDevice::STARTIMAGE()
00560 {
00561 #ifdef _WGL
00562 wglMakeCurrent(theHDC, theHRC);
00563 #elif _GLX
00564 glXMakeCurrent(theDisplay, theWindow, cx);
00565 #else
00566
00567 #endif
00568 }
00569
00570 void
00571 OpenGlDevice::ENDIMAGE()
00572 {
00573 #ifdef _WGL
00574 wglMakeCurrent(theHDC, theHRC);
00575 SwapBuffers(theHDC);
00576 #elif _GLX
00577 if (swap_flag == GL_TRUE)
00578 glXSwapBuffers(theDisplay, theWindow);
00579 glXMakeCurrent(theDisplay, theWindow, cx);
00580 #else
00581
00582 #endif
00583 }
00584
00585
00586 int
00587 OpenGlDevice::GetWidth()
00588 {
00589 return width;
00590 }
00591
00592 int
00593 OpenGlDevice::GetHeight()
00594 {
00595 return height;
00596 }
00597
00598
00599
00600 void
00601 OpenGlDevice::initWindow(void) {
00602
00603
00604 #ifdef _WGL
00605
00606 #elif _GLX
00607
00608 #else
00609
00610 #endif
00611 }
00612
00613
00614 void
00615 OpenGlDevice::drawText(float x, float y, float z, char *text, int length,
00616 char horizontalJustify, char verticalJustify)
00617 {
00618
00619 #ifdef _WGL
00620 glColor3f(0.0,0.0,0.0);
00621 glRasterPos3f(x,y,z);
00622 glListBase(FontBase);
00623 glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
00624 #elif _GLX
00625
00626
00627 glColor3f(0.0, 0.0 , 0.0);
00628 glRasterPos3f(x,y,z);
00629
00630
00631 int moveX = 0;
00632 int moveY = 0;
00633
00634 int height = fontInfo->ascent;
00635 if (horizontalJustify != 'l') {
00636 char *s;
00637 int width = 0;
00638 for (s=text; *s; s++) {
00639 width += fontInfo->per_char[*s].width;
00640 }
00641 if (horizontalJustify == 'r')
00642 moveX = -width;
00643 else
00644 moveX = -width/2;
00645 }
00646
00647 if (verticalJustify != 'b') {
00648 if (verticalJustify == 't')
00649 moveY = -height - 1;
00650 else
00651 moveY = -height/2;
00652 } else
00653 moveY = +2;
00654
00655 glBitmap(0, 0, 0, 0, (GLfloat)moveX, (GLfloat)moveY, NULL);
00656
00657
00658 glListBase(FontBase);
00659 glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);
00660 #else
00661
00662 #endif
00663 }
00664
00665
00666 int
00667 OpenGlDevice::saveImage(const char *fileName, int type)
00668 {
00669
00670 #ifdef _WGL
00671 return this->saveImageAsBMP(fileName);
00672 #elif _GLX
00673 return this->saveImageAsPNG(fileName);
00674 #else
00675
00676 #endif
00677
00678 return 0;
00679 }
00680
00681 int
00682 OpenGlDevice::saveImageAsBMP(const char *fileName)
00683 {
00684
00685 #ifdef _WGL
00686 wglMakeCurrent(theHDC, theHRC);
00687 #elif _GLX
00688 glXMakeCurrent(theDisplay, theWindow, cx);
00689 #else
00690
00691 #endif
00692
00693
00694 char *newFileName = new char[strlen(fileName)+4];
00695 if (newFileName == 0) {
00696 opserr << "OpenGlDevice::saveImageAsBMP() failed to open file: " << fileName << endln;
00697 return -1;
00698 }
00699 strcpy(newFileName, fileName);
00700 strcat(newFileName,".BMP");
00701
00702
00703 FILE *fp;
00704 if ((fp = fopen(newFileName,"wb")) == NULL) {
00705 opserr << "OpenGLDevice::saveBmpImage() - could not open file named" << newFileName << endln;
00706 return -1;
00707 }
00708
00709 #ifdef _WGL
00710 int bitsize = (info.bmiHeader.biWidth *
00711 info.bmiHeader.biBitCount + 7) / 8 *
00712 abs(info.bmiHeader.biHeight);
00713 int infosize;
00714 infosize = sizeof(BITMAPINFOHEADER);
00715 switch (info.bmiHeader.biCompression) {
00716 case BI_BITFIELDS :
00717 infosize += 12;
00718 if (info.bmiHeader.biClrUsed == 0)
00719 break;
00720 case BI_RGB :
00721 if (info.bmiHeader.biBitCount > 8 &&
00722 info.bmiHeader.biClrUsed == 0)
00723 break;
00724 case BI_RLE8 :
00725 case BI_RLE4 :
00726 if (info.bmiHeader.biClrUsed == 0)
00727 infosize += (1 << info.bmiHeader.biBitCount) * 4;
00728 else
00729 infosize += info.bmiHeader.biClrUsed * 4;
00730 break;
00731 }
00732
00733 int size = sizeof(BITMAPFILEHEADER) + infosize + bitsize;
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 glFinish();
00781 glPixelStorei(GL_PACK_ALIGNMENT, 4);
00782 glPixelStorei(GL_PACK_ROW_LENGTH, 0);
00783 glPixelStorei(GL_PACK_SKIP_ROWS, 0);
00784 glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
00785
00786 if (bits == 0) opserr << "BITS ZERO\n";
00787
00788 glReadPixels(0, 0, info.bmiHeader.biWidth, info.bmiHeader.biHeight,
00789 GL_BGR_EXT, GL_UNSIGNED_BYTE, bits);
00790
00791
00792 currentBitSize = info.bmiHeader.biWidth * info.bmiHeader.biHeight;
00793
00794 BITMAPFILEHEADER header;
00795 header.bfType = 'MB';
00796 header.bfSize = size;
00797 header.bfReserved1 = 0;
00798 header.bfReserved2 = 0;
00799 header.bfOffBits = sizeof(BITMAPFILEHEADER) + infosize;
00800
00801 if (fwrite(&header, 1, sizeof(BITMAPFILEHEADER), fp) < sizeof(BITMAPFILEHEADER))
00802 {
00803
00804
00805 opserr << "OpenGLDevice::saveBmpImage() - failed to write BITMAPHEADER" << endln;
00806 fclose(fp);
00807 return -4;
00808 }
00809 if (fwrite(&info, 1, infosize, fp) < infosize)
00810 {
00811
00812
00813 opserr << "OpenGLDevice::saveBmpImage() - failed to write BITMAPINFOHEADER" << endln;
00814 fclose(fp);
00815 return -5;
00816 }
00817 if (fwrite(bits, 1, bitsize, fp) < bitsize)
00818 {
00819
00820
00821 opserr << "OpenGLDevice::saveBmpImage() - failed to write BITMAPINFOHEADER" << endln;
00822 fclose(fp);
00823 return -6;
00824 }
00825
00826 #endif
00827
00828 delete [] newFileName;
00829 fclose(fp);
00830 return 0;
00831 }
00832
00833
00834
00835 int
00836 OpenGlDevice::saveImageAsPNG(const char *fileName)
00837 {
00838
00839
00840 #ifdef _WGL
00841 wglMakeCurrent(theHDC, theHRC);
00842 #elif _GLX
00843 glXMakeCurrent(theDisplay, theWindow, cx);
00844 #else
00845
00846 #endif
00847
00848
00849
00850
00851
00852
00853 char *image;
00854 image = new char[3*width*height];
00855 if (image == 0) {
00856 opserr << "OpenGlDevice::failed to allocate memory for image\n";
00857 return(-1);
00858 }
00859
00860
00861 glReadBuffer(GL_BACK_LEFT);
00862 glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, image);
00863
00864
00865
00866
00867
00868
00869
00870
00871 FILE *fp;
00872 char *newFileName = new char (strlen(fileName+4));
00873 if (newFileName == 0) {
00874 opserr << "OpenGlDevice::saveImageAsPNG() failed to open file: " << fileName << endln;
00875 delete [] image;
00876 return -1;
00877 }
00878
00879 strcpy(newFileName, fileName);
00880 strcat(newFileName, ".png");
00881
00882 if((fp = fopen(newFileName, "wb"))==NULL) {
00883 opserr << "OpenGlDevice::saveImageAsPNG() failed to open file: " << fileName << endln;
00884 delete [] image;
00885 return -1;
00886 }
00887
00888 #ifdef _PNG
00889
00890 png_structp png_ptr = png_create_write_struct
00891 (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
00892 if(!png_ptr) {
00893 delete [] image;
00894 fclose(fp);
00895 opserr << "OpenGlDevice::saveImageAsPNG() - out of memery creating write structure\n";
00896 return -1;
00897 }
00898
00899 png_infop info_ptr = png_create_info_struct(png_ptr);
00900 if(!info_ptr) {
00901 png_destroy_write_struct(&png_ptr,
00902 (png_infopp)NULL);
00903 delete [] image;
00904 fclose(fp);
00905 opserr << "OpenGlDevice::saveImageAsPNG() - out of memery creating info structure\n";
00906
00907 return -1;
00908 }
00909
00910
00911
00912
00913
00914
00915 if(setjmp(png_jmpbuf(png_ptr))) {
00916 png_destroy_write_struct(&png_ptr, &info_ptr);
00917 fclose(fp);
00918 opserr << "OpenGlDevice::saveImageAsPNG() - setjmp problem\n";
00919 return 2;
00920 }
00921
00922
00923 png_init_io(png_ptr, fp);
00924
00925
00926
00927
00928
00929
00930
00931
00932 png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943 int color_type, interlace_type, numChannels;
00944
00945
00946
00947 color_type = PNG_COLOR_TYPE_RGB; numChannels = 3;
00948
00949
00950 interlace_type = PNG_INTERLACE_NONE;
00951
00952
00953
00954 int bit_depth = 8;
00955 png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
00956 color_type,
00957 interlace_type,
00958 PNG_COMPRESSION_TYPE_BASE,
00959 PNG_FILTER_TYPE_BASE);
00960
00961
00962
00963
00964
00965
00966
00967 png_write_info(png_ptr, info_ptr);
00968
00969
00970
00971
00972 png_bytep* row_pointers = new png_bytep[height];
00973 if (row_pointers == 0) {
00974 png_destroy_write_struct(&png_ptr, &info_ptr);
00975 delete [] image;
00976 fclose(fp);
00977 opserr << "OpenGlDevice::failed to allocate memory for row pointers\n";
00978 return(-1);
00979 }
00980
00981 unsigned int row_stride = width*numChannels;
00982 unsigned char *rowptr = (unsigned char*) image;
00983 for (int row = height-1; row >=0 ; row--) {
00984 row_pointers[row] = rowptr;
00985 rowptr += row_stride;
00986 }
00987
00988
00989 png_write_image(png_ptr, row_pointers);
00990
00991
00992
00993
00994
00995 png_write_end(png_ptr, info_ptr);
00996
00997
00998
00999
01000
01001 png_destroy_write_struct(&png_ptr, &info_ptr);
01002
01003 delete [] row_pointers;
01004
01005 #endif
01006
01007 delete [] image;
01008 delete [] newFileName;
01009 fclose(fp);
01010
01011 return 0;
01012 }
01013
01014
01015