Code Search for Developers
 
 
  

pixelbuffer.cpp from NeoEngineNG at Krugle


Show pixelbuffer.cpp syntax highlighted

/***************************************************************************
              pixelbuffer.cpp  -  OpenGL pixel buffer implementation
                             -------------------
    begin                : Thu April 17, 2003
    copyright            : (C) 2003 by Cody Russell
    email                : cody [at] jhu.edu

  	last modify date	: Fri Jul 07 2006
	last modify			:
	l.m. copyright   	: (C) 2006 by Arcadia Design s.r.l.
    email       		: Dario Deledda (penguindark@hotmail.com)

 ***************************************************************************

 The contents of this file are subject to the Mozilla Public License Version
 1.1 (the "License"); you may not use this file except in compliance with
 the License. You may obtain a copy of the License at
 http://www.mozilla.org/MPL/

 Software distributed under the License is distributed on an "AS IS" basis,
 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 for the specific language governing rights and limitations under the
 License.

 The Original Code is the NeoEngine, NeoDevOpenGL, pixelbuffer.cpp

 The Initial Developer of the Original Code is Cody Russell.
 Portions created by Cody Russell are Copyright (C) 2003
 Cody Russell. All Rights Reserved.

 Contributors: Mattias Jansson (mattias@realityrift.com)

 ***************************************************************************/

#define __NEED_VECTOR_INT
#define NEEDGDI

#include "device.h"
#include "pixelbuffer.h"
#include "pixelbuffertarget.h"
#include "textureunit.h"

#include <neoengine/logstream.h>

using namespace std;
using namespace NeoEngine;


namespace NeoOGL
{


/*! Free buffer IDs */
vector< int > g_vuiFreePBufferID;

/*! Last buffer ID */
unsigned int  g_uiNextPBufferID = 0;

GLenum g_Kdrawbuffers[] = {
						GL_COLOR_ATTACHMENT0_EXT,
						GL_COLOR_ATTACHMENT1_EXT,
						GL_COLOR_ATTACHMENT2_EXT,
						GL_COLOR_ATTACHMENT3_EXT,
						GL_COLOR_ATTACHMENT4_EXT,
						GL_COLOR_ATTACHMENT5_EXT,
						GL_COLOR_ATTACHMENT6_EXT,
						GL_COLOR_ATTACHMENT7_EXT,
						GL_COLOR_ATTACHMENT8_EXT,
						GL_COLOR_ATTACHMENT9_EXT ,
						GL_COLOR_ATTACHMENT10_EXT,
						GL_COLOR_ATTACHMENT11_EXT,
						GL_COLOR_ATTACHMENT12_EXT,
						GL_COLOR_ATTACHMENT13_EXT,
						GL_COLOR_ATTACHMENT14_EXT,
						GL_COLOR_ATTACHMENT15_EXT
					};

#ifdef WIN32

//Helper method
string GetLastErrorString( DWORD dwError )
{
	LPVOID lpMsgBuf;

    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPTSTR)&lpMsgBuf, 0, NULL );

	string strRet = (char*)lpMsgBuf;

	LocalFree( lpMsgBuf );

	return strRet;
}


#endif


NeoEngine::PixelBuffer *Device::CreatePixelBuffer( unsigned int uiWidth, unsigned int uiHeight, unsigned int uiBPP, Texture::TEXTURETYPE eTextureType, Texture::TEXTUREFORMAT eTextureFormat )
{
	if( m_kWindow.m_kCaps.IsSet( RenderCaps::RENDERTEXTURE ) )
	{
		PixelBuffer *pkPBuffer = new PixelBuffer( this );

		if( pkPBuffer->Open( uiWidth, uiHeight, uiBPP, eTextureType, eTextureFormat ) )
			return pkPBuffer;

		neolog << LogLevel( ERROR ) << "*** Unable to create pixel buffer: Unable to open buffer [" << uiWidth << "x" << uiHeight << "x" << uiBPP << "]" << endl;

		delete pkPBuffer;
	}

	return 0;
}

unsigned int PixelBuffer::AddTarget( NeoEngine::TexturePtr pTexture)
{
	if ( pTexture &&  ( m_vMtTexture.size() < m_pkDevice->GetFBOMaxTarget() ) ){
		m_vMtTexture.push_back(pTexture);
		return m_vMtTexture.size();
	}
	return 0;
}

