/*
Copyright (C) 1997-2001 Id Software, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  

See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

#ifdef __cplusplus
# define QGL_EXTERN extern "C"
#else
# define QGL_EXTERN extern
#endif

#ifdef _WIN32
# include <windows.h>

# define QGL_WGL(type,name,params) QGL_EXTERN type (APIENTRY * q##name) params;
# define QGL_WGL_EXT(type,name,params) QGL_EXTERN type (APIENTRY * q##name) params;
# define QGL_GLX(type,name,params)
# define QGL_GLX_EXT(type,name,params)
#endif

#ifdef __linux__
# define QGL_WGL(type,name,params)
# define QGL_WGL_EXT(type,name,params)
# define QGL_GLX(type,name,params) QGL_EXTERN type (APIENTRY * q##name) params;
# define QGL_GLX_EXT(type,name,params) QGL_EXTERN type (APIENTRY * q##name) params;
#endif

#if defined (__APPLE__) || defined (MACOSX)
# define QGL_WGL(type,name,params)
# define QGL_WGL_EXT(type,name,params)
# define QGL_GLX(type,name,params)
# define QGL_GLX_EXT(type,name,params)
#endif

#include "../qcommon/qcommon.h"

#define QGL_FUNC(type,name,params) QGL_EXTERN type (APIENTRY * q##name) params;
#define QGL_EXT(type,name,params) QGL_EXTERN type (APIENTRY * q##name) params;
#ifdef MYSTICARB
#define QGL_ARB(type,name,params) QGL_EXTERN type (APIENTRY * q##name) params;
#endif

#include "qgl.h"

#undef QGL_GLX_EXT
#undef QGL_GLX
#undef QGL_WGL_EXT
#undef QGL_WGL
#undef QGL_EXT
#ifdef MYSTICARB
#undef QGL_ARB
#endif
#undef QGL_FUNC

#include "../client/cin.h"
#include "render.h"

#define	REF_VERSION	"GL 0.01"

typedef unsigned int index_t;

/*

  skins will be outline flood filled and mip mapped
  pics and sprites with alpha will be outline flood filled
  pic won't be mip mapped

  model skin
  sprite frame
  wall texture
  pic

*/

#define IT_CLAMP		1
#define IT_NOMIPMAP		2
#define IT_NOPICMIP		4
#define IT_SKY			8
#define IT_CUBEMAP		16
#define IT_HEIGHTMAP	32
#define IT_FLIPX		64
#define IT_FLIPY		128
#define IT_FLIPDIAGONAL	256
#define IT_NORGB		512
#define IT_NOALPHA		1024
#define IT_NOCOMPRESS	2048

#define IT_CINEMATIC	(IT_NOPICMIP|IT_NOMIPMAP|IT_CLAMP|IT_NOCOMPRESS)

typedef struct image_s
{
	char		name[MAX_QPATH];				// game path, not including extension
	char		extension[8];					// file extension
	int			flags;
	int			width, height, depth;			// source image
	int			upload_width, upload_height, upload_depth;	// after power of two and picmip
	int			texnum;							// gl texture binding
	float		bumpScale;
	struct image_s *hash_next;
} image_t;

enum
{
	TEXTURE_UNIT0,
	TEXTURE_UNIT1,
	TEXTURE_UNIT2,
	TEXTURE_UNIT3,
	TEXTURE_UNIT4,
	TEXTURE_UNIT5,
	TEXTURE_UNIT6,
	TEXTURE_UNIT7,
	MAX_TEXTURE_UNITS
};

#define FOG_TEXTURE_WIDTH	256
#define FOG_TEXTURE_HEIGHT	32

#define SHADOWS_STENCIL			2
//#define SHADOW_VOLUMES		3

#define VERTEX_BUFFER_OBJECTS


#ifdef MYSTICARB
/*
 =======================================================================
 START ARB PROGRAM MANAGER
 =======================================================================
*/

/*=========================================================
 enum_flag_attribute
=========================================================*/
typedef enum
{
	VATTRIB_VERTEX		= (1<<0),
	VATTRIB_TEX0		= (1<<1),
	VATTRIB_TEX1		= (1<<2),
	VATTRIB_TANGENT		= (1<<3),
	VATTRIB_BINORMAL	= (1<<4),
	VATTRIB_NORMAL		= (1<<5),
	VATTRIB_LIGHT		= (1<<6),
	VATTRIB_COLOR		= (1<<7),

	VATTRIB_INVALID		= (1<<8)
}enum_flag_attribute;

