/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2009.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: sgx/src/drivers/common/opengl/oglgraphics.hpp

*/

#ifndef SGX_OPENGL_GRAPHICS_H
#define SGX_OPENGL_GRAPHICS_H

// NOTE: You must include <GL/glut.h> before this file
#include "oglstates.hpp"

typedef tBOOL (cb_pOpenGLIdleFunction)(tREAL32, tMEM_SIZE);

class COpenGLEngine : public CSGXGraphicsEngine
{
public:
	static sgxTexEnvState			m_StateTexEnv;
	static sgxBindTexState			m_StateBindTex;
	static sgxBlendFuncState		m_StateBlendFunc;

	static CSGXGraphicsEngine *create(const sgxString &appname, const tUINT32 width, const tUINT32 height);
	static COpenGLEngine *GetOpenGL();

	virtual void	idleScene();
	virtual void	runEngine(cb_pOpenGLIdleFunction *pFN, const tMEM_SIZE param);
	virtual void	stopEngine();

	virtual tUINT32	GetMaxLights() const;

protected:
	COpenGLEngine::COpenGLEngine(const sgxString &appname, const tUINT32 width, const tUINT32 height);
	COpenGLEngine::COpenGLEngine() : CSGXGraphicsEngine() {}

	virtual void Set2DMode();
	virtual void Set3DMode();

	virtual void doBeginScene();
	virtual void preDrawScene();
	virtual void doDrawScene();
	virtual void blit();

	virtual void setRenderBuffer(tUINT32 id);

	virtual void postUpdateScene(const tREAL32 telaps);

	virtual void flushClearBuffer();

	virtual CSGXTexture *grabFrame();

	virtual void updateViewTransform();
	virtual void updateProjectionTransform();


	// Primitives
//	virtual void drawPolygon(const sgxPolygonPrimitive &poly, const sgxMatrix43 &transform);
	//	virtual void drawMesh(const CStaticMesh &mesh, const sgxMatrix43 &transform);
	
	virtual void updateAnimatedMesh(CAnimatedMesh &animmesh, const tREAL32 telaps);
	virtual void drawAnimatedMesh(const CAnimatedMesh &animmesh, const sgxMatrix43 &transform);

	virtual void drawPrimitiveCuboidImpl(const sgxGfxCuboid &cuboid, const sgxMatrix43 &transform);
	virtual void drawPrimitiveCuboid(const CSGXTexture **pTextures, const sgxMatrix43 &transform, const sgxVector3 &minpos, const sgxVector3 &maxpos);
	virtual void drawPrimitiveSphereImpl(const sgxGfxSphere &sphere, const sgxMatrix43 &transform);
	virtual void drawLine3D(const sgxVector3 &from, const sgxVector3 &to);

	virtual void drawTriStrip(const CSGXTexture	*pTexture, const sgxVector<sgxPolyVtx> &vtx);
	virtual void drawQuadStrip(const CSGXTexture *pTexture, const sgxVector<sgxPolyVtx> &vtx);

	virtual void drawRect2D(const sgxVector2 &from, const sgxVector2 &to);

	virtual void drawSkyBox(const CSGXTexture **pTextures,const sgxMatrix43 &transform, const sgxVector3 &minpos, const sgxVector3 &maxpos);
	virtual void drawAlphaFaces();

	virtual void drawPolygonImpl(const sgxGfxPolygon &poly, const sgxMatrix43 &transform);
	virtual void drawAlphaPolygonImpl(const sgxGfxPolygon &poly, const sgxMatrix43 &transform);

	virtual void SetCamera(const CSGXCamera &camera);

	// Conversion
	virtual void convertPolygon(sgxGfxPolygon &mesh);
	virtual void convertAnimatedMesh(CAnimatedMesh &animmesh);

private:
	cb_pOpenGLIdleFunction	*m_pIdleCallback;
	tMEM_SIZE				m_iIdleParameter;
	sgxMatrixState			m_MatrixModeState;
	
	GLfloat					m_GLViewMatrix[16];
	GLfloat					m_GLProjectionMatrix[16];

	CSGXCamera				m_CurrentCamera;
	tBOOL					m_bPostRedisplay;

	//
	// OpenGL utility functions
	//
	GLenum	GetOGLMode();
	void	prepareCallbacks();
	void	applyLighting();
};

#endif /* SGX_OPENGL_GRAPHICS_H */