bool	PixelBuffer::RemoveTarget( NeoEngine::TexturePtr pTexture)
{
	std::vector< NeoEngine::TexturePtr >::iterator iter=m_vMtTexture.begin();
	std::vector< NeoEngine::TexturePtr >::iterator end=m_vMtTexture.end();

	while ( iter != end){
		if ( *iter == pTexture){
			m_vMtTexture.erase(iter);
			return true;
		}
		iter++;
	}

	return false;
}


PixelBuffer::PixelBuffer( Device *pkDevice ) :
	Activator(),
	NeoEngine::PixelBuffer(),
	m_pkDevice( pkDevice ),
	m_bIsBound( false ),
	m_kViewport( m_pkDevice->GetViewport() ),
	m_eCurCubemapFace( Texture::CUBEFACE_FRONT )
{
	Deactivate();

	if( g_vuiFreePBufferID.size() )
	{
		m_uiID = *( g_vuiFreePBufferID.end() - 1 );
		g_vuiFreePBufferID.pop_back();
	}
	else
		m_uiID = g_uiNextPBufferID++;

	m_pkDevice->m_vpkPixelBuffers.push_back( this );
	m_iFrameBufObj = 0;
	m_iDepthBufObj = 0;

	m_vMtTexture.clear();
}


PixelBuffer::~PixelBuffer()
{
	Close();

	g_vuiFreePBufferID.push_back( m_uiID );


	std::vector< NeoEngine::TexturePtr >::iterator iter=m_vMtTexture.begin();
	std::vector< NeoEngine::TexturePtr >::iterator end=m_vMtTexture.end();

	while ( iter != end){
		m_vMtTexture.erase(iter);
		iter=m_vMtTexture.begin();
		end=m_vMtTexture.end();
	}

	vector< PixelBuffer* >::iterator ppkBuffer    = m_pkDevice->m_vpkPixelBuffers.begin();
	vector< PixelBuffer* >::iterator ppkBufferEnd = m_pkDevice->m_vpkPixelBuffers.end();

	for( ; ppkBuffer != ppkBufferEnd; ++ppkBuffer )
		if( *ppkBuffer == this )
		{
			m_pkDevice->m_vpkPixelBuffers.erase( ppkBuffer );
			break;
		}

	if( m_pkDevice->m_pkPixelBufferTarget->m_pkCurBuffer == this )
		m_pkDevice->m_pkPixelBufferTarget->m_pkCurBuffer = 0;

	// test for Frame Object support
	if ( m_pkTexture  && m_pkTexture->GetType() == Texture::TEX2DF && m_pkDevice->m_kExtensions.IsSupported( Extensions::EXT_FRAME_BUFFER) ){
		if ( m_iFrameBufObj ){
			neoglDeleteFramebuffersEXT (1,&m_iFrameBufObj);
		}
		if ( m_iDepthBufObj ){
			neoglDeleteFramebuffersEXT (1,&m_iDepthBufObj);
		}
	}
	if ( m_pkTexture  && m_pkTexture->GetType() == Texture::CUBEMAPFBO && m_pkDevice->m_kExtensions.IsSupported( Extensions::EXT_FRAME_BUFFER) ){
		int index=0;
		while ( index < 6 ){
			if ( m_iCubeMapBufObj[index] )
				neoglGenFramebuffersEXT(1, &m_iCubeMapBufObj[index] );
			index++;
		}
		if ( m_iDepthBufObj ){
			neoglDeleteFramebuffersEXT (1,&m_iDepthBufObj);
		}
	}
}