/*=========================================================
 enum_render_type
=========================================================*/
typedef enum
{
	RENDER_TYPE_NONE = 0,
	// VERTEX/FRAGMENT PROGRAMS
	RENDER_TYPE_VF_DEFAULT,
	RENDER_TYPE_VF_GENERIC,
	RENDER_TYPE_VF_DIFFUSE_BUMPMAP,
	RENDER_TYPE_VF_DIFFUSE_BUMPMAP_SPECULAR,
	RENDER_TYPE_VF_DIFFUSE_BUMPMAP_GLOSS_SPECULAR,
	// VERTEX PROGRAM
	RENDER_TYPE_V_DEFAULT,
	RENDER_TYPE_V_GENERIC,

	// FRAGMENT PROGRAM
	RENDER_TYPE_F_DEFAULT,
	RENDER_TYPE_F_GENERIC,

	RENDER_TYPE_INVALID
}enum_render_type;

/*=========================================================
 Vertex Attribute Position
=========================================================*/
#define	ATTR_VERTEX_POS			0
#define	ATTR_TEXCOORD0_POS		8
#define	ATTR_TEXCOORD1_POS		9
#define	ATTR_TANGENT_POS		6
#define	ATTR_BINORMAL_POS		7
#define	ATTR_NORMAL_POS			10
#define	ATTR_LIGHT_POS			11
#define	ATTR_COLOR_POS			12

/*=========================================================
 ENV PARAMETERS POS
=========================================================*/
#define	ENV_VIEW_ORIGIN_POS			0
#define	ENV_LIGHT_ORIGIN_POS		1
#define	ENV_LIGHT_COLOR_POS			2
#define	ENV_BUMP_SCALE_POS			3
#define	ENV_HEIGHT_SCALE_POS		4
#define	ENV_HEIGHT_BIAS_POS			5
#define	ENV_SPECULAR_EXP_POS		6
#define	ENV_SPECULAR_SCALE_POS		7
#define	ENV_REFRACTION_INDEX_POS	8
#define	ENV_ETA_RATIO_POS			9
#define	ENV_FRESNEL_POWER_POS		10
#define	ENV_FRESNEL_SCALE_POS		11
#define	ENV_FRESNEL_BIAS_POS		12
#define	ENV_DEFORM_MAGNITUDE_POS	13
#define	ENV_INVERSE_RADIUS_POS		14
#define	ENV_AMBIENT_POS				15
#define	ENV_FUSION_DEPTH_POS		16
#define	ENV_DIFFUSE_POS				17
#define	ENV_LIGHT_DIR_POS			18
#define	ENV_OFFSET_POS				19

/*=========================================================
 Uniform PARAMETERS
=========================================================*/
#define	UNIFORM_BUMP_SCALE		"u_bump_scale"
#define	UNIFORM_VIEW_ORIGIN		"u_view_origin"
#define	UNIFORM_LIGHT_ORIGIN	"u_light_origin"
#define	UNIFORM_LIGHT_COLOR		"u_light_color"
#define	UNIFORM_HEIGHT_SCALE	"u_height_scale"
#define	UNIFORM_HEIGHT_BIAS		"u_height_bias"
#define	UNIFORM_SPECULAR_EXP	"u_specular_exponent"
#define	UNIFORM_SPECULAR_SCALE	"u_specular_scale"
#define	UNIFORM_REFRACTION_INDEX "u_refraction_index"
#define	UNIFORM_ETA_RATIO		"u_eta_ratio"
#define	UNIFORM_FRESNEL_POWER	"u_fresnel_power"
#define	UNIFORM_FRESNEL_SCALE	"u_fresnel_scale"
#define	UNIFORM_FRESNEL_BIAS	"u_fresnel_bias"
#define	UNIFORM_DEFORM_MAGNITUDE "u_deform_magnitude"
#define	UNIFORM_INVERSE_RADIUS	"u_inverse_radius"
#define	UNIFORM_AMBIENT			"u_ambient"
#define	UNIFORM_FUSION_DEPTH	"u_fusion_depth"
#define	UNIFORM_DIFFUSE			"u_diffuse"
#define	UNIFORM_OFFSET			"u_offset"
#define	UNIFORM_HEIGHT_SCALE	"u_height_scale"
#define	UNIFORM_HEIGHT_RANGE	"u_height_range"

