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