| |
| |
| #include "qtofflinegl.h" |
| #include <traster.h> |
| #include <tconvert.h> |
| |
| |
| |
| #ifdef _WIN32 |
| |
| void swapRedBlueChannels(void *buffer, int bufferSize) |
| { |
| void *b = buffer; |
| |
| #ifdef x64 |
| int size = bufferSize; |
| UCHAR *pix = (UCHAR *)b; |
| while (size > 0) { |
| UCHAR r = *pix; |
| UCHAR b = *(pix + 2); |
| *pix = b; |
| *(pix + 2) = r; |
| pix += 4; |
| size--; |
| } |
| #else |
| __asm |
| { |
| mov ecx, bufferSize |
| mov ebx, b |
| label: |
| mov al,[ebx+0] |
| mov ah,[ebx+2] |
| mov [ebx+2],al |
| mov [ebx+0],ah |
| |
| add ebx,4 |
| dec ecx |
| jnz label |
| } |
| #endif |
| } |
| |
| #endif |
| |
| |
| |
| #if defined(MACOSX) |
| #if defined(powerpc) |
| |
| void rightRotateBits(UCHAR *buf, int bufferSize) |
| { |
| UINT *buffer = (UINT *)buf; |
| UINT app; |
| for (int i = 0; i < bufferSize; i++, buffer++) { |
| app = *buffer; |
| *buffer = app >> 8 | app << 24; |
| } |
| } |
| #else |
| void rightRotateBits(UCHAR *buf, int bufferSize) |
| { |
| UINT *buffer = (UINT *)buf; |
| UINT app; |
| for (int i = 0; i < bufferSize; i++, buffer++) { |
| app = *buffer; |
| *buffer = (app >> 16 & 0x000000ff) | (app << 16 & 0x00ff0000) | (app & 0xff00ff00); |
| } |
| } |
| #endif |
| #endif |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| QtOfflineGL::QtOfflineGL(TDimension rasterSize, std::shared_ptr<TOfflineGL::Imp> shared) |
| : TOfflineGL::Imp(rasterSize.lx, rasterSize.ly) |
| , m_context(0) |
| , m_oldContext(0) |
| { |
| createContext(rasterSize, std::move(shared)); |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| |
| |
| |
| QtOfflineGL::~QtOfflineGL() |
| { |
| } |
| |
| |
| |
| void QtOfflineGL::createContext(TDimension rasterSize, std::shared_ptr<TOfflineGL::Imp> shared) |
| { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| QGLFormat fmt; |
| |
| #ifdef _WIN32 |
| fmt.setAlphaBufferSize(8); |
| fmt.setAlpha(true); |
| fmt.setRgba(true); |
| fmt.setDepthBufferSize(32); |
| fmt.setDepth(true); |
| fmt.setStencilBufferSize(32); |
| fmt.setStencil(true); |
| fmt.setAccum(false); |
| fmt.setPlane(0); |
| #elif MACOSX |
| fmt = QGLFormat::defaultFormat(); |
| |
| fmt.setVersion(2, 1); |
| #if 0 |
| fmt.setAlphaBufferSize(8); |
| fmt.setAlpha(true); |
| fmt.setRgba(true); |
| fmt.setDepthBufferSize(32); |
| fmt.setDepth(true); |
| fmt.setStencilBufferSize(8); |
| fmt.setStencil(true); |
| fmt.setAccum(false); |
| fmt.setPlane(0); |
| fmt.setDirectRendering(false); |
| #endif |
| #endif |
| |
| QSurfaceFormat format; |
| format.setProfile(QSurfaceFormat::CompatibilityProfile); |
| |
| m_surface = std::make_shared<QOffscreenSurface>(); |
| m_surface->setFormat(format); |
| m_surface->create(); |
| |
| m_context = std::make_shared<QOpenGLContext>(); |
| m_context->setFormat(format); |
| m_context->create(); |
| m_context->makeCurrent(m_surface.get()); |
| |
| QOpenGLFramebufferObjectFormat fbo_format; |
| m_fbo = std::make_shared<QOpenGLFramebufferObject>(rasterSize.lx, rasterSize.ly, fbo_format); |
| m_fbo->bind(); |
| |
| printf("create context:%p [thread:0x%x]\n", m_context.get(), QThread::currentThreadId()); |
| |
| |
| |
| |
| } |
| |
| |
| void QtOfflineGL::makeCurrent() |
| { |
| if (m_context) { |
| m_context->moveToThread(QThread::currentThread()); |
| m_context->makeCurrent(m_surface.get()); |
| } |
| |
| |
| } |
| |
| |
| |
| void QtOfflineGL::doneCurrent() |
| { |
| if (m_context) { |
| m_context->doneCurrent(); |
| } |
| } |
| |
| |
| |
| void QtOfflineGL::saveCurrentContext() |
| { |
| |
| } |
| |
| |
| |
| void QtOfflineGL::restoreCurrentContext() |
| { |
| |
| |
| } |
| |
| |
| |
| void QtOfflineGL::getRaster(TRaster32P raster) |
| { |
| makeCurrent(); |
| glFlush(); |
| |
| int lx = raster->getLx(); |
| int ly = raster->getLy(); |
| |
| raster->lock(); |
| raster->copy( TRaster32P(lx, ly, m_fbo->width(), (TPixelRGBM32 *)m_fbo->toImage(false).bits(), false) ); |
| raster->unlock(); |
| } |
| |
| |
| |
| |
| |
| |
| |
| QtOfflineGLPBuffer::QtOfflineGLPBuffer(TDimension rasterSize) |
| : TOfflineGL::Imp(rasterSize.lx, rasterSize.ly), m_context(0) |
| { |
| createContext(rasterSize); |
| |
| makeCurrent(); |
| |
| glClearColor(0.0f, 0.0f, 0.0f, 0.0f); |
| glClear(GL_COLOR_BUFFER_BIT); |
| |
| doneCurrent(); |
| } |
| |
| |
| |
| QtOfflineGLPBuffer::~QtOfflineGLPBuffer() |
| { |
| } |
| |
| |
| |
| void QtOfflineGLPBuffer::createContext(TDimension rasterSize) |
| { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| QGLFormat fmt; |
| |
| #ifdef _WIN32 |
| fmt.setAlphaBufferSize(8); |
| fmt.setAlpha(false); |
| fmt.setRgba(true); |
| fmt.setDepthBufferSize(32); |
| fmt.setDepth(true); |
| fmt.setStencilBufferSize(32); |
| fmt.setStencil(true); |
| fmt.setAccum(false); |
| fmt.setPlane(0); |
| #elif MACOSX |
| fmt.setAlphaBufferSize(1); |
| fmt.setAlpha(false); |
| fmt.setRgba(true); |
| fmt.setDepthBufferSize(24); |
| fmt.setDepth(true); |
| fmt.setStencilBufferSize(8); |
| fmt.setStencil(true); |
| fmt.setAccum(false); |
| fmt.setPlane(0); |
| #endif |
| |
| |
| |
| int sizeMax = std::max(rasterSize.lx, rasterSize.ly); |
| |
| |
| int pBufferSize = 2; |
| while (pBufferSize < sizeMax) |
| pBufferSize *= 2; |
| |
| m_context = std::make_shared<QGLPixelBuffer>(QSize(pBufferSize, pBufferSize), fmt); |
| } |
| |
| |
| |
| void QtOfflineGLPBuffer::makeCurrent() |
| { |
| if (m_context){ |
| m_context->makeCurrent(); |
| } |
| } |
| |
| |
| |
| void QtOfflineGLPBuffer::doneCurrent() |
| { |
| if (m_context) |
| m_context->doneCurrent(); |
| } |
| |
| |
| |
| void QtOfflineGLPBuffer::getRaster(TRaster32P raster) |
| { |
| makeCurrent(); |
| glFlush(); |
| |
| |
| QImage image = m_context->toImage(); |
| |
| int lx = raster->getLx(), ly = raster->getLy(); |
| |
| static const TRaster32P emptyRaster; |
| if (image.height() == 0 || image.width() == 0) |
| return; |
| |
| |
| |
| int yOffset = image.height() - ly; |
| raster->lock(); |
| |
| for (int y = 0; y < ly; y++) { |
| QRgb *inpPix = (QRgb *)image.scanLine(yOffset + y); |
| |
| TPixel32 *pix = raster->pixels(ly - 1 - y); |
| TPixel32 *endPix = pix + lx; |
| |
| for (; pix < endPix; ++pix) { |
| pix->m = 255; |
| pix->r = qRed(*inpPix); |
| pix->g = qGreen(*inpPix); |
| pix->b = qBlue(*inpPix); |
| inpPix++; |
| } |
| } |
| raster->unlock(); |
| } |
| |