/*=========================================================
 LOCAL PARAMETERS POS - TODO
=========================================================*/
#define LOC_ATTPARAMS_POS				0
#define LOC_BOOLMODIFYCOLORS_POS		1
#define LOC_HEIGHT_SCALE_POS			2
#define LOC_HEIGHT_RANGE_POS			3
#define LOC_LIGHT_COLOR_POS				4
//...
//...
#define	UNIFORM_ATT_PARAMS		"u_attparams"


/*=========================================================
 shader_ARBparams_t
=========================================================*/
typedef struct
{
	// public user
	vec4_t	param_BumpScale;
	vec4_t	param_SpecularExponent;
	vec4_t	param_SpecularScale;
	vec4_t	param_Ambient;
	vec4_t	param_Diffuse;
	vec4_t	param_attParams;
	vec4_t	param_HeightScale;
	vec4_t	param_HeightRange;
} shader_ARBparams_t;

/*=========================================================
 shader_formatdescriptor_t
=========================================================*/
typedef struct
{
	enum_render_type	render_type;
	const char			*cmd;
	enum_flag_attribute	flag_attrib;
} shader_formatdescriptor_t;

/*=========================================================
 Prototypes Communications
=========================================================*/
enum_render_type	R_GetRenderTypesFromCmd(const char *cmd);
const char			*R_GetCommandRenderTypes(enum_render_type et);
enum_flag_attribute R_GetAttribRenderTypes(enum_render_type et);

extern inline void		R_EnableVertexAttribsArrays(enum_flag_attribute flags);
extern inline void		R_SetVertexAttribPointers(enum_flag_attribute flags, const void *VertexArray, const void *CoordsArray0,
						const void *CoordsArray1, const void *TangentsArray, const void *BinormalsArray,
						const void *NormalsArray, const void *LightsArray, const void *ColorsArray);
extern inline void		R_DisableVertexAttribsArrays(enum_flag_attribute flags);

#define MAX_ARB_PROGRAMS		512

/*=========================================================
 struct ARB_program_t
=========================================================*/
typedef struct ARB_program_s {
	char				name[MAX_QPATH];
	unsigned			uploadTarget;
	unsigned			progNum;
	struct ARB_program_s	*nextHash;
} ARB_program_t;

extern ARB_program_t	*r_ARB_defaultVertexProgram;
extern ARB_program_t	*r_ARB_defaultFragmentProgram;

/*=========================================================
API
=========================================================*/
void		R_ARB_ProgramList_f (void);
ARB_program_t	*R_ARB_FindProgram (const char *name, unsigned target);
void		R_ARB_InitPrograms (void);
void		R_ARB_ShutdownPrograms (void);


/*=========================================================
 Prototypes Rendering - r_arb_backend.c
=========================================================*/
void R_RenderMesh_ARB_Program( void );

/*
 =======================================================================
 END ARB PROGRAM MANAGER
 =======================================================================
*/
#endif // MYSTICARB

//===================================================================

enum
{
	rserr_ok,

	rserr_invalid_fullscreen,
	rserr_invalid_mode,

	rserr_unknown
} rserr_t;

#include "r_math.h"
#include "r_mesh.h"
#include "r_shader.h"
#include "r_backend.h"
#include "r_shadow.h"
#include "r_model.h"

#define BACKFACE_EPSILON	0.01

#define	ON_EPSILON			0.1			// point on plane side epsilon

#define	SIDE_FRONT			0
#define	SIDE_BACK			1
#define	SIDE_ON				2

//====================================================

typedef struct
{
	vec3_t		origin;
	vec3_t		color;
	vec3_t		mins, maxs;
	float		intensity;
	shader_t	*shader;
} dlight_t;

typedef struct
{
	int			features;
	int			lightmapNum[MAX_LIGHTMAPS];
	int			lightmapStyles[MAX_LIGHTMAPS];
	int			vertexStyles[MAX_LIGHTMAPS];
} superLightStyle_t;

//====================================================

extern	char		*r_cubemapSuff[6];

extern qboolean		r_ligtmapsPacking;

extern	image_t		*r_cintexture;
extern	image_t		*r_notexture;
extern	image_t		*r_whitetexture;
extern	image_t		*r_particletexture;
extern	image_t		*r_dlighttexture;
extern	image_t		*r_fogtexture;
extern	image_t		*r_lightmapTextures[];