bool PixelBuffer::Open( unsigned int uiWidth, unsigned int uiHeight, unsigned int uiBPP, Texture::TEXTURETYPE eTextureType, Texture::TEXTUREFORMAT eTextureFormat )
{
	m_uiWidth   = uiWidth;
	m_uiHeight  = uiHeight;
	m_uiBPP     = uiBPP;
	int    iComp            = 0;
	GLenum iInternalFormat	= 0;
	GLenum iDataFormat      = GL_RGB;
	GLenum iDataType		= GL_UNSIGNED_BYTE;

	if ( eTextureType==Texture::TEXDEPTH && !m_pkDevice->m_kExtensions.IsSupported( Extensions::ARB_DEPTH_TEXTURE ) ){
		m_uiWidth   = 0;
		m_uiHeight  = 0;
		neolog << LogLevel( ERROR ) << "*** Invalid texture type [ ARB_DEPTH_TEXTURE ] not supported by this graphic card!!!" << endl;
		return false;
	}

	switch( eTextureFormat )
	{
		case Texture::ALPHA:
		{
			iInternalFormat   = GL_ALPHA;
			iDataFormat       = GL_ALPHA;
			iComp             = 1;
			iDataType		  = GL_UNSIGNED_BYTE;
			//m_iInternalFormat = Texture::INTERNALFORMAT_ALPHA8;
			break;
		}

		case Texture::RGB:
		{
			iInternalFormat   = GL_RGB;
			iDataFormat       = GL_RGB;
			iComp             = 3;
			iDataType		  = GL_UNSIGNED_BYTE;
			//m_iInternalFormat = Texture::INTERNALFORMAT_RGB888;
			break;
		}

		case Texture::RGBA:
		{
			iInternalFormat   = GL_RGBA;
			iDataFormat       = GL_RGBA;
			iComp             = 4;
			iDataType		  = GL_UNSIGNED_BYTE;
			//m_iInternalFormat = Texture::INTERNALFORMAT_RGBA8888;
			break;
		}

		case Texture::DEPTH:
		{
			iInternalFormat   = GL_DEPTH_COMPONENT;
			iDataFormat       = GL_DEPTH_COMPONENT;
			iComp             = 1;
			iDataType		  = GL_UNSIGNED_INT;
			//m_iInternalFormat = Texture::INTERNALFORMAT_DEPTH;
			break;
		}

		case Texture::RGBA16F:
		{
			if( m_pkDevice->m_kExtensions.IsSupported( Extensions::ARB_FLOAT_TEXTURE ) ){
				iInternalFormat   = GL_RGBA16F_ARB;
				iDataFormat       = GL_RGBA;
				iComp             = 4;
				iDataType		  = GL_FLOAT;
				//m_iInternalFormat = Texture::INTERNALFORMAT_RGBA16F;
			}else{
				neolog << LogLevel( ERROR ) << "*** Invalid texture format [" << (int)eTextureFormat << "]" << endl;
			}
			break;
		}

		case Texture::RGB16F:
		{
			if( m_pkDevice->m_kExtensions.IsSupported( Extensions::ARB_FLOAT_TEXTURE ) ){
				iInternalFormat   = GL_RGB16F_ARB;
				iDataFormat       = GL_RGB;
				iComp             = 3;
				iDataType		  = GL_FLOAT;
				//m_iInternalFormat = Texture::INTERNALFORMAT_RGB16F;
			}else{
				neolog << LogLevel( ERROR ) << "*** Invalid texture format [" << (int)eTextureFormat << "]" << endl;
			}
			break;
		}

		case Texture::RGBA32F:
		{
			if( m_pkDevice->m_kExtensions.IsSupported( Extensions::ARB_FLOAT_TEXTURE ) ){
				iInternalFormat   = GL_RGBA32F_ARB;
				iDataFormat       = GL_RGBA;
				iComp             = 4;
				iDataType		  = GL_FLOAT;
				//m_iInternalFormat = Texture::INTERNALFORMAT_RGBA32F;
			}else{
				neolog << LogLevel( ERROR ) << "*** Invalid texture format [" << (int)eTextureFormat << "]" << endl;
			}
			break;
		}

		case Texture::RGB32F:
		{
			if( m_pkDevice->m_kExtensions.IsSupported( Extensions::ARB_FLOAT_TEXTURE ) ){
				iInternalFormat   = GL_RGB32F_ARB;
				iDataFormat       = GL_RGB;
				iComp             = 3;
				iDataType		  = GL_FLOAT;
				//m_iInternalFormat = Texture::INTERNALFORMAT_RGB32F;
			}else{
				neolog << LogLevel( ERROR ) << "*** Invalid texture format [" << (int)eTextureFormat << "]" << endl;
			}
			break;
		}

		default:
		{
			neolog << LogLevel( ERROR ) << "*** Invalid texture format [" << (int)eTextureFormat << "]" << endl;
			break;
		}
	}

	// Prevent depth texture greater than screen
	if ( eTextureType == Texture::TEXDEPTH){
		while( m_uiWidth > m_pkDevice->GetWidth() )
			m_uiWidth >>= 2;

		while( m_uiHeight > m_pkDevice->GetHeight() )
			m_uiHeight >>= 2;
	}


	// test for non power of two texture support
	if ( !m_pkDevice->m_kExtensions.IsSupported( Extensions::ARB_NP2_TEXTURE) ){

		float fExp    = float( log( float( m_uiWidth ) ) ) / float( log( 2.0f ) );
		float fFrac   = fExp - float( int( fExp ) );

		if( ( fFrac > 0.0001f ) && ( fFrac < 0.9999f ) )
		{
			neolog << LogLevel( ERROR ) << "*** Unable to create pixelbuffer: width [" << m_uiWidth << "] not a power of 2, exponent [" << fExp << "]" << endl;
			return false;
		}

		fExp  = float( log( float( m_uiHeight ) ) ) / float( log( 2.0f ) );
		fFrac = fExp - float( int( fExp ) );

		if( ( fFrac > 0.0001f ) && ( fFrac < 0.9999f ) )
		{
			neolog << LogLevel( ERROR ) << "*** Unable to create pixelbuffer: height [" << m_uiHeight << "] not a power of 2, exponent [" << fExp << "]" << endl;
			return false;
		}

		if( eTextureType != Texture::TEXDEPTH ){
			while( m_uiWidth > m_pkDevice->GetWidth() )
				m_uiWidth >>= 2;

			while( m_uiHeight > m_pkDevice->GetHeight() )
				m_uiHeight >>= 2;
		}
	}


	// test for rectangular texture support
	if (  !m_pkDevice->m_kExtensions.IsSupported( Extensions::ARB_RECT_TEXTURE)  )
	{
		// We shouldn't ruin the squareness when resizing
		if( m_uiWidth != m_uiHeight )
		{
			m_uiWidth  = MIN( m_uiWidth, m_uiHeight );
			m_uiHeight = m_uiWidth;
		}
	}

	// test for Frame Object support
	if ( (eTextureType == Texture::TEX2DF || eTextureType == Texture::CUBEMAPFBO )
		&& m_pkDevice->m_kExtensions.IsSupported( Extensions::EXT_FRAME_BUFFER)  ){

		// create FBO (off-screen framebuffer)
		m_iFrameBufObj=0;
		m_iDepthBufObj=0;
		m_iCubeMapBufObj[0]=0;

		if ( eTextureType == Texture::CUBEMAPFBO){

			int i=0;
			while (i < 6){
				m_iCubeMapBufObj[i]=0;
				neoglGenFramebuffersEXT(1, &m_iCubeMapBufObj[i] );
				i++;
			}
			neoglGenFramebuffersEXT(1, &m_iDepthBufObj );

		} else if ( eTextureFormat == Texture::DEPTH){

			neoglGenFramebuffersEXT(1, &m_iDepthBufObj );

		}else{

			neoglGenFramebuffersEXT(1, &m_iFrameBufObj );
			neoglGenFramebuffersEXT(1, &m_iDepthBufObj );

		}
	}

	m_kViewport.m_iX=0;
	m_kViewport.m_iY=0;
	m_kViewport.m_iWidth=m_uiWidth;
	m_kViewport.m_iHeight=m_uiHeight;

	m_pkTexture = new NeoOGL::Texture( m_pkDevice, "__pbuffer", eTextureType, eTextureFormat, Texture::LINEAR | ( Texture::LINEAR << 8 ), 1, 0, 0, m_uiWidth, m_uiHeight );

	m_pkDevice->m_ppkTMU[0]->SetTexture( (NeoOGL::Texture*)(NeoEngine::Texture*)m_pkTexture );

	if( eTextureType == Texture::TEXDEPTH )
	{
		iDataFormat = GL_DEPTH_COMPONENT;
		GLint iInternalFormat;
		if ( m_uiBPP == 24 )
			iInternalFormat = GL_DEPTH_COMPONENT24;
		else if ( m_uiBPP == 16 )
			iInternalFormat = GL_DEPTH_COMPONENT16;
		else if ( m_uiBPP == 32 )
			iInternalFormat = GL_DEPTH_COMPONENT32;
		else
			iInternalFormat = GL_DEPTH_COMPONENT;

		iDataType		  = GL_UNSIGNED_INT;
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
		//glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
		glTexImage2D( GL_TEXTURE_2D, 0, iInternalFormat, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
	}
	else if( eTextureType == Texture::TEX2D )
	{
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

		glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
	}
	else if( eTextureType == Texture::TEX2DF )
	{
		if ( eTextureFormat== Texture::DEPTH )
		{
			iDataFormat = GL_DEPTH_COMPONENT;
			GLint iInternalFormat;
			if ( m_uiBPP == 24 )
				iInternalFormat = GL_DEPTH_COMPONENT24;
			else if ( m_uiBPP == 16 )
				iInternalFormat = GL_DEPTH_COMPONENT16;
			else if ( m_uiBPP == 32 )
				iInternalFormat = GL_DEPTH_COMPONENT32;
			else
				iInternalFormat = GL_DEPTH_COMPONENT;

			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
			glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
//			glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
			glTexImage2D( GL_TEXTURE_2D, 0, iInternalFormat, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
		}else{
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
			glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
			glTexImage2D( GL_TEXTURE_2D, 0, iInternalFormat , m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
		}
	}

	else if( eTextureType == Texture::CUBEMAP )
	{
		if( !m_pkDevice->m_kExtensions.IsSupported( Extensions::ARB_TEXTURE_CUBE_MAP ) )
		{
			neolog << LogLevel( ERROR ) << "*** Unable to create pixelbuffer: no cubemap support" << endl;
			return false;
		}

		glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
		glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
		glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );

		glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

		for( int iFace = 0; iFace < 6; ++iFace )
			glTexImage2D( Texture::s_aeOGLCubeFaces[iFace], 0, GL_RGB, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
	}
	else if( eTextureType == Texture::CUBEMAPFBO ){
		if( !m_pkDevice->m_kExtensions.IsSupported( Extensions::ARB_TEXTURE_CUBE_MAP ) )
		{
			neolog << LogLevel( ERROR ) << "*** Unable to create pixelbuffer: no cubemap support" << endl;
			return false;
		}
		glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
		glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
		glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );

		glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		glTexParameteri( GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
//		for( int iFace = 0; iFace < 6; ++iFace )
//			glTexImage2D(Texture::s_aeOGLCubeFaces[iFace], 0, iInternalFormat, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, iInternalFormat, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
		glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, iInternalFormat, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, iInternalFormat, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
		glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, iInternalFormat, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
		glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, iInternalFormat, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
		glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, iInternalFormat, m_uiWidth, m_uiHeight, 0, iDataFormat, iDataType, 0 );
	}
	else
	{
		neolog << LogLevel( ERROR ) << "*** Unable to create pixelbuffer: unsupported texture type [" << (int)eTextureType << "]" << endl;
		return false;
	}

	neoglCheckError();

	GLint iRealWidth = 0;
	GLint iRealHeight = 0;
	GLint iA = 0;
	GLint iR = 0;
	GLint iG = 0;
	GLint iB = 0;
	GLint iD = 0;
	GLint iIntFmt = 0;

	GLenum eTextureID = 0;
	if( eTextureType == Texture::TEX2D || eTextureType == Texture::TEX2DF ) eTextureID= GL_TEXTURE_2D;
	if( eTextureType == Texture::TEXDEPTH ) eTextureID= GL_TEXTURE_2D;
	if( eTextureType == Texture::CUBEMAP ) eTextureID= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
	if( eTextureType == Texture::CUBEMAPFBO ) eTextureID= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;


	glGetTexLevelParameteriv( eTextureID, 0, GL_TEXTURE_WIDTH,			&iRealWidth );
	glGetTexLevelParameteriv( eTextureID, 0, GL_TEXTURE_HEIGHT,			&iRealHeight );
	glGetTexLevelParameteriv( eTextureID, 0, GL_TEXTURE_ALPHA_SIZE,		&iA );
	glGetTexLevelParameteriv( eTextureID, 0, GL_TEXTURE_RED_SIZE,		&iR );
	glGetTexLevelParameteriv( eTextureID, 0, GL_TEXTURE_GREEN_SIZE,		&iG );
	glGetTexLevelParameteriv( eTextureID, 0, GL_TEXTURE_BLUE_SIZE,		&iB );
	glGetTexLevelParameteriv( eTextureID, 0, GL_TEXTURE_DEPTH_SIZE_ARB,	&iD );
	glGetTexLevelParameteriv( eTextureID, 0, GL_TEXTURE_INTERNAL_FORMAT,&iIntFmt);

	neolog << LogLevel( DEBUG ) << "Created pixelbuffer texture " << uiWidth << "x" << uiHeight 
		<< " ID " << m_pkTexture->GetID() << " -> [" << iRealWidth << "x" << iRealHeight 
		<< "] ARGB" << iA << iR << iG << iB << ( ( eTextureType == Texture::CUBEMAP || eTextureType == Texture::CUBEMAPFBO ) ? " x 6" : "" ) 
		<< " depth:"<< iD 
		<< " Internal Format:"<<iIntFmt
		<<endl;

	m_uiWidth  = (unsigned int)iRealWidth;
	m_uiHeight = (unsigned int)iRealHeight;

	Deactivate();
	return true;
}

void PixelBuffer::Close()
{
	m_pkTexture = 0;
}


void PixelBuffer::Activate()
{
	if( IsActive() )
		return;

	if ( m_iCubeMapBufObj[0] && m_pkTexture && m_pkTexture->GetType() == Texture::CUBEMAPFBO ){
		Activator::Activate();
		m_pkDevice->SetCullMode( m_pkDevice->m_eCullMode );
		//m_pkDevice->m_bIsRenderingTexture = true;

		int index=m_eCurCubemapFace;
		// bind offscreen buffer
		neoglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
			m_iCubeMapBufObj[index] );
		// set viewport with FBO flag true
		m_pkDevice->SetViewport( 0, 0, m_uiWidth, m_uiHeight, true );

		// attach texture
		neoglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
			GL_COLOR_ATTACHMENT0_EXT,
			GL_TEXTURE_CUBE_MAP_POSITIVE_X+index,m_pkTexture->GetID(),0);

		// initialize depth renderbuffer
		neoglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_iDepthBufObj);
		neoglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
			GL_DEPTH_COMPONENT24, m_uiWidth, m_uiHeight);
		neoglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
			GL_DEPTH_ATTACHMENT_EXT,
			GL_RENDERBUFFER_EXT, m_iDepthBufObj);

		// set the texture as render target
		glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
		return;
	}

	if ( m_iDepthBufObj && m_pkTexture && m_pkTexture->GetFormat() == Texture::DEPTH ){
		Activator::Activate();
		m_kViewport = m_pkDevice->GetViewport();
		//m_pkDevice->m_bIsRenderingTexture = true;
        // Enable render-to-texture
        neoglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_iDepthBufObj);

		// Set up depth_tex for render-to-texture
        neoglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                                  GL_DEPTH_ATTACHMENT_EXT,
                                  GL_TEXTURE_2D, m_pkTexture->GetID(), 0);
        // No color buffer to draw to or read from
        glDrawBuffer(GL_NONE);
        glReadBuffer(GL_NONE);

		// set viewport with FBO flag true
		m_pkDevice->SetViewport( 0, 0, m_uiWidth, m_uiHeight, true );
		return;
	}
	// test for Frame Object support
	else if ( m_iFrameBufObj && m_pkTexture && m_pkTexture->GetType() == Texture::TEX2DF ){
		Activator::Activate();
		//m_pkDevice->m_bIsRenderingTexture = true;
		m_pkDevice->SetCullMode( m_pkDevice->m_eCullMode );
		// bind offscreen buffer
		neoglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_iFrameBufObj );
		// attach texture
		// set viewport with FBO flag true

		neoglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
			GL_COLOR_ATTACHMENT0_EXT,
			GL_TEXTURE_2D,m_pkTexture->GetID(),0);

		// set the other target textures
		std::vector< NeoEngine::TexturePtr >::iterator iter=m_vMtTexture.begin();
		std::vector< NeoEngine::TexturePtr >::iterator end=m_vMtTexture.end();
		unsigned int nAttach=1;
		while ( iter != end  ){
			neoglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
				GL_COLOR_ATTACHMENT0_EXT+nAttach,
				GL_TEXTURE_2D,(*iter)->GetID(),0);
			nAttach++;
			iter++;
		}

		// initialize depth renderbuffer
		neoglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_iDepthBufObj);
		neoglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
			GL_DEPTH_COMPONENT24, m_uiWidth, m_uiHeight);
		neoglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
			GL_DEPTH_ATTACHMENT_EXT,
			GL_RENDERBUFFER_EXT, m_iDepthBufObj);

		// set the texture as render target
		if (nAttach > 1){
			neoglDrawBuffersEXT(nAttach,g_Kdrawbuffers);
		}else{
//			neoglDrawBuffersEXT(1,g_Kdrawbuffers);
			glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
		}

		m_pkDevice->SetViewport( 0, 0, m_uiWidth, m_uiHeight, true );

		return;
	} else {
		Activator::Activate();

		m_kViewport = m_pkDevice->GetViewport();

		m_pkDevice->SetViewport( 0, 0, m_uiWidth, m_uiHeight );

		m_pkDevice->m_bIsRenderingTexture = true;

		m_pkDevice->SetCullMode( m_pkDevice->m_eCullMode );
	}
}


