Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "macofflinegl.h"
Toshihiro Shimizu 890ddd
#include <traster.h></traster.h>
Toshihiro Shimizu 890ddd
#include <tconvert.h></tconvert.h>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tthread.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#if defined(powerpc)
Shinya Kitaoka 120a6e
void rightRotateBits(UCHAR *buf, int bufferSize) {
Shinya Kitaoka 120a6e
  UINT *buffer = (UINT *)buf;
Shinya Kitaoka 120a6e
  register UINT app;
Shinya Kitaoka 120a6e
  for (int i = 0; i < bufferSize; i++, buffer++) {
Shinya Kitaoka 120a6e
    app     = *buffer;
Shinya Kitaoka 120a6e
    *buffer = app >> 8 | app << 24;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#else
Shinya Kitaoka 120a6e
void rightRotateBits(UCHAR *buf, int bufferSize) {
Shinya Kitaoka 120a6e
  UINT *buffer = (UINT *)buf;
Shinya Kitaoka 120a6e
  register UINT app;
Shinya Kitaoka 120a6e
  for (int i = 0; i < bufferSize; i++, buffer++) {
Shinya Kitaoka 120a6e
    app     = *buffer;
Shinya Kitaoka 120a6e
    *buffer = (app >> 16 & 0x000000ff) | (app << 16 & 0x00ff0000) |
Shinya Kitaoka 120a6e
              (app & 0xff00ff00);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
}  // namespace
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
GLubyte *memBuffer;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
// MacOfflineGL : implem. offlineGL usando Pixel Buffer (tramite AGL)
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
MacOfflineGL::MacOfflineGL(TDimension rasterSize, const TOfflineGL::Imp *shared)
Shinya Kitaoka 120a6e
    : TOfflineGL::Imp(rasterSize.lx, rasterSize.ly)
Shinya Kitaoka 120a6e
    , m_context(0)
Shinya Kitaoka 120a6e
    , m_oldContext(0) {
Shinya Kitaoka 120a6e
  createContext(rasterSize, shared);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
MacOfflineGL::~MacOfflineGL() { aglDestroyContext(m_context); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MacOfflineGL::createContext(TDimension rasterSize,
Shinya Kitaoka 120a6e
                                 const TOfflineGL::Imp *shared) {
Shinya Kitaoka 120a6e
  GLint attribs[20], cnt = 0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // NOTE: AGL_OFFSCREEN *must* be selected - or it seems that gl surfaces are
Shinya Kitaoka 120a6e
  // never destructed correctly!
Shinya Kitaoka 120a6e
  // This may lead to a kernel panic!
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  attribs[cnt++] = AGL_RGBA;
Shinya Kitaoka 120a6e
  attribs[cnt++] = GL_TRUE;
Shinya Kitaoka 120a6e
  attribs[cnt++] = AGL_PIXEL_SIZE;
Shinya Kitaoka 120a6e
  attribs[cnt++] = 32;
Shinya Kitaoka 120a6e
  attribs[cnt++] = AGL_BUFFER_SIZE;
Shinya Kitaoka 120a6e
  attribs[cnt++] = 32;
Shinya Kitaoka 120a6e
  attribs[cnt++] = AGL_STENCIL_SIZE;
Shinya Kitaoka 120a6e
  attribs[cnt++] = 8;
Shinya Kitaoka 120a6e
  attribs[cnt++] = AGL_DEPTH_SIZE;
Shinya Kitaoka 120a6e
  attribs[cnt++] = 24;
Shinya Kitaoka 120a6e
  attribs[cnt++] = AGL_OFFSCREEN;
Shinya Kitaoka 120a6e
  attribs[cnt++] = AGL_ALPHA_SIZE;
Shinya Kitaoka 120a6e
  attribs[cnt++] = 8;
Shinya Kitaoka 120a6e
  attribs[cnt]   = AGL_NONE;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  AGLPixelFormat fmt = aglChoosePixelFormat(0, 0, attribs);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (fmt == NULL) {
Shinya Kitaoka 120a6e
    GLenum err = aglGetError();
Shinya Kitaoka 120a6e
    std::cout << "Unable to create a pixel format, AGLError =  " << err
Shinya Kitaoka 120a6e
              << std::endl;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_context = aglCreateContext(fmt, NULL);
Shinya Kitaoka 120a6e
  if (!m_context) {
Shinya Kitaoka 120a6e
    GLenum err = aglGetError();
Shinya Kitaoka 120a6e
    /*
Shinya Kitaoka 120a6e
    AGL_NO_ERROR                 0
Shinya Kitaoka 120a6e
    AGL_BAD_ATTRIBUTE        10000
Shinya Kitaoka 120a6e
    AGL_BAD_PROPERTY         10001
Shinya Kitaoka 120a6e
    AGL_BAD_PIXELFMT         10002
Shinya Kitaoka 120a6e
    AGL_BAD_RENDINFO         10003
Shinya Kitaoka 120a6e
    AGL_BAD_CONTEXT          10004
Shinya Kitaoka 120a6e
    AGL_BAD_DRAWABLE         10005
Shinya Kitaoka 120a6e
    AGL_BAD_GDEV             10006
Shinya Kitaoka 120a6e
    AGL_BAD_STATE            10007
Shinya Kitaoka 120a6e
    AGL_BAD_VALUE            10008
Shinya Kitaoka 120a6e
    AGL_BAD_MATCH            10009
Shinya Kitaoka 120a6e
    AGL_BAD_ENUM             10010
Shinya Kitaoka 120a6e
    AGL_BAD_OFFSCREEN        10011
Shinya Kitaoka 120a6e
    AGL_BAD_FULLSCREEN       10012
Shinya Kitaoka 120a6e
    AGL_BAD_WINDOW           10013
Shinya Kitaoka 120a6e
    AGL_BAD_POINTER          10014
Shinya Kitaoka 120a6e
    AGL_BAD_MODULE           10015
Shinya Kitaoka 120a6e
    AGL_BAD_ALLOC            10016
Shinya Kitaoka 120a6e
    AGL_BAD_CONNECTION       10017
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
    std::cout << "Unable to create an OpenGL Context, AGLError = " << err
Shinya Kitaoka 120a6e
              << std::endl;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  makeCurrent();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Creo il pixel buffer
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  GLboolean ret;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  AGLPbuffer pbuffer;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ret = aglCreatePBuffer(rasterSize.lx, rasterSize.ly, GL_TEXTURE_RECTANGLE_EXT,
Shinya Kitaoka 120a6e
                         GL_RGBA, 0, &pbuffer);
Shinya Kitaoka 120a6e
  if (!ret) {
Shinya Kitaoka 120a6e
    GLenum err = aglGetError();
Shinya Kitaoka 120a6e
    std::cout << "Unable to create a PBuffer, AGLError = " << err << std::endl;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // memBuffer = new GLubyte[rasterSize.lx*rasterSize.ly*4];
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ret = aglSetOffScreen(m_context, rasterSize.lx, rasterSize.ly,
Shinya Kitaoka 120a6e
                        rasterSize.lx * 4, memBuffer);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  ret = aglSetPBuffer(m_context, pbuffer, 0, 0, 0);
Shinya Kitaoka 120a6e
  if (!ret) {
Shinya Kitaoka 120a6e
    GLenum err = aglGetError();
Shinya Kitaoka 120a6e
    std::cout << "Unable to set a PBuffer, AGLError = " << err << std::endl;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Non serve piu'
Shinya Kitaoka 120a6e
  aglDestroyPixelFormat(fmt);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MacOfflineGL::makeCurrent() {
Shinya Kitaoka 120a6e
  if (m_context) {
Shinya Kitaoka 120a6e
    bool ret = aglSetCurrentContext(m_context);
Shinya Kitaoka 120a6e
    if (ret == GL_FALSE) {
Shinya Kitaoka 120a6e
      GLenum err = aglGetError();
Shinya Kitaoka 120a6e
      std::cout << "Unable to set current OpenGL Context, AGLError = " << err
Shinya Kitaoka 120a6e
                << std::endl;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    m_oldContext = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MacOfflineGL::doneCurrent() {
Shinya Kitaoka 120a6e
  if (aglGetCurrentContext() != m_context) return;
Shinya Kitaoka 120a6e
  aglSetCurrentContext(0);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MacOfflineGL::saveCurrentContext() {
Shinya Kitaoka 120a6e
  m_oldContext = aglGetCurrentContext();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MacOfflineGL::restoreCurrentContext() {
Shinya Kitaoka 120a6e
  if (m_oldContext) aglSetCurrentContext(m_oldContext);
Shinya Kitaoka 120a6e
  m_oldContext = 0;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void MacOfflineGL::getRaster(TRaster32P raster) {
Shinya Kitaoka 120a6e
  makeCurrent();
Shinya Kitaoka 120a6e
  glFinish();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  int lx = raster->getLx();
Shinya Kitaoka 120a6e
  int ly = raster->getLy();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  raster->lock();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  glReadPixels(0, 0, lx, ly, GL_RGBA, GL_UNSIGNED_BYTE, raster->getRawData());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  rightRotateBits(raster->getRawData(), lx * ly);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  raster->unlock();
Toshihiro Shimizu 890ddd
}