extern	entity_t	*currententity;
extern	model_t		*currentmodel;

extern	int			r_visframecount;
extern	int			r_framecount;
extern	cplane_t	frustum[4];
extern	int			c_brush_polys, c_world_leafs;

extern	unsigned int	r_mark_leaves, r_mark_lights, r_world_node;
extern	unsigned int	r_add_polys, r_add_entities;
extern	unsigned int	r_sort_meshes, r_draw_meshes;

extern	int			gl_filter_min, gl_filter_max;

extern	float		gldepthmin, gldepthmax;

//
// view origin
//
extern	vec3_t		vup;
extern	vec3_t		vpn;
extern	vec3_t		vright;
extern	vec3_t		r_origin;

extern	qboolean	r_portalview;	// if true, get vis data at
extern	vec3_t		r_portalorg;	// portalorg instead of vieworg

extern	qboolean	r_mirrorview;	// if true, lock pvs

extern	qboolean	r_envview;

extern	cplane_t	r_clipplane;

//
// screen size info
//
extern	int			r_numEntities;
extern	entity_t	r_entities[MAX_ENTITIES];

extern	int			r_numDlights;
extern	dlight_t	r_dlights[MAX_DLIGHTS];

extern	int			r_numPolys;
extern	poly_t		r_polys[MAX_POLYS];

extern	lightstyle_t	r_lightStyles[MAX_LIGHTSTYLES];

extern	refdef_t	r_refdef;
extern	refdef_t	r_lastRefdef;

extern	int			r_viewcluster, r_oldviewcluster;

extern	float		r_farclip, r_farclip_min, r_farclip_bias;

extern	entity_t	r_worldent;
extern	model_t		*r_worldmodel;

extern	cvar_t		*r_stencilbits;
extern	cvar_t		*r_colorbits;

extern	cvar_t		*r_norefresh;
extern	cvar_t		*r_drawentities;
extern	cvar_t		*r_drawworld;
extern	cvar_t		*r_speeds;
extern	cvar_t		*r_fullbright;
extern	cvar_t		*r_lightmap;
extern	cvar_t		*r_novis;
extern	cvar_t		*r_nocull;
extern	cvar_t		*r_lerpmodels;
extern	cvar_t		*r_fastsky;
extern	cvar_t		*r_ignorehwgamma;
extern	cvar_t		*r_overbrightbits;
extern	cvar_t		*r_mapoverbrightbits;
extern	cvar_t		*r_flares;
extern	cvar_t		*r_flaresize;
extern	cvar_t		*r_flarefade;
extern	cvar_t		*r_dynamiclight;
extern	cvar_t		*r_detailtextures;
extern	cvar_t		*r_subdivisions;
extern	cvar_t		*r_faceplanecull;
extern	cvar_t		*r_showtris;
extern	cvar_t		*r_shownormals;
extern	cvar_t		*r_ambientscale;
extern	cvar_t		*r_directedscale;
extern	cvar_t		*r_draworder;
extern	cvar_t		*r_packlightmaps;
extern	cvar_t		*r_spherecull;
extern	cvar_t		*r_bumpscale;
extern	cvar_t		*r_maxlmblocksize;

extern	cvar_t		*gl_extensions;
extern	cvar_t		*gl_ext_multitexture;
extern	cvar_t		*gl_ext_compiled_vertex_array;
extern	cvar_t		*gl_ext_texture_env_add;
extern	cvar_t		*gl_ext_texture_env_combine;
extern	cvar_t		*gl_ext_texture_env_dot3;
extern	cvar_t		*gl_ext_NV_texture_env_combine4;
extern	cvar_t		*gl_ext_compressed_textures;
extern	cvar_t		*gl_ext_texture_edge_clamp;
extern	cvar_t		*gl_ext_texture_filter_anisotropic;
extern	cvar_t		*gl_ext_max_texture_filter_anisotropic;
extern	cvar_t		*gl_ext_max_texture_filter_anisotropic;
extern	cvar_t		*gl_ext_draw_range_elements;
#ifdef VERTEX_BUFFER_OBJECTS
extern	cvar_t		*gl_ext_vertex_buffer_object;
#endif
extern	cvar_t		*gl_ext_texture_cube_map;
extern	cvar_t		*gl_ext_bgra;
extern	cvar_t		*gl_ext_texture3D;

#ifdef MYSTICARB
extern  cvar_t		*gl_arb_program;
#endif