void PixelBuffer::Deactivate()
{
	if( !IsActive() )
		return;

	if ( m_iCubeMapBufObj[0] && m_pkTexture && m_pkTexture->GetType() == Texture::CUBEMAPFBO ){
		neoglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0 );
		Activator::Deactivate();
		m_pkDevice->SetViewport( m_kViewport.m_iX, m_kViewport.m_iY, m_kViewport.m_iWidth, m_kViewport.m_iHeight );
		m_pkDevice->m_bIsRenderingTexture = false;
		m_pkDevice->SetCullMode( m_pkDevice->m_eCullMode );
		glDrawBuffer( GL_BACK );
		return;
	}

	// test for depth Frame Object support
	if ( m_iDepthBufObj && m_pkTexture && m_pkTexture->GetFormat() == Texture::DEPTH ){
		neoglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0 );
		Activator::Deactivate();
		m_pkDevice->SetViewport( m_kViewport.m_iX, m_kViewport.m_iY, m_kViewport.m_iWidth, m_kViewport.m_iHeight );
		m_pkDevice->m_bIsRenderingTexture = false;
		m_pkDevice->SetCullMode( m_pkDevice->m_eCullMode );
		glDrawBuffer( GL_BACK );
		return;
	}
	// test for Frame Object support
	if ( m_iFrameBufObj && m_pkTexture && m_pkTexture->GetType() == Texture::TEX2DF  ){
		neoglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0 );
		Activator::Deactivate();
		m_pkDevice->SetViewport( m_kViewport.m_iX, m_kViewport.m_iY, m_kViewport.m_iWidth, m_kViewport.m_iHeight );
		m_pkDevice->m_bIsRenderingTexture = false;
		m_pkDevice->SetCullMode( m_pkDevice->m_eCullMode );
		glDrawBuffer( GL_BACK );
		return;
	}else{
		Activator::Deactivate();
		GrabTexture();
		m_pkDevice->SetViewport( m_kViewport.m_iX, m_kViewport.m_iY, m_kViewport.m_iWidth, m_kViewport.m_iHeight );
		m_pkDevice->m_bIsRenderingTexture = false;
		m_pkDevice->SetCullMode( m_pkDevice->m_eCullMode );
		return;
	}
}


