//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------

#include "giofx.h"

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
cScene::cScene(char* bundlePath)
{
	resolutionX		= 0;
	resolutionY		= 0;
	
	GLint pView[4];
	glGetIntegerv(GL_VIEWPORT, (GLint*)&pView);
	resolutionX = pView[2];
	resolutionY = pView[3];

    grabTexID       = 0;
    grabImage       = 0;
    captureImage    = 0;
    pushEmail       = 0;
	renderActive	= false;
	selectedObject	= -1;
    showMarkers     = 0;
    renderFxAfter   = MAX_ENTITIES;
	accelerometerX	= false;
	accelerometerY	= false;
	touch			= false;
    texFont         = 0;
    
	accelerometerSensitivity = 0.1f;
	shakeSensitivity		 = 0.2f;
    
	touchDivider.Set(300.0f,300.0f,0.0f);
	touchAccelFactor.Set(0.001f,0.001f,0.0f);
	accelerometerFactor.Set(0.001f,0.001f,0.0f);
	accelerometerDeadZone.Set(0,0,0);
	acceleration.Set(0,0,0);
	
	srandom((unsigned int)time(NULL));

	speed.Clear();
	position.Clear();
	angle.Clear();
	scale.Set(1.0,1.0,1.0);
    
#if TARGET_OS_IPHONE
	sprintf(dataPath,"%s",bundlePath);
#else
	sprintf(dataPath,"%s/Contents/Resources/",bundlePath);
    //printf("\ndata path is %s\n",dataPath);
#endif
	
	for (int i=0; i<MAX_ENTITIES; i++)
	{
		pParticle[i]	= NULL;
		pTexture[i]		= NULL;
		pObject[i]		= NULL;
		pTexGfx[i]		= NULL;
		pLight[i]		= NULL;
		pKeyframer[i]	= NULL;
		pFlare[i]		= NULL;
		pFluide[i]		= NULL;
		pFramebuffer[i]	= NULL;
	}
	
	totObjs			= 0;
	totKeyframers	= 0;
	totFluids		= 0;
	totParticles	= 0;
	totFlares		= 0;
	totTexGfx		= 0;
	totLights		= 0;
	totFrameBuffers	= 0;
	
    scale.Set(1,1,1);
	globalScale.Set(1,1,1);
	globalScaleObj[0] = 0;
	globalScaleObj[1] = 0;
	acceleration.Clear();
    frustumZoom = 1.0;
	
	pTransition = NULL;
	
	//prep opengl
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
    glDepthMask(TRUE);
	glShadeModel(GL_SMOOTH);
	//glDisable(GL_DITHER);
    
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glEnableClientState(GL_NORMAL_ARRAY);
    
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

	glDisable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GEQUAL,0.1);
    
    glEnable(GL_NORMALIZE);
	
	glHint(GL_LINE_SMOOTH_HINT , GL_NICEST);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT , GL_NICEST);

	srandom((unsigned int)time(NULL)); 

    /*
    _charInfo		= NULL;
	_kerningPair	= NULL;
    LoadFont((char*)"font.jpg",(char*)"font.fnt");
    */
    
	SetFrustumFromFOV();

#ifdef USE_SOUNDS
	InitSoundEngine();
#endif

#ifdef USE_BULLET
	p_sdkHandle		= NULL;
	p_worldHandle	= NULL;
	PhysicStart(0,0,0);
#endif

#ifdef USE_BOX2D
	world			= NULL;
	m_mouseJoint	= NULL;
	m_mouseForce	= 100000.0f;
	m_boundBody[0]	= NULL;
	m_boundBody[1]	= NULL;
	m_boundBody[2]	= NULL;
	m_boundBody[3]	= NULL;
#endif
	
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
cScene::~cScene()
{
	renderActive = false;
	
	SAFE_DELETE(pTransition);
	DeleteAll();

#ifdef USE_SOUNDS
	EndSoundEngine();
#endif

#ifdef USE_BULLET
	PhysicStop();
#endif

#ifdef USE_BOX2D
	PhysicStop();
#endif
	
}

