/*
Copyright (C) 1996-1997 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.

*/
// disable data conversion warnings

#ifdef _WIN32
#pragma warning (disable : 4244)     // MIPS
#pragma warning (disable : 4136)     // X86
#pragma warning (disable : 4051)     // ALPHA
  
//#ifdef _WIN32
#include <windows.h>
#endif

#include <GL/gl.h>
#include <GL/glu.h>	// by joe
#include <GL/glext.h>

void GL_BeginRendering (int *x, int *y, int *width, int *height);
void GL_EndRendering (void);


// Function prototypes for the Texture Object Extension routines
typedef GLboolean (APIENTRY *ARETEXRESFUNCPTR)(GLsizei, const GLuint *, const GLboolean *);
typedef void (APIENTRY *BINDTEXFUNCPTR)(GLenum, GLuint);
typedef void (APIENTRY *DELTEXFUNCPTR)(GLsizei, const GLuint *);
typedef void (APIENTRY *GENTEXFUNCPTR)(GLsizei, GLuint *);
typedef GLboolean (APIENTRY *ISTEXFUNCPTR)(GLuint);
typedef void (APIENTRY *PRIORTEXFUNCPTR)(GLsizei, const GLuint *, const GLclampf *);
typedef void (APIENTRY *TEXSUBIMAGEPTR)(int, int, int, int, int, int, int, int, void *);

extern	BINDTEXFUNCPTR bindTexFunc;
extern	DELTEXFUNCPTR delTexFunc;
extern	TEXSUBIMAGEPTR TexSubImage2DFunc;

extern	int		texture_extension_number;
extern	float	gldepthmin, gldepthmax;
extern	int		gl_max_size_default;


// added by joe
#define	TEX_COMPLAIN		1
#define TEX_MIPMAP			2
#define TEX_ALPHA			4
#define TEX_LUMA			8
#define TEX_FULLBRIGHT		16
#define	TEX_BRIGHTEN		32
#define	TEX_BLEND			64

#define	MAX_GLTEXTURES 4096

void GL_SelectTexture (GLenum target);
void GL_DisableMultitexture (void);
void GL_EnableMultitexture (void);
void GL_EnableTMU (GLenum target);
void GL_DisableTMU (GLenum target);

void GL_Upload32 (unsigned *data, int width, int height, int mode);
void GL_Upload8 (byte *data, int width, int height, int mode);
int GL_LoadTexture (char *identifier, int width, int height, byte *data, int mode, int bytesperpixel);
byte *GL_LoadImagePixels (char* filename, int matchwidth, int matchheight, int mode);
int GL_LoadTextureImage (char *filename, char *identifier, int matchwidth, int matchheight, int mode);
int GL_LoadPicTexture (char *name, mpic_t *pic, byte *data);
mpic_t *GL_LoadPicImage (char *filename, char *id, int matchwidth, int matchheight, int mode);
int GL_LoadCharsetImage (char *filename, char *identifier);

qboolean OnChange_r_skybox (cvar_t *var, char *string);
qboolean OnChange_gl_max_size (cvar_t *var, char *string);
qboolean OnChange_gl_texturemode (cvar_t *var, char *string);
qboolean OnChange_gl_crosshairimage (cvar_t *var, char *string);
qboolean OnChange_gl_smoothfont (cvar_t *var, char *string);

typedef struct
{
	float	x, y, z;
	float	s, t;
	float	r, g, b;
} glvert_t;

extern glvert_t	glv;

extern	int	glx, gly, glwidth, glheight;

#ifdef _WIN32
extern	PROC glArrayElementEXT;
extern	PROC glColorPointerEXT;
extern	PROC glTexturePointerEXT;
extern	PROC glVertexPointerEXT;
#endif

// r_local.h -- private refresh defs

#define ALIAS_BASE_SIZE_RATIO		(1.0 / 11.0)
					// normalizing factor so player model works out to about
					//  1 pixel per triangle
#define	MAX_LBM_HEIGHT		480

#define SKYSHIFT		7
#define	SKYSIZE			(1 << SKYSHIFT)
#define SKYMASK			(SKYSIZE - 1)

#define BACKFACE_EPSILON	0.01


void R_TimeRefresh_f (void);
void R_ReadPointFile_f (void);
texture_t *R_TextureAnimation (texture_t *base);


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

void QMB_InitParticles (void);
void QMB_ClearParticles (void);
void QMB_DrawParticles (void);