void PixelBuffer::SetCubeMapFace( Texture::TEXTURECUBEMAPFACE eCubeMapFace )
{
	if( m_eCurCubemapFace == eCubeMapFace )
		return;

	if( IsActive() && m_pkTexture && ( m_pkTexture->GetType() == Texture::CUBEMAP ) )
		GrabTexture();

	m_eCurCubemapFace = eCubeMapFace;

	if( !IsActive() )
		return;

	if ( m_iCubeMapBufObj[0] && m_pkTexture && m_pkTexture->GetType() == Texture::CUBEMAPFBO ){
		Activator::Activate();
		m_pkDevice->SetCullMode( m_pkDevice->m_eCullMode );

		int index=m_eCurCubemapFace;

		// bind offscreen buffer
		neoglBindFramebufferEXT(GL_FRAMEBUFFER_EXT,
			m_iCubeMapBufObj[index] );

		// attach texture
		neoglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
			GL_COLOR_ATTACHMENT0_EXT,
			GL_TEXTURE_CUBE_MAP_POSITIVE_X+index,m_pkTexture->GetID(),0);

		// initialize depth renderbuffer
		neoglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_iDepthBufObj);
		neoglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
			GL_DEPTH_COMPONENT24, m_uiWidth, m_uiHeight);
		neoglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
			GL_DEPTH_ATTACHMENT_EXT,
			GL_RENDERBUFFER_EXT, m_iDepthBufObj);

		// set viewport with FBO flag true
		m_pkDevice->SetViewport( 0, 0, m_uiWidth, m_uiHeight, true );

		// set the texture as render target
		glDrawBuffer (GL_COLOR_ATTACHMENT0_EXT);
		return;
	}

}


