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