//------------------------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------------------------
void cScene::DeleteAll(int fromObject)
{
	for (int i=0; i<MAX_ENTITIES; i++)
	{
		if (i >= fromObject)
			SAFE_DELETE(pObject[i]);
		
		SAFE_DELETE(pParticle[i]);
		SAFE_DELETE(pTexture[i]);
		SAFE_DELETE(pTexGfx[i]);
		SAFE_DELETE(pLight[i]);
		SAFE_DELETE(pKeyframer[i]);
		SAFE_DELETE(pFlare[i]);
		SAFE_DELETE(pFramebuffer[i]);
		SAFE_DELETE(pFluide[i]);
	}
	
	totObjs			= 0;
	totKeyframers	= 0;
	totFluids		= 0;
	totParticles	= 0;
	totTexGfx		= 0;
	totLights		= 0;
	totFlares		= 0;
	totFrameBuffers = 0;
}
//------------------------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------------------------
void cScene::SetScale(float scaleX,float scaleY,float scaleZ)
{
	scale.Set(scaleX,scaleY,scaleZ);
}
//------------------------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------------------------
void cScene::EnableAccelerometers(bool tEnable)
{
	accelerometerX = tEnable;
	accelerometerY = tEnable;
}
//------------------------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------------------------
void cScene::EnableAccelerometerX(bool tEnable)
{
	accelerometerX = tEnable;
}
//------------------------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------------------------
void cScene::EnableAccelerometerY(bool tEnable)
{
	accelerometerY = tEnable;
}
//------------------------------------------------------------------------------------------------
// 
//------------------------------------------------------------------------------------------------
void cScene::SetAcceleration(float ax,float ay,float az)
{
	acceleration.Clear();
	
	if (angle.y == 180)
		ax *= -1.0f;

	if (accelerometerX)
		acceleration.x = (ax - accelerometerDeadZone.x);
	
	if (accelerometerY)
		acceleration.y = (ay - accelerometerDeadZone.y);
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetTouchDivider(float tDiv,float accelFactor)
{
	touchDivider.x = tDiv;
	touchDivider.y = tDiv;
	
	touchAccelFactor.x  = accelFactor;
	touchAccelFactor.y  = accelFactor;
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetAccelerometerDivider(float tDiv,float angle)
{
	accelerometerFactor.x  = tDiv;
	accelerometerFactor.y  = tDiv;
	
	//da usare per escludere alcune posizioni
	accelerometerDeadZone.Set(angle,angle,angle);
	
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetAccelerometerSensitivity(float tSensitivity)
{
	accelerometerSensitivity = tSensitivity;
	
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetShakeSensitivity(float tSensitivity)
{
	shakeSensitivity = tSensitivity;
	
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetAccelerometerDividerX(float tDiv,float angle)
{
	accelerometerFactor.x = tDiv;
	
	//da usare per escludere alcune posizioni
	accelerometerDeadZone.x = angle;
	
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetAccelerometerDividerY(float tDiv,float angle)
{
	accelerometerFactor.y = tDiv;
	
	//da usare per escludere alcune posizioni
	accelerometerDeadZone.y = angle;
	
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetTouchDividerX(float tDiv,float accelFactor)
{
	touchDivider.x		= tDiv;
	touchAccelFactor.x  = accelFactor;
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetTouchDividerY(float tDiv,float accelFactor)
{
	touchDivider.y		= tDiv;
	touchAccelFactor.y  = accelFactor;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cScene::EnableInteraction(bool tEnable)
{
	touch = tEnable;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cScene::SetColorMask(int rr,int gg,int bb,int aa)
{
    glColorMask(rr,gg,bb,aa);
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
cVertex cScene::GetExtents()
{
    
    //1024 / 768    = 1.33333   IPAD1/2/MINI
    //2048 / 1536   = 1.33333   IPAD3/4/AIR/MINI RETINA,PRO9.7
    //2732 / 2048   = 1.33333   PRO12.9
    //2224 / 1668   = 1.33333   PRO10.5
    //960  / 640    = 1.5       IPHONE4 4S
    //1136 / 640    = 1.7       IPHONE5 5C 5S SE
    //1334 / 750    = 1.7       IPHONE6 6S 7 8
    //1920 / 1080   = 1.7       IPHONE6+ 7+ 8+
    //2436 / 1125   = 2.16      IPHONEX
    //printf("res %d x %d\n",resolutionX,resolutionY);
    
    cVertex extents(0,0,0);

//estende lo schermo rispettando la ratio...
#ifdef FULLRES_DEVICE

    //per i vecchi dada etc
    #ifdef FULLRES_DEVICE_DEPRECATED
    
        if (resolutionX == 1024 || resolutionX == 2048 || resolutionX == 2732 || resolutionX == 2224)     //ipad1,2,3,mini,air,pro10,pro12
            extents.Set(1.5f, 1.125f, 0.0f);
        else if (resolutionX == 960)                            //iphone4
            extents.Set(1.7f, 1.125f, 0.0f);
        else                                                    //da iphone 5 in po stesso rapporto
            extents.Set(2.0f, 1.125f, 0.0f);

    #else
        //portrait
        if (resolutionY > resolutionX)
        {
            if (resolutionY == 1024 || resolutionY == 2048 || resolutionY == 2732 || resolutionX == 2224)     //ipad
                extents.Set(1.125f, 1.5f, 0.0f);
            else if (resolutionY == 960)                        //iphone4
                extents.Set(0.938f, 1.40f, 0.0f);
            else                                                
                extents.Set(0.938f, 1.66f, 0.0f);               //da iphone 5 in po stesso rapporto
        }
        //landscape
        else
        {
            if (resolutionX == 1024 || resolutionX == 2048 || resolutionX == 2732 || resolutionX == 2224)     //ipad
                extents.Set(1.5f,   1.125f, 0.0f);
            else if (resolutionX == 960)                        //iphone4
                extents.Set(1.40f,  0.938f, 0.0f);
            else
                extents.Set(1.66f,  0.938f, 0.0f);              //da iphone 5 in po stesso rapporto
        }

    
    #endif
    
//...altrimenti filla lo schermo
#else
    
    //float ratio = (float)resolutionX / (float)resolutionY;
    //extents.Set(ratio * 1.5f, 1.5f,0.0f);
    extents.Set(1.5f, 1.125f, 0.0f);
    
#endif
    
    return extents;
}
//---------------------------------------------------------------------------------
//
//---------------------------------------------------------------------------------
void cScene::SetFrustumFromFOV(bool ortho,float angle,float aspect,float px, float py, float zoom)
{
    glViewport(0,0,resolutionX,resolutionY);
	glGetIntegerv(GL_VIEWPORT,&viewport[0]);
    
    if (zoom == 1 && frustumZoom != zoom)
    {
        zoom = frustumZoom;
        frustumZoom = 1.0;
    }

    glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

    cVertex extents = GetExtents();
    cVertex viewCenter(px,py,0.0f);
    
    extents *= zoom;
	cVertex lower = viewCenter - extents;
	cVertex upper = viewCenter + extents;

    frustumResolution.Set(upper.x, upper.y, upper.z);
    
	if (ortho)
	{
		glLoadIdentity();
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		glOrtho(lower.x,   upper.x, lower.y, upper.y, -1.0f, +800.0f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		useOrtho = true;
		return;
	}

    frustumAngle    = angle;
	float left		= -extents.x;
	float right		= +extents.x;
	float bottom	= -extents.y;
	float top		= +extents.y;

#ifndef FULLRES_DEVICE
    top    = tan((angle * M_PI) / 360.0f) * +1;
    bottom = -top;
    left   = aspect * bottom;
    right  = aspect * top;
#endif

    glLoadIdentity();
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
    glFrustum(left, right, bottom, top, 1, 80000);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
    
	useOrtho = false;
}

//----------------------------------------------------------------------------------
// pick sugli oggetti 2D
//----------------------------------------------------------------------------------

void cScene::DrawFullScreen(bool pickRender)
{

#ifdef DEBUG
    if (pickRender)
        printf("*** Warning 2D to 3D enabled ***\n");
#endif

    cVertex tPos   = position;
    cVertex tAngle = angle;
    
    SetFrustumFromFOV();
    SetPosition(0,0,0);
    SetAngle(0,0,0);

    for (int i=totObjs - showMarkers; i < totObjs; i++)
        if (pObject[i])
        {
            glDisable(GL_DEPTH_TEST);
            glDepthMask(FALSE);
            
            if (pickRender)
                pObject[i]->PickRender();
            else
                pObject[i]->Render();

            glEnable(GL_DEPTH_TEST);
            glDepthMask(TRUE);
        }

    SetFrustumFromFOV(false,frustumAngle);
    position    = tPos;
    angle       = tAngle;
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::EnableFog(bool enabled,float fR,float fG,float fB,float fNear,float fFar,float fDensity)
{
	if (!enabled)
	{
		glDisable(GL_FOG);
	}
	else
	{
		float fogColor[4] = {fR,fG,fB, 1.0f};
		glFogf(GL_FOG_MODE,		GL_LINEAR);
		glFogfv(GL_FOG_COLOR,	fogColor);
		glFogf(GL_FOG_DENSITY,  fDensity);
		glHint(GL_FOG_HINT,		GL_NICEST);//GL_FASTEST);
		glFogf(GL_FOG_START,	fNear);
		glFogf(GL_FOG_END,		fFar);
		glEnable(GL_FOG);
	}
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetPosition(float xx,float yy,float zz)
{
	position.Set(xx,yy,zz);
#ifdef USE_VISIBILITY_TEST
    StoreFOV();
#endif
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetPosition(cVertex tPosition)
{
	position = tPosition;
#ifdef USE_VISIBILITY_TEST
    StoreFOV();
#endif
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetPosition(cVertex tPosition,cVertex tAngle)
{
	position = tPosition;
	angle	 = tAngle;
#ifdef USE_VISIBILITY_TEST
    StoreFOV();
#endif
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetGlobalScale(int startObj,int endObj,float xx,float yy,float zz)
{
	globalScale.Set(xx,yy,zz);
	globalScaleObj[0] = startObj;
	globalScaleObj[1] = endObj;
}	
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetAngle(float xx,float yy,float zz)
{
	angle.Set(xx,yy,zz);
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::SetColor(float r,float g,float b, float a)
{
	backColor.Set(r,g,b,a);
	glClearColor(r,g,b,a);
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------

void cScene::Start() { renderActive = true; };


void cScene::Stop() { renderActive = false; };


//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------

void cScene::RenderOperators()
{

#ifdef USE_BULLET
	if (p_worldHandle)
		plStepSimulation(p_worldHandle,p_stepSimulation);
#endif

#ifdef USE_BOX2D
	PhysicIdle();
#endif

	if (totKeyframers)
		for (int t=0;t<totKeyframers;t++)
			if (pKeyframer[t])
			{
				cVertex pos(0,0,0),rot(0,0,0);
				if (pKeyframer[t]->GetFrame(pos,rot))
				{
					if (pKeyframer[t]->object < 0)
					{
						if (pKeyframer[t]->freeAngle)
							SetPosition(pos);
						else
							SetPosition((cVertex)pos,(cVertex)rot);
					}else{
						
						if (pKeyframer[t]->freeAngle)
							pObject[pKeyframer[t]->object]->SetPosition((cVertex)pos);
						else
							pObject[pKeyframer[t]->object]->SetPosition((cVertex)pos,(cVertex)rot);
					}
				}		
			}
	
	if (totTexGfx)
		for (int i=0; i<totTexGfx; i++)
			if (pTexGfx[i])
				pTexGfx[i]->Update();

	if (totFluids)
		for (int t=0;t<totFluids;t++)
			if (pFluide[t])
				pFluide[t]->Update();
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::Render(GLint resX,GLint resY)
{

    if (!resolutionX || (resX > 0 && resX != resolutionX) || !resolutionY || (resY > 0 && resY != resolutionY))
	{
        resolutionX = resX;
		resolutionY = resY;
        SetFrustumFromFOV(useOrtho,50);
        
	}
	
	if (pTransition && pTransition->transition_active)
	{	
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
		pTransition->Render();
		return;
	}
	
	if (!renderActive)
		return;
		
	++globalTimer;
	
	RenderOperators();

	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();

    glScalef(scale.x,scale.y,scale.z);
 
    for (int t=0;t<totFrameBuffers;t++)
        if (pFramebuffer[t] && pFramebuffer[t]->m_prerender)
            pFramebuffer[t]->Render();

    glRotatef(angle.x,1,0,0);
	glRotatef(angle.y,0,1,0);
	glRotatef(angle.z,0,0,1);

	glTranslatef(position.x, position.y, position.z);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_DEPTH_TEST);
    
	for (int t=0;t<totLights;t++)
		if (pLight[t])
			pLight[t]->Render();

	for (int i=0; i<totObjs - showMarkers; i++)
		if (pObject[i])
		{
			glPushMatrix();
			
            if (globalScaleObj[1] > globalScaleObj[0] && i>= globalScaleObj[0] && i <= globalScaleObj[1])
				glScalef(globalScale.x,globalScale.y,globalScale.z);
				
			pObject[i]->Render();
			glPopMatrix();
            
            //fxs
            if (renderFxAfter < MAX_ENTITIES && renderFxAfter == i)
            {
                glPushMatrix();
                glDisable(GL_CULL_FACE);
    
                for (int i=0; i<totParticles; i++)
                    if (pParticle[i])
                        pParticle[i]->Render();
		
                for (int i=0; i<totFlares; i++)
                    if (pFlare[i])
                        pFlare[i]->Render();
				
                glPopMatrix();
            }
		}

	for (int t=0;t<totFrameBuffers;t++)
		if (pFramebuffer[t] && pFramebuffer[t]->m_active && !pFramebuffer[t]->m_prerender)
			pFramebuffer[t]->Render(); 
    
    //fxs
    if (renderFxAfter == MAX_ENTITIES)
    {
        glPushMatrix();
        glDisable(GL_CULL_FACE);
        
        for (int i=0; i<totParticles; i++)
            if (pParticle[i])
                pParticle[i]->Render();
		
        for (int i=0; i<totFlares; i++)
            if (pFlare[i])
                pFlare[i]->Render();
        
        glPopMatrix();
    }
    
    if (showMarkers)
        DrawFullScreen();
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------

cVertex cScene::Convert2Dto3D(float posx, float posy, float posz)
{
	posy = (resolutionY - posy);
	
	GLint viewPort[4];
	float modelMatrix[16];
	float projMatrix[16];
	
	float ppx,ppy,ppz;
	
	glGetIntegerv(GL_VIEWPORT, viewPort);
	glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);
	glGetFloatv(GL_PROJECTION_MATRIX, projMatrix);
	
	_gluUnProject(
					posx, posy, posz,
					modelMatrix,
					projMatrix,
					viewPort,
					&ppx, &ppy, &ppz);

	cVertex retVal(ppx,ppy,ppz);
	return retVal;
};

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
int cScene::PickObject(int sx,int sy)
{
	selectedObject = -1;
	glClearColor(0,0,0,1);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	int enabled = false;
	glGetIntegerv(GL_FOG, &enabled);
	glDisable(GL_FOG);
	
	glLoadIdentity();
    glScalef(scale.x,scale.y,scale.z);
	glRotatef(angle.x,1,0,0);
	glRotatef(angle.y,0,1,0);
    glRotatef(angle.z,0,0,1);
	glTranslatef(position.x, position.y, position.z);
	glEnable(GL_DEPTH_TEST);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	
	for (int i=0; i<totObjs - showMarkers; i++)
		if (pObject[i])
		{
			glPushMatrix();
			if (globalScaleObj[1] > globalScaleObj[0] && i>= globalScaleObj[0] && i <= globalScaleObj[1])
				glScalef(globalScale.x,globalScale.y,globalScale.z);
				
			pObject[i]->PickRender();
			glPopMatrix();
		}
    
    if (showMarkers)
        DrawFullScreen(true);
		
	GLubyte pixelColor[4];
	glPixelStorei(GL_PACK_ALIGNMENT, 4);
	glReadPixels((int)sx,(int)sy,1,1,GL_RGBA,GL_UNSIGNED_BYTE,&pixelColor[0]);
	
	glFlush();
	
	glClearColor(backColor.r,backColor.g,backColor.b,backColor.a);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	for (int i=0; i<MAX_ENTITIES; i++)
		if (pObject[i] != NULL)
			if (pObject[i]->pickColor[0] == pixelColor[0] && pixelColor[0] > 0)
			{
                selectedObject = i;
                break;
            }
	
	if (enabled)
		glEnable(GL_FOG);
	
	return selectedObject;
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
void cScene::MergeTextures(int textureRGB,int textureAlpha)
{ 

    if (!pTexture[textureRGB] || !pTexture[textureAlpha])
        return;
    
    renderActive = false;
    float m_texsize = pTexture[textureRGB]->size.h;
    
    glClearColor(0,0,0,0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glOrtho(0,m_texsize,0,m_texsize,-1,+1);
    glDisable(GL_BLEND);
	glDisable(GL_DEPTH_TEST);
	glFrontFace(GL_FRONT_AND_BACK);
    glViewport(0,0,m_texsize,m_texsize);
    
    float z = 0;
	float ctexCoord[]={0,1 ,1,1 ,1,0 ,0,1 ,1,0 ,0,0 };
	float cvertCoord[]={	
		0,			m_texsize,	z,
		m_texsize,	m_texsize,	z,
		m_texsize,	0,			z,
		0,			m_texsize,	z,
		m_texsize,	0,			z,
		0,			0,			z};
	
    
    glEnable(GL_TEXTURE_2D);
	glColor4f(1,1,1,1);
    
    glEnable(GL_BLEND);
    
    //fill
	glBindTexture(GL_TEXTURE_2D,pTexture[textureRGB]->memAddr);	
	glTexCoordPointer(2, GL_FLOAT, 0, ctexCoord);
	glVertexPointer(3, GL_FLOAT, 0, cvertCoord);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    
    //alpha
    glBlendFunc(GL_DST_COLOR,GL_SRC_ALPHA);
    glBindTexture(GL_TEXTURE_2D,pTexture[textureAlpha]->memAddr);	
	glTexCoordPointer(2, GL_FLOAT, 0, ctexCoord);
	glVertexPointer(3, GL_FLOAT, 0, cvertCoord);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    glColorMask(1,1,1,1);
    glBindTexture(GL_TEXTURE_2D,pTexture[textureRGB]->memAddr);
    glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,m_texsize,m_texsize);
    
    glEnable(GL_DEPTH_TEST);
	glEnable(GL_BLEND);
    renderActive = true;
    
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
int cScene::SwapTexture(int idx,char* texName,int texMode,bool useFilter)
{ 
	if (pTexture[idx])
		SAFE_DELETE(pTexture[idx]);
    
	return LoadTexture(texName,texMode,useFilter);
}
//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
int cScene::LoadTexture(char* texName,int texMode,bool useFilter)
{ 

	char realPath[MAX_PATH];
    sprintf(realPath,"%s%s",this->dataPath,texName);
    
#if TARGET_OS_IPHONE
    
    sprintf(realPath,"%s",texName);

#else
    
	if (!util_exists(realPath))
        return -1;
    
#endif

	for (int i=0; i<MAX_ENTITIES; i++)
		if (pTexture[i] != NULL && !strcmp(realPath,pTexture[i]->name))
			return i;
	
	for (int i=0; i<MAX_ENTITIES; i++)
		if (pTexture[i] == NULL)
		{	
			pTexture[i] = new cTexture(realPath,texMode,useFilter);
            if (!pTexture[i]->size.h || !pTexture[i]->size.v)
            {
                SAFE_DELETE(pTexture[i]);
                printf("*** WARNING failed to load texture %d %s\n", i,texName);
                return -1;
            }
            return i;
		}

    printf("*** WARNING over MAX_ENTITIES range ***\n");
	return -1;
}

//----------------------------------------------------------------------------------
//
//----------------------------------------------------------------------------------