void QMB_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count);
void QMB_RocketTrail (vec3_t start, vec3_t end, trail_type_t type);
void QMB_BlobExplosion (vec3_t org);
void QMB_ParticleExplosion (vec3_t org);
void QMB_LavaSplash (vec3_t org);
void QMB_TeleportSplash (vec3_t org);
void QMB_InfernoFlame (vec3_t org);
void QMB_StaticBubble (entity_t *ent);
void QMB_ColorMappedExplosion (vec3_t org, int colorStart, int colorLength);
void QMB_TorchFlame (vec3_t org);
void QMB_BigTorchFlame (vec3_t org);
void QMB_LightningBeam (vec3_t start, vec3_t end);
void QMB_ShamblerCharge (vec3_t org);

extern	qboolean	qmb_initialized;
extern  qboolean	skyboxloaded;

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


extern	entity_t	r_worldentity;
extern	qboolean	r_cache_thrash;		// compatability
extern	vec3_t		modelorg, r_entorigin;
extern	entity_t	*currententity;
extern	int			r_visframecount;	// ??? what difs?
extern	int			r_framecount;
extern	mplane_t	frustum[4];
extern	int			c_brush_polys, c_alias_polys;


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

// screen size info
extern	refdef_t	r_refdef;
extern	mleaf_t		*r_viewleaf, *r_oldviewleaf;
extern	mleaf_t		*r_viewleaf2, *r_oldviewleaf2;	// for watervis hack
extern	texture_t	*r_notexture_mip;
extern	int		d_lightstylevalue[256];	// 8.8 fraction of base light value

extern	int	currenttexture;
extern	int	particletexture;
extern	int	skyboxtextures;
extern	int	underwatertexture;
extern	int	detailtexture;
extern  int chrometexture;
extern  int glasstexture;
extern  int	newwatertex;
extern  int	newlavatex;
extern  int	newslimetex;
extern  int	newteletex;

extern	int playertextures;
extern  int playerfbtextures;

extern  cvar_t  r_vertex_arrays;
extern	cvar_t	r_drawentities;
extern	cvar_t	r_drawworld;
extern	cvar_t	r_drawviewmodel;
extern	cvar_t	r_viewmodelsize;
extern	cvar_t	r_speeds;
extern	cvar_t	r_waterwarp;
extern	cvar_t	r_fullbright;
extern	cvar_t	r_lightmap;
extern	cvar_t	r_shadows;
extern	cvar_t	r_wateralpha;
extern	cvar_t	r_liquidshade;
extern	cvar_t	r_dynamic;
extern	cvar_t	r_novis;
extern	cvar_t	r_fullbrightskins;
extern	cvar_t	r_fastsky;
extern	cvar_t	r_skycolor;
extern	cvar_t	r_skybox;
extern	cvar_t	r_farclip;
extern  cvar_t  r_waterripple;

// fenix@io.com: model interpolation
extern  cvar_t  gl_interpolate_animation;
extern  cvar_t  gl_interpolate_transform;

extern	cvar_t	gl_clear;
extern	cvar_t	gl_cull;
extern	cvar_t	gl_poly;
extern	cvar_t	gl_ztrick;
extern	cvar_t	gl_smoothmodels;
extern	cvar_t	gl_affinemodels;
extern	cvar_t	gl_polyblend;
extern	cvar_t	gl_flashblend;
extern	cvar_t	gl_nocolors;
extern	cvar_t	gl_loadlitfiles;	// by joe
extern  cvar_t  gl_lerpimages;
extern	cvar_t	gl_doubleeyes;
extern	cvar_t	gl_interdist;		// joe: only for debug
extern  cvar_t  gl_waterfog;		
extern  cvar_t  gl_waterfog_density;
extern  cvar_t  gl_detail;
extern  cvar_t  gl_caustics;
extern  cvar_t  gl_shiny;
extern	cvar_t	gl_fb_bmodels;
extern	cvar_t	gl_fb_models;
extern  cvar_t	gl_hwblend;
extern  cvar_t  gl_vertexlights;
extern  cvar_t  gl_coronas;
extern	cvar_t	gl_triplebuffer;

extern  cvar_t	gl_part_explosions;
extern  cvar_t	gl_part_trails;
extern  cvar_t	gl_part_spikes;
extern  cvar_t	gl_part_gunshots;
extern  cvar_t	gl_part_blood;
extern  cvar_t	gl_part_telesplash;
extern  cvar_t	gl_part_blobs;
extern  cvar_t	gl_part_lavasplash;
extern  cvar_t	gl_part_inferno;
extern	cvar_t	gl_part_flames;
extern	cvar_t	gl_part_lightning;
extern	cvar_t	gl_bounceparticles;
extern	cvar_t	gl_clipparticles;
extern	cvar_t	gl_q3particles;
extern	cvar_t	gl_ringalpha;