extern	cvar_t		*r_shadows;
extern	cvar_t		*r_shadows_alpha;
extern	cvar_t		*r_shadows_nudge;
extern	cvar_t		*r_shadows_projection_distance;

extern	cvar_t		*r_lodbias;
extern	cvar_t		*r_lodscale;

extern	cvar_t		*r_gamma;
extern	cvar_t		*r_colorbits;
extern	cvar_t		*r_texturebits;
extern	cvar_t		*r_texturemode;
extern	cvar_t		*r_mode;
extern	cvar_t		*r_nobind;
extern	cvar_t		*r_picmip;
extern	cvar_t		*r_skymip;
extern	cvar_t		*r_clear;
extern	cvar_t		*r_polyblend;
extern  cvar_t		*r_lockpvs;
extern	cvar_t		*r_screenshot_jpeg;
extern	cvar_t		*r_screenshot_jpeg_quality;
extern	cvar_t		*r_swapinterval;

extern	cvar_t		*gl_finish;
extern	cvar_t		*gl_delayfinish;
extern	cvar_t		*gl_cull;
extern	cvar_t		*gl_drawbuffer;
extern  cvar_t		*gl_driver;

extern	cvar_t		*vid_fullscreen;

extern	mat4x4_t	r_worldview_matrix;
extern	mat4x4_t	r_modelview_matrix;
extern	mat4x4_t	r_projection_matrix;

//====================================================================

static inline qbyte R_FloatToByte( float x )
{
	union {
		float			f;
		unsigned int	i;
	} f2i;

	// shift float to have 8bit fraction at base of number
	f2i.f = x + 32768.0f;
	f2i.i &= 0x7FFFFF;

	// then read as integer and kill float bits...
	return ( qbyte )min( f2i.i, 255 );
}

float R_FastSin( float t );
void R_LatLongToNorm( qbyte latlong[2], vec3_t out );

//====================================================================

//
// r_alias.c
//
void	R_AddAliasModelToList( entity_t *e );
void	R_DrawAliasModel( const meshbuffer_t *mb, qboolean shadow );
qboolean R_AliasModelLerpTag( orientation_t *orient, maliasmodel_t *aliasmodel, int framenum, int oldframenum, float lerpfrac, const char *name );

//
// r_cin.c
//
void	R_PlayCinematic( cinematics_t *cin );
void	R_RunCinematic( cinematics_t *cin );
void	R_StopCinematic( cinematics_t *cin );
image_t *R_ResampleCinematicFrame( shaderpass_t *pass );

//
// r_image.c
//
void	GL_SelectTexture( int tmu );
void	GL_Bind( int tmu, image_t *tex );
void	GL_TexEnv( GLenum mode );
void	GL_LoadTexMatrix( mat4x4_t m );
void	GL_LoadIdentityTexMatrix( void );

void	R_InitImages( void );
void	R_ShutdownImages( void );

void	R_ScreenShot_f( void );
void	R_EnvShot_f( void );
void	R_ImageList_f( void );
void	R_TextureMode( char *string );

image_t *R_LoadPic( char *name, qbyte **pic, int width, int height, int flags, int samples );
image_t	*R_FindImage( char *name, int flags, float bumpScale );
image_t *R_LoadCubemapPic( char *name, qbyte *pic[6], int width, int height, int flags, int samples );
image_t	*R_FindCubemapImage( char *name, int flags );

void	R_Upload32( qbyte **data, int width, int height, int flags, int *upload_width, int *upload_height, int samples, qboolean subImage );

//
// r_light.c
//
#define DLIGHT_SCALE		0.5f
#define MAX_SUPER_STYLES	1023

extern	int		r_numSuperLightStyles;
extern	superLightStyle_t	r_superLightStyles[MAX_SUPER_STYLES];

void	R_LightBounds( const vec3_t origin, float intensity, vec3_t mins, vec3_t maxs );
qboolean R_SurfPotentiallyLit( msurface_t *surf );
void	R_MarkLightsWorldNode( void );
void	R_MarkLightsBmodel( const entity_t *e, const vec3_t mins, const vec3_t maxs );
void	R_AddDynamicLights( unsigned int dlightbits, GLenum func, GLenum sfactor, GLenum dfactor );
void	R_LightForEntity( entity_t *e, qbyte *bArray );
void	R_LightForEntityDot3( entity_t *e, qbyte *bArray, vec4_t ambient, vec4_t diffuse );
void	R_LightForOrigin( vec3_t origin, vec3_t dir, vec4_t ambient, vec4_t diffuse, float radius );
void	R_BuildLightmaps( int numLightmaps, int w, int h, const qbyte *data, mlightmapRect_t *rects );
void	R_InitLightStyles( void );
int		R_AddSuperLightStyle( const int *lightmaps, const qbyte *lightmapStyles, const qbyte *vertexStyles );
void	R_SortSuperLightStyles( void );