void PixelBuffer::GrabTexture()
{
	if( m_pkTexture )
	{
		//Copy texture data
		m_pkDevice->m_ppkTMU[0]->SetTexture( (NeoOGL::Texture*)(NeoEngine::Texture*)m_pkTexture );

		GLenum eTarget = GL_TEXTURE_2D;

		if( m_pkTexture->GetType() == Texture::CUBEMAP )
			eTarget = Texture::s_aeOGLCubeFaces[ m_eCurCubemapFace ];

		glCopyTexSubImage2D( eTarget, 0, 0, 0, 0, m_pkDevice->GetHeight() - m_uiHeight, m_uiWidth, m_uiHeight );
	}
}

}; // namespace NeoOGL





See more files for this project here

NeoEngineNG

NeoenEngine NG (Next Generation) is the evolution of neoengine one,it\'s a different development from NeoEngine2, it\'s a direct inherits from NeoEngine one.\n

Project homepage: http://sourceforge.net/projects/neoengineng
Programming language(s): C,C++
License: other

  glew/
    bin/
      glew32.dll
      glewinfo.exe
      visualinfo.exe
    doc/
      advanced.html
      basic.html
      credits.html
      glew.css
      glew.html
      glew.png
      glx.txt
      glxew.html
      gpl.txt
      index.html
      install.html
      log.html
      new.png
      ogl_sm.jpg
      sgi.txt
      wglew.html
    include/
      GL/
    lib/
      glew32.lib
      glew32s.lib
  Makefile.am
  SConscript
  base.h
  begin.cpp
  buffermanager.cpp
  buffermanager.h
  bufferregion.cpp
  bufferregion.h
  callback.cpp
  clear.cpp
  close.cpp
  config.cpp
  device.cpp
  device.h
  end.cpp
  execute.cpp
  extensions.cpp
  extensions.h
  flip.cpp
  framebuffertarget.cpp
  framebuffertarget.h
  glext.h
  glue.cpp
  glxext.h
  initialize.cpp
  input.cpp
  light.cpp
  link.h
  mouse.cpp
  neodevopengl-static.dev
  neodevopengl.cbp
  neodevopengl.depend
  neodevopengl.dev
  neodevopengl.dsp
  neodevopengl.layout
  neodevopengl.vcproj
  op.h
  open.cpp
  pixelbuffer.cpp
  pixelbuffer.h
  pixelbuffertarget.cpp
  pixelbuffertarget.h
  polygonbuffer.cpp
  polygonstripbuffer.cpp
  program-glsl.cpp
  program-glsl.h
  projection.cpp
  query.cpp
  render.cpp
  renderqueue.cpp
  renderqueue.h
  rendertarget.cpp
  rendertarget.h
  resize.cpp
  shader.cpp
  shader.h
  shadowmap.cpp
  shadowmap.h
  shutdown.cpp
  statistics.cpp
  statistics.h
  stencilbuffer.cpp
  texture.cpp
  texture.h
  textureunit.cpp
  textureunit.h
  vertexbuffer-glsl.cpp
  vertexbuffer-glsl.h
  vertexbuffer.cpp
  vertexbuffer.h
  vertexbuffermanager-glsl.cpp
  vertexbuffermanager-glsl.h
  vertexbuffermanager-nobs.cpp
  vertexbuffermanager-nobs.h
  vertexbuffermanager.cpp
  vertexbuffermanager.h
  viewport.cpp
  wglext.h
  zbufferstate.cpp
  zbufferstate.h