| |
| |
| #ifdef USE_MESA |
| #include <GL/osmesa.h> |
| #endif |
| |
| #include "tvectorrenderdata.h" |
| #include "tvectorimage.h" |
| #include "tstrokeutil.h" |
| #include "tmathutil.h" |
| |
| #include "tgl.h" |
| #include "tcurves.h" |
| |
| #ifndef __sgi |
| #include <cstdio> |
| #include <cstdlib> |
| #include <cstring> |
| #else |
| #include <math.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #endif |
| |
| #if defined(LINUX) || defined(__sgi) |
| #include <GL/glx.h> |
| #include <X11/Xlib.h> |
| #include <X11/Xutil.h> |
| #endif |
| |
| #ifdef USE_MESA |
| |
| extern "C" int GLAPIENTRY wglChoosePixelFormat(HDC, const PIXELFORMATDESCRIPTOR *); |
| extern "C" int GLAPIENTRY wglDescribePixelFormat(HDC, int, unsigned int, LPPIXELFORMATDESCRIPTOR); |
| extern "C" int GLAPIENTRY wglSetPixelFormat(HDC, int, const PIXELFORMATDESCRIPTOR *); |
| extern "C" int GLAPIENTRY wglSwapBuffers(HDC); |
| |
| #define ChoosePixelFormat wglChoosePixelFormat |
| #define SetPixelFormat wglSetPixelFormat |
| #define SwapBuffers wglSwapBuffers |
| #endif |
| |
| |
| |
| #ifdef WIN32 |
| |
| |
| void initBITMAPINFO(BITMAPINFO &info, const TRasterP img) |
| { |
| memset(&info, 0, sizeof(BITMAPINFOHEADER)); |
| |
| info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); |
| info.bmiHeader.biWidth = img->getLx(); |
| info.bmiHeader.biHeight = img->getLy(); |
| info.bmiHeader.biPlanes = 1; |
| info.bmiHeader.biBitCount = 32; |
| info.bmiHeader.biCompression = BI_RGB; |
| info.bmiHeader.biSizeImage = 0; |
| info.bmiHeader.biXPelsPerMeter = 1000; |
| info.bmiHeader.biYPelsPerMeter = 1000; |
| info.bmiHeader.biClrUsed = 0; |
| info.bmiHeader.biClrImportant = 0; |
| } |
| |
| |
| #ifdef BUBU |
| void hardRenderVectorImage_MESA(const TVectorRenderData &rd, TRaster32P &ras, const TVectorImageP &vimg) |
| { |
| int rasterWidth = ras->getLx(); |
| int rasterHeight = ras->getLy(); |
| |
| |
| |
| |
| #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305 |
| |
| OSMesaContext ctx = OSMesaCreateContextExt(OSMESA_RGBA, 16, 0, 0, NULL); |
| #else |
| OSMesaContext ctx = OSMesaCreateContext(OSMESA_RGBA, NULL); |
| #endif |
| if (!ctx) { |
| throw TException("OSMesaCreateContext failed!\n"); |
| } |
| ras->lock(); |
| |
| if (!OSMesaMakeCurrent(ctx, ras->getRawData(), GL_UNSIGNED_BYTE, ras->getLx(), ras->getLy())) { |
| { |
| ras->unlock(); |
| throw TException("OSMesaMakeCurrent failed!\n"); |
| } |
| } |
| |
| |
| |
| glViewport(0, 0, rasterWidth, rasterHeight); |
| glMatrixMode(GL_PROJECTION); |
| glLoadIdentity(); |
| gluOrtho2D(0, rasterWidth, 0, rasterHeight); |
| glMatrixMode(GL_MODELVIEW); |
| glLoadIdentity(); |
| glTranslatef(0.375, 0.375, 0.0); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| assert(vimg); |
| tglDraw(rd, vimg.getPointer()); |
| |
| |
| glFlush(); |
| glFinish(); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| OSMesaDestroyContext(ctx); |
| ras->unlock(); |
| } |
| #endif |
| void hardRenderVectorImage(const TVectorRenderData &rd, TRaster32P &ras, const TVectorImageP &vimg) |
| { |
| int rasterWidth = ras->getLx(); |
| int rasterHeight = ras->getLy(); |
| ras->lock(); |
| |
| #ifdef USE_MESA |
| |
| #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305 |
| |
| OSMesaContext ctx = OSMesaCreateContextExt(OSMESA_RGBA, 16, 0, 0, NULL); |
| #else |
| OSMesaContext ctx = OSMesaCreateContext(OSMESA_RGBA, NULL); |
| #endif |
| if (!ctx) { |
| ras->unlock(); |
| throw TException("OSMesaCreateContext failed!\n"); |
| } |
| |
| |
| |
| if (!OSMesaMakeCurrent(ctx, ras->getRawData(), GL_UNSIGNED_BYTE, ras->getLx(), ras->getLy())) { |
| |
| { |
| ras->unlock(); |
| throw TException("OSMesaMakeCurrent failed!\n"); |
| } |
| } |
| #else |
| BITMAPINFO info; |
| |
| initBITMAPINFO(info, ras); |
| |
| void *offData = 0; |
| |
| |
| HDC offDC = CreateCompatibleDC(NULL); |
| |
| HBITMAP offDIB = |
| CreateDIBSection(offDC, &info, DIB_RGB_COLORS, &offData, NULL, 0); |
| |
| assert(offDIB); |
| assert(offData); |
| |
| int dataSize = |
| rasterWidth * rasterHeight * 4; |
| |
| memset(offData, 0, dataSize); |
| |
| HGDIOBJ oldobj = |
| SelectObject(offDC, offDIB); |
| |
| static PIXELFORMATDESCRIPTOR pfd = |
| { |
| sizeof(PIXELFORMATDESCRIPTOR), |
| 1, |
| 0 | (false ? (PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER) : (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI)) | PFD_SUPPORT_OPENGL, |
| PFD_TYPE_RGBA, |
| 32, |
| 0, 0, 0, 0, 0, 0, |
| 0, |
| 0, |
| 0, |
| 0, 0, 0, 0, |
| 32, |
| 0, |
| 0, |
| PFD_MAIN_PLANE, |
| 0, |
| 0, 0, 0 |
| }; |
| |
| |
| int iPixelFormat = ChoosePixelFormat(offDC, &pfd); |
| assert(iPixelFormat != 0); |
| |
| |
| int ret = SetPixelFormat(offDC, iPixelFormat, &pfd); |
| assert(ret == TRUE); |
| |
| |
| HGLRC hglRC = wglCreateContext(offDC); |
| assert(hglRC); |
| ret = wglMakeCurrent(offDC, hglRC); |
| assert(ret == TRUE); |
| #endif |
| |
| glViewport(0, 0, rasterWidth, rasterHeight); |
| glMatrixMode(GL_PROJECTION); |
| glLoadIdentity(); |
| gluOrtho2D(0, rasterWidth, 0, rasterHeight); |
| glMatrixMode(GL_MODELVIEW); |
| glLoadIdentity(); |
| glTranslatef(0.375, 0.375, 0.0); |
| #ifndef USE_MESA |
| glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| |
| |
| glRasterPos2d(0, 0); |
| glDrawPixels(ras->getLx(), ras->getLy(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, ras->getRawData()); |
| #endif |
| |
| assert(vimg); |
| |
| tglDraw(rd, vimg.getPointer()); |
| |
| |
| glFlush(); |
| |
| #ifdef USE_MESA |
| OSMesaDestroyContext(ctx); |
| #else |
| |
| TDimension size = ras->getSize(); |
| |
| if (ras->getWrap() == rasterWidth) |
| memcpy(ras->getRawData(), offData, ras->getPixelSize() * size.lx * size.ly); |
| else { |
| TRaster32P temp(ras->getLx(), ras->getLy()); |
| memcpy(temp->getRawData(), offData, ras->getPixelSize() * size.lx * size.ly); |
| ras->copy(temp); |
| } |
| |
| ret = wglMakeCurrent(offDC, NULL); |
| assert(ret == TRUE); |
| wglDeleteContext(hglRC); |
| |
| |
| SelectObject(offDC, oldobj); |
| DeleteObject(offDIB); |
| DeleteObject(offDC); |
| #endif |
| ras->unlock(); |
| } |
| |
| |
| #elif defined(__sgi) || defined(LINUX) |
| |
| |
| |
| namespace |
| { |
| |
| GLXContext ctx; |
| XVisualInfo *visinfo; |
| GC gc; |
| Window make_rgb_window(Display *dpy, |
| unsigned int width, unsigned int height) |
| { |
| const int sbAttrib[] = {GLX_RGBA, |
| GLX_RED_SIZE, 1, |
| GLX_GREEN_SIZE, 1, |
| GLX_BLUE_SIZE, 1, |
| None}; |
| const int dbAttrib[] = {GLX_RGBA, |
| GLX_RED_SIZE, 1, |
| GLX_GREEN_SIZE, 1, |
| GLX_BLUE_SIZE, 1, |
| GLX_DOUBLEBUFFER, |
| None}; |
| int scrnum; |
| XSetWindowAttributes attr; |
| TUINT32 mask; |
| Window root; |
| Window win; |
| |
| scrnum = DefaultScreen(dpy); |
| root = RootWindow(dpy, scrnum); |
| |
| visinfo = glXChooseVisual(dpy, scrnum, (int *)sbAttrib); |
| if (!visinfo) { |
| visinfo = glXChooseVisual(dpy, scrnum, (int *)dbAttrib); |
| if (!visinfo) { |
| printf("Error: couldn't get an RGB visual\n"); |
| exit(1); |
| } |
| } |
| |
| |
| attr.background_pixel = 0; |
| attr.border_pixel = 0; |
| |
| attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); |
| attr.event_mask = StructureNotifyMask | ExposureMask; |
| mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; |
| |
| win = XCreateWindow(dpy, root, 0, 0, width, height, |
| 0, visinfo->depth, InputOutput, |
| visinfo->visual, mask, &attr); |
| |
| |
| gc = XCreateGC(dpy, win, 0, NULL); |
| |
| |
| ctx = glXCreateContext(dpy, visinfo, NULL, False); |
| if (!ctx) { |
| printf("Error: glXCreateContext failed\n"); |
| exit(-1); |
| } |
| |
| printf("Direct rendering: %s\n", glXIsDirect(dpy, ctx) ? "Yes" : "No"); |
| |
| return win; |
| } |
| |
| GLXPixmap make_pixmap(Display *dpy, Window win, |
| unsigned int width, unsigned int height, |
| Pixmap *pixmap) |
| { |
| Pixmap pm; |
| GLXPixmap glxpm; |
| XWindowAttributes attr; |
| |
| pm = XCreatePixmap(dpy, win, width, height, visinfo->depth); |
| if (!pm) { |
| printf("Error: XCreatePixmap failed\n"); |
| exit(-1); |
| } |
| |
| XGetWindowAttributes(dpy, win, &attr); |
| |
| |
| |
| |
| |
| |
| |
| |
| #ifdef PROBLEMI_CON_IL_DRIVER_NVIDIA |
| if (strstr(glXQueryExtensionsString(dpy, 0), "GLX_MESA_pixmap_colormap")) { |
| |
| glxpm = glXCreateGLXPixmapMESA(dpy, visinfo, pm, attr.colormap); |
| } else { |
| glxpm = glXCreateGLXPixmap(dpy, visinfo, pm); |
| } |
| #else |
| |
| glxpm = glXCreateGLXPixmap(dpy, visinfo, pm); |
| #endif |
| |
| if (!glxpm) { |
| printf("Error: GLXCreateGLXPixmap failed\n"); |
| exit(-1); |
| } |
| |
| *pixmap = pm; |
| |
| return glxpm; |
| } |
| } |
| |
| |
| void hardRenderVectorImage(const TVectorRenderData &rd, TRaster32P &ras, const TVectorImageP &vimg) |
| { |
| Display *dpy; |
| Window win; |
| Pixmap pm; |
| GLXPixmap glxpm; |
| |
| ras->lock(); |
| |
| dpy = XOpenDisplay(NULL); |
| |
| win = make_rgb_window(dpy, ras->getLx(), ras->getLy()); |
| glxpm = make_pixmap(dpy, win, ras->getLx(), ras->getLy(), &pm); |
| |
| GLXContext oldctx = glXGetCurrentContext(); |
| GLXDrawable olddrw = glXGetCurrentDrawable(); |
| |
| glXMakeCurrent(dpy, glxpm, ctx); |
| |
| |
| |
| glViewport(0, 0, ras->getLx(), ras->getLy()); |
| |
| glMatrixMode(GL_PROJECTION); |
| glLoadIdentity(); |
| gluOrtho2D(0, ras->getLx(), 0, ras->getLy()); |
| glMatrixMode(GL_MODELVIEW); |
| glLoadIdentity(); |
| glTranslatef(0.375, 0.375, 0.0); |
| |
| glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| |
| |
| glRasterPos2d(0, 0); |
| glDrawPixels(ras->getLx(), ras->getLy(), GL_RGBA, GL_UNSIGNED_BYTE, ras->getRawData()); |
| |
| |
| assert(vimg); |
| |
| tglDraw(rd, vimg.getPointer()); |
| |
| glFlush(); |
| |
| #if defined(__sgi) |
| |
| glReadPixels(0, 0, |
| ras->getLx(), ras->getLy(), |
| GL_ABGR_EXT, |
| GL_UNSIGNED_BYTE, |
| ras->getRawData()); |
| |
| #elif defined(LINUX) |
| |
| glReadPixels(0, 0, |
| ras->getLx(), ras->getLy(), |
| GL_RGBA, |
| GL_UNSIGNED_BYTE, |
| ras->getRawData()); |
| #endif |
| |
| Bool ret = glXMakeCurrent(dpy, olddrw, oldctx); |
| #ifdef DEBUG |
| if (!ret) { |
| std::cerr << __FUNCTION__ |
| << " error in glXMakeCurrent olddrw=" << olddrw |
| << " oldctx=" << oldctx << std::endl; |
| } |
| #endif |
| ras->unlock(); |
| } |
| |
| #endif |
| |