//
// r_main.c
//
int 	R_Init( void *hinstance, void *hWnd );
void	R_InitMedia( void );
void	R_FreeMedia( void );
void	R_Restart( void );
void	R_Shutdown( void );
void	R_BeginFrame( float cameraSeparation );
void	R_EndFrame( void );

void	R_RenderView( refdef_t *fd, meshlist_t *list );

qboolean R_CullBox( const vec3_t mins, const vec3_t maxs, const int clipflags );
qboolean R_CullSphere( const vec3_t centre, const float radius, const int clipflags );
qboolean R_VisCullBox( const vec3_t mins, const vec3_t maxs );
qboolean R_VisCullSphere( const vec3_t origin, float radius );

mfog_t	*R_FogForSphere( const vec3_t centre, const float radius );
void	R_LoadIdentity( void );
void	R_RotateForEntity( entity_t *e );
void	R_TranslateForEntity( entity_t *e );
void	R_TransformToScreen_Vec3( vec3_t in, vec3_t out );
void	R_TransformVectorToScreen( refdef_t *rd, vec3_t in, vec2_t out );

void	R_PushFlareSurf( const meshbuffer_t *mb );
qboolean R_SpriteOverflow( void );
void	R_AddSpriteModelToList( entity_t *e );
void	R_DrawSpriteModel( const meshbuffer_t *mb );
void	R_AddSpritePolyToList( entity_t *e );
void	R_DrawSpritePoly( const meshbuffer_t *mb );

//
// r_poly.c
//
qboolean R_PolyOverflow( const meshbuffer_t *mb );
void	R_PushPoly( const meshbuffer_t *mb );
void	R_DrawPoly( const meshbuffer_t *mb );
void	R_AddPolysToList( void );
qboolean R_SurfPotentiallyFragmented( msurface_t *surf );
int		R_GetClippedFragments( vec3_t origin, float radius, vec3_t axis[3], int maxfverts, vec3_t *fverts, int maxfragments, fragment_t *fragments );

//
// r_surf.c
//
void	R_MarkLeaves( void );
void	R_DrawWorld( void );
qboolean R_SurfPotentiallyVisible( msurface_t *surf );
void	R_AddBrushModelToList( entity_t *e );
void	R_FixAutosprites( msurface_t *surf );

//
// r_skin.c
//
void R_InitSkinFiles( void );
void R_ShutdownSkinFiles( void );
struct skinfile_s *R_SkinFile_Load( char *name );
struct skinfile_s *R_RegisterSkinFile( char *name );
shader_t *R_FindShaderForSkinFile( struct skinfile_s *skinfile, char *meshname );

//
// r_skm.c
//
void	R_AddSkeletalModelToList( entity_t *e );
void	R_DrawSkeletalModel( const meshbuffer_t *mb, qboolean shadow );

//
// r_warp.c
//
skydome_t *R_CreateSkydome( float skyheight, shader_t **farboxShaders, shader_t	**nearboxShaders );
void	R_FreeSkydome( skydome_t *skydome );
void	R_ClearSkyBox( void );
void	R_DrawSky( shader_t *shader );
void	R_AddSkySurface( msurface_t *fa );

//BLOOMS[start] 
// 
// r_bloom.c 
// 
void R_BloomBlend( refdef_t *fd ); 
void R_InitBloomTextures( void ); 
//BLOOMS[end]

//====================================================================

/*
** GL config stuff
*/
#define GL_RENDERER_VOODOO		0x00000001
#define GL_RENDERER_VOODOO2   	0x00000002
#define GL_RENDERER_VOODOO_RUSH	0x00000004
#define GL_RENDERER_BANSHEE		0x00000008
#define	GL_RENDERER_3DFX		0x0000000F

#define GL_RENDERER_PCX1		0x00000010
#define GL_RENDERER_PCX2		0x00000020
#define GL_RENDERER_PMX			0x00000040
#define	GL_RENDERER_POWERVR		0x00000070

