#ifdef USE_MESA #include #endif #include "tvectorrenderdata.h" #include "tvectorimage.h" #include "tstrokeutil.h" #include "tmathutil.h" #include "tgl.h" #include "tcurves.h" #ifndef __sgi #include #include #include #else #include #include #include #endif #if defined(LINUX) || defined(__sgi) #include #include #include #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 // init a BITMAPINFO structure 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(); //--- begin mesa stuff /* Create an RGBA-mode context */ #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305 /* specify Z, stencil, accum sizes */ 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(); /* Bind the buffer to the context and make it current */ if (!OSMesaMakeCurrent(ctx, ras->getRawData(), GL_UNSIGNED_BYTE, ras->getLx(), ras->getLy())) { { ras->unlock(); throw TException("OSMesaMakeCurrent failed!\n"); } } //---end mesa stuff // cfr. help: OpenGL/Programming tip/OpenGL Correctness Tips 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); /* glClearColor(0.0f,0.0f,0.0f,0.0f); glClear(GL_COLOR_BUFFER_BIT); // draw background glRasterPos2d(0, 0); glDrawPixels( ras->getLx(),ras->getLy(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, ras->getRawData()); */ // do OpenGL draw assert(vimg); tglDraw(rd, vimg.getPointer()); // force to finish glFlush(); glFinish(); /* // set info in out raster 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); } */ OSMesaDestroyContext(ctx); ras->unlock(); } #endif // BUBU void hardRenderVectorImage(const TVectorRenderData &rd, TRaster32P &ras, const TVectorImageP &vimg) { int rasterWidth = ras->getLx(); int rasterHeight = ras->getLy(); ras->lock(); #ifdef USE_MESA /* Create an RGBA-mode context */ #if OSMESA_MAJOR_VERSION * 100 + OSMESA_MINOR_VERSION >= 305 /* specify Z, stencil, accum sizes */ 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"); } /* Bind the buffer to the context and make it current */ 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; // a pointer to buffer // open an offscreen device HDC offDC = CreateCompatibleDC(NULL); HBITMAP offDIB = // and a bitmap image CreateDIBSection(offDC, &info, DIB_RGB_COLORS, &offData, NULL, 0); assert(offDIB); assert(offData); int dataSize = // number of byte of raster rasterWidth * rasterHeight * 4; memset(offData, 0, dataSize); HGDIOBJ oldobj = // select BIB to write SelectObject(offDC, offDIB); static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd 1, // version number 0 | (false ? (PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER) : (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI)) | PFD_SUPPORT_OPENGL, // support OpenGL PFD_TYPE_RGBA, // RGBA type 32, // 32-bit color depth 0, 0, 0, 0, 0, 0, // color bits ignored 0, // no alpha buffer 0, // shift bit ignored 0, // no accumulation buffer 0, 0, 0, 0, // accum bits ignored 32, // 32-bit z-buffer 0, // no stencil buffer 0, // no auxiliary buffer PFD_MAIN_PLANE, // main layer 0, // reserved 0, 0, 0 // layer masks ignored }; // get the best available match of pixel format for the device context int iPixelFormat = ChoosePixelFormat(offDC, &pfd); assert(iPixelFormat != 0); // make that the pixel format of the device context int ret = SetPixelFormat(offDC, iPixelFormat, &pfd); assert(ret == TRUE); // make a valid context for OpenGL rendering HGLRC hglRC = wglCreateContext(offDC); assert(hglRC); ret = wglMakeCurrent(offDC, hglRC); assert(ret == TRUE); #endif // cfr. help: OpenGL/Programming tip/OpenGL Correctness Tips 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); // draw background glRasterPos2d(0, 0); glDrawPixels(ras->getLx(), ras->getLy(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, ras->getRawData()); #endif // do OpenGL draw assert(vimg); tglDraw(rd, vimg.getPointer()); // force to finish glFlush(); #ifdef USE_MESA OSMesaDestroyContext(ctx); #else // set info in out raster 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); // release object SelectObject(offDC, oldobj); DeleteObject(offDIB); DeleteObject(offDC); #endif ras->unlock(); } // end of WIN32 #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); } } /* window attributes */ attr.background_pixel = 0; attr.border_pixel = 0; /* TODO: share root colormap if possible */ 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); /* make an X GC so we can do XCopyArea later */ gc = XCreateGC(dpy, win, 0, NULL); /* need indirect context */ 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); /* * IMPORTANT: * Use the glXCreateGLXPixmapMESA funtion when using Mesa because * Mesa needs to know the colormap associated with a pixmap in order * to render correctly. This is because Mesa allows RGB rendering * into any kind of visual, not just TrueColor or DirectColor. */ #ifdef PROBLEMI_CON_IL_DRIVER_NVIDIA // GLX_MESA_pixmap_colormap // if (strstr(glXQueryExtensionsString(dpy, 0), "GLX_MESA_pixmap_colormap")) { /* stand-alone Mesa, specify the colormap */ glxpm = glXCreateGLXPixmapMESA(dpy, visinfo, pm, attr.colormap); } else { glxpm = glXCreateGLXPixmap(dpy, visinfo, pm); } #else /* This will work with Mesa too if the visual is TrueColor or DirectColor */ glxpm = glXCreateGLXPixmap(dpy, visinfo, pm); #endif if (!glxpm) { printf("Error: GLXCreateGLXPixmap failed\n"); exit(-1); } *pixmap = pm; return glxpm; } } // void offscreenRender(TRaster32P& ras, const TVectorImageP& vimg, const // TAffine& aff) 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); // printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); // cfr. help: OpenGL/Programming tip/OpenGL Correctness Tips 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); // draw background glRasterPos2d(0, 0); glDrawPixels(ras->getLx(), ras->getLy(), GL_RGBA, GL_UNSIGNED_BYTE, ras->getRawData()); // do OpenGL draw 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