// fogging code
extern  cvar_t  gl_fogenable; 
extern  cvar_t  gl_fogstart;
extern  cvar_t  gl_fogend; 
extern  cvar_t  gl_fogred; 
extern  cvar_t  gl_fogblue; 
extern  cvar_t  gl_foggreen; 
extern  cvar_t  gl_fogdensity; 
extern  cvar_t  gl_fogalpha;

// by joe - gamma
extern	cvar_t	gl_contrast;
extern	cvar_t	gl_gamma;

extern	int		lightmode;		// by joe

extern	int		gl_lightmap_format;
extern	int		gl_solid_format;
extern	int		gl_alpha_format;

extern	cvar_t	gl_max_size;
extern	cvar_t	gl_playermip;
extern	cvar_t	gl_picmip_all;
extern  cvar_t  gl_subdivide_size;

extern	float	bubblecolor[NUM_DLIGHTTYPES][4];
extern	float	r_world_matrix[16];
extern	float	wateralpha;
extern  float	watershade;
extern	float	vlight_pitch, vlight_yaw;

extern	const char *gl_vendor;
extern	const char *gl_renderer;
extern	const char *gl_version;
extern	const char *gl_extensions;

void GL_Bind (int texnum);

// Multitexture
#define	GL_TEXTURE0_ARB 				  0x84C0
#define	GL_TEXTURE1_ARB 				  0x84C1
#define	GL_TEXTURE2_ARB 				  0x84C2
#define	GL_TEXTURE3_ARB 				  0x84C3
#define GL_MAX_TEXTURE_UNITS_ARB		  0x84E2

typedef void (APIENTRY *lpMTexFUNC) (GLenum, GLfloat, GLfloat);
typedef void (APIENTRY *lpSelTexFUNC) (GLenum);

extern lpMTexFUNC qglMultiTexCoord2f;
extern lpSelTexFUNC qglActiveTexture;

extern	qboolean	gl_add_ext;
extern  qboolean	gl_mtexable;
extern  int			gl_textureunits;

void GL_DisableMultitexture (void);
void GL_EnableMultitexture (void);

// vid_common_gl.c
void VID_CheckGamma (unsigned char *pal);
void VID_SetPalette (unsigned char *palette);
void VID_InitGL (void);

// gl_image.c
extern	int	image_width;
extern	int	image_height;
byte *LoadTGA (FILE *fin, char *name, int matchwidth, int matchheight);
int WriteTGA (char *filename, byte *pixels, int width, int height);
byte *LoadPNG (FILE *fin, char *filename, int matchwidth, int matchheight);
int WritePNG (char *filename, int compression, byte *pixels, int width, int height);

// gl_warp.c
void GL_SubdivideSurface (msurface_t *fa);
void EmitWaterPolys (msurface_t *fa);
void EmitSkyPolys (msurface_t *fa, qboolean mtex);
void EmitCausticsPolys (void);
void EmitDetailPolys (void);
void EmitChromePolys (void);
void EmitGlassPolys (void);

void R_DrawSkyChain (void);
void R_AddSkyBoxSurface (msurface_t *fa);
void R_ClearSkyBox (void);
void R_DrawSkyBox (void);
int R_SetSky (char *skyname);		// by joe

// gl_draw.c
void GL_Set2D (void);

// gl_rmain.c
qboolean R_CullBox (vec3_t mins, vec3_t maxs);
qboolean R_CullSphere (vec3_t centre, float radius); 
void R_RotateForEntity (entity_t *e);
void R_PolyBlend (void);
void R_BrightenScreen (void);

// gl_rlight.c
void R_MarkLights (dlight_t *light, int bit, mnode_t *node);
void R_AnimateLight (void);
void R_RenderDlights (void);
void R_InitVertexLights (void);
int R_LightPoint (vec3_t p);
float R_LerpVertexLight (int index1, int index2, float ilerp, float apitch, float ayaw);
float R_VertexLight (int index, float apitch, float ayaw);

// gl_refrag.c
void R_StoreEfrags (efrag_t **ppefrag);

// gl_mesh.c
void GL_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr);

// gl_rsurf.c
void R_RenderDynamicLightmaps (msurface_t *fa);
void R_DrawBrushModel (entity_t *e);
void R_DrawWorld (void);
void R_DrawGLPoly (glpoly_t *p);
void GL_BuildLightmaps (void);

// gl_rmisc
void R_InitOtherTextures(void);		