#define GL_RENDERER_PERMEDIA2	0x00000100
#define GL_RENDERER_GLINT_MX	0x00000200
#define GL_RENDERER_GLINT_TX	0x00000400
#define GL_RENDERER_3DLABS_MISC	0x00000800
#define	GL_RENDERER_3DLABS		0x00000F00

#define GL_RENDERER_REALIZM		0x00001000
#define GL_RENDERER_REALIZM2	0x00002000
#define	GL_RENDERER_INTERGRAPH	0x00003000

#define GL_RENDERER_3DPRO		0x00004000
#define GL_RENDERER_REAL3D		0x00008000
#define GL_RENDERER_RIVA128		0x00010000
#define GL_RENDERER_DYPIC		0x00020000

#define GL_RENDERER_V1000		0x00040000
#define GL_RENDERER_V2100		0x00080000
#define GL_RENDERER_V2200		0x00100000
#define	GL_RENDERER_RENDITION	0x001C0000

#define GL_RENDERER_O2          0x00100000
#define GL_RENDERER_IMPACT      0x00200000
#define GL_RENDERER_RE			0x00400000
#define GL_RENDERER_IR			0x00800000
#define	GL_RENDERER_SGI			0x00F00000

#define GL_RENDERER_MCD			0x01000000
#define GL_RENDERER_OTHER		0x80000000

typedef struct
{
	int         renderer;
	const char	*rendererString;
	const char	*vendorString;
	const char	*versionString;
	const char	*extensionsString;

	qboolean	allowCDS;

	int			maxTextureSize;
	int			maxTextureUnits;
	int			maxTextureCubemapSize;
	int			max3DTextureSize;

	qboolean	compiledVertexArray;
	qboolean	multiTexture;
	qboolean	textureCubeMap;
	qboolean	textureEnvAdd;
	qboolean	textureEnvCombine;
	qboolean	textureEnvDot3;
	qboolean	NVTextureEnvCombine4;
	qboolean	textureEdgeClamp;
	qboolean	textureFilterAnisotropic;
	int			maxTextureFilterAnisotropic;
	qboolean	compressedTextures;
	qboolean	drawRangeElements;
#ifdef VERTEX_BUFFER_OBJECTS
	qboolean	vertexBufferObject;
#endif
	qboolean	bgra;
	qboolean	texture3D;

#ifdef MYSTICARB
	qboolean	arb_program;
	int			arb_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB;
	int			arb_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB;
	int			arb_MAX_PROGRAM_TEX_INDIRECTIONS_ARB;
	int			arb_MAX_PROGRAM_LOCAL_PARAMETERS_ARB;
	int			arb_MAX_PROGRAM_ENV_PARAMETERS_ARB;
	int			arb_MAX_PROGRAM_TEMPORARIES_ARB;
	int			arb_MAX_PROGRAM_ATTRIBS_ARB;
#endif
} glconfig_t;

typedef struct
{
	int			width, height;
	qboolean	fullScreen;

	qboolean	initializedMedia;

	int			previousMode;

	int			currentTMU;
	int			currentTextures[MAX_TEXTURE_UNITS];
	int			currentEnvModes[MAX_TEXTURE_UNITS];
	qboolean	texIdentityMatrix[MAX_TEXTURE_UNITS];

	float		cameraSeparation;
	qboolean	stereoEnabled;
	qboolean	stencilEnabled;
	qboolean	in2DMode;

	qboolean	hwGamma;
	unsigned short orignalGammaRamp[3*256];

	float		pow2MapOvrbr;
	float		invPow2Ovrbr;
} glstate_t;

extern glconfig_t  glConfig;
extern glstate_t   glState;

/*
====================================================================

IMPLEMENTATION SPECIFIC FUNCTIONS

====================================================================
*/

void		GLimp_BeginFrame( void );
void		GLimp_EndFrame( void );
int 		GLimp_Init( void *hinstance, void *hWnd );
void		GLimp_Shutdown( void );
int     	GLimp_SetMode( int mode, qboolean fullscreen );
void		GLimp_AppActivate( qboolean active );
qboolean	GLimp_GetGammaRamp( size_t stride, unsigned short *ramp );
void		GLimp_SetGammaRamp( size_t stride, unsigned short *ramp );

void		VID_NewWindow( int width, int height);
qboolean	VID_GetModeInfo( int *width, int *height, int mode );
