//-----------------------------------------------------------------------------
//
//  $Logfile:: /Source/gl_local.h                                             $
// $Revision:: 3                                                              $
//   $Author:: Burgermac                                                      $
//     $Date:: 8/21/01 6:07 PM                                                $
//
// Copyright (C) 1998 by Ritual Entertainment, Inc.
// All rights reserved.
//
// This source is may not be distributed and/or modified without
// expressly written permission by Ritual Entertainment, Inc.
//

#ifndef __GL_LOCAL_H__
#define __GL_LOCAL_H__

#ifndef __GL_LOC1_H__
#include "gl_loc1.h"
#endif

#ifndef __GL_MODEL_H__
#include "gl_model.h"
#endif

#ifndef __GL_ARRAYS_H__
#include "gl_arrays.h"
#endif

#ifndef __GL_STATE_H__
#include "gl_state.h"
#endif

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

typedef struct conInfo_t {
	float surface_width;
	float surface_height;
	vec3_t u;
	vec3_t v;
	vec3_t n;
	vec3_t origin;
	qboolean onscreen;
	float alpha;
} conInfo_t;

#define	MAX_LBM_HEIGHT 480
#define BACKFACE_EPSILON 0.01

/* Knightmare - Moved here from gl_rsurf.c */

#define LIGHTMAP_BYTES 4

#define	LM_BLOCK_WIDTH	128
#define	LM_BLOCK_HEIGHT	128

#define	MAX_LIGHTMAPS	128

#define GL_LIGHTMAP_FORMAT GL_RGBA

#define BATCH_LM_UPDATES

typedef struct
{
	unsigned int	left;
	unsigned int	right;
	unsigned int	top;
	unsigned int	bottom;
} rect_t;

typedef struct {
	int internal_format;
	int	current_lightmap_texture;

	msurface_t	*lightmap_surfaces[MAX_LIGHTMAPS];

	int			allocated[LM_BLOCK_WIDTH];

	// the lightmap texture data needs to be kept in
	// main memory so texsubimage can update properly
	unsigned	lightmap_buffer[LM_BLOCK_WIDTH*LM_BLOCK_HEIGHT];
#ifdef BATCH_LM_UPDATES /* Knightmare added */
	unsigned	*lightmap_update[MAX_LIGHTMAPS];
	rect_t		lightrect[MAX_LIGHTMAPS];
	qboolean	modified[MAX_LIGHTMAPS];
#endif	// BATCH_LM_UPDATES
} gllightmapstate_t;

extern gllightmapstate_t gl_lms;
/* end Knightmare */

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _H2INC
void GL_BeginRendering (int *x, int *y, int *AMD_width, int *height);
#else
void GL_BeginRendering (int *x, int *y, int *width, int *height);
#endif
void GL_EndRendering (void);

void GL_SetDefaultState (void);
void GL_UpdateSwapInterval (void);

extern	float	gldepthmin, gldepthmax;

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



extern	image_t		*r_notexture;
extern	image_t		*r_particletexture;
extern	image_t		*r_specular;
extern	image_t		*r_envmap;
extern	image_t		*r_goldenvmap;

// 2015 code 
extern	image_t		*r_gogglesmap;
extern	cvar_t		*gl_drawflat;
extern	float		r_solidcolors[256*3];

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_alias_polys;

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

//
// screen size info
//
extern	refdef_t	r_newrefdef;
extern	int		r_viewcluster, r_viewcluster2, r_oldviewcluster, r_oldviewcluster2;

extern	cvar_t	*r_norefresh;
extern	cvar_t	*r_lefthand;
extern	cvar_t	*r_drawentities;
extern	cvar_t	*r_drawworld;
extern	cvar_t	*r_speeds;
extern	cvar_t	*r_fullbright;
extern	cvar_t	*r_novis;
extern	cvar_t	*r_nocull;
extern	cvar_t	*r_lerpmodels;

extern	cvar_t	*r_lightlevel;	// FIXME: This is a HACK to get the client's light level

extern cvar_t	*gl_vertex_arrays;

extern cvar_t	*gl_ext_swapinterval;
extern cvar_t	*gl_ext_multitexture;
extern cvar_t	*gl_ext_pointparameters;
extern cvar_t	*gl_ext_compiled_vertex_array;

extern cvar_t	*gl_particle_min_size;
extern cvar_t	*gl_particle_max_size;
extern cvar_t	*gl_particle_size;
extern cvar_t	*gl_particle_att_a;
extern cvar_t	*gl_particle_att_b;
extern cvar_t	*gl_particle_att_c;

extern	cvar_t	*gl_nosubimage;
extern	cvar_t	*gl_bitdepth;
extern	cvar_t	*gl_log;
extern	cvar_t	*gl_lightmap;
extern	cvar_t	*gl_shadows;
extern	cvar_t	*gl_dynamic;
extern	cvar_t  *gl_monolightmap;
extern	cvar_t	*gl_nobind;
extern	cvar_t	*gl_round_down;
extern	cvar_t	*gl_skymip;
extern	cvar_t	*gl_showtris;
extern	cvar_t	*gl_ztrick;
extern	cvar_t	*gl_clear;
extern	cvar_t	*gl_cull;
extern	cvar_t	*gl_poly;
extern	cvar_t	*gl_texsort;
extern	cvar_t	*gl_polyblend;
extern	cvar_t	*gl_flashblend;
extern	cvar_t	*gl_lightmaptype;
extern	cvar_t	*gl_modulate;
extern	cvar_t	*gl_playermip;
extern	cvar_t	*gl_drawbuffer;
extern	cvar_t	*gl_3dlabs_broken;
extern	cvar_t	*gl_swapinterval;
extern	cvar_t	*gl_texturemode;
extern	cvar_t	*gl_texturealphamode;
extern	cvar_t	*gl_texturesolidmode;
extern	cvar_t	*gl_saturatelighting;
extern	cvar_t	*gl_lockpvs;
extern	cvar_t	*vid_fullscreen;

extern	cvar_t	*r_conchars;
extern	cvar_t	*r_condist;
extern	cvar_t	*r_conoffset;
extern	cvar_t	*r_conthresh;
extern	cvar_t	*r_detaildist;
extern	cvar_t	*r_detailthresh;
extern	cvar_t	*gl_skintexturemode;
extern	cvar_t	*gl_showents;
extern	cvar_t	*r_monolighting;

typedef float vec4_t[4];
extern	vec4_t	s_lerped[MAX_VERTS];

extern	cvar_t	*gl_ignorehwgamma; /* FS */
extern	cvar_t	*gl_displayrefresh; /* FS */
extern	cvar_t	*vid_gamma;

/* Knightmare */
extern	cvar_t	*gl_shadows_stencil;
extern	cvar_t	*gl_bbox;
extern	cvar_t	*gl_render_immediate;
extern	cvar_t	*gl_lightcutoff;

extern	int		c_visible_lightmaps;
extern	int		c_visible_textures;

extern	float	r_world_matrix[16];

void R_TranslatePlayerSkin (int playernum);

#ifndef _H2INC

#endif

void R_LightPoint (vec3_t p, vec3_t color, qboolean dlight);
void R_PushDlights (void);

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

extern	model_t	*r_worldmodel;

extern byte d_8to24table[1024];

extern	int		registration_sequence;

void V_AddBlend (float r, float g, float b, float a, float *v_blend);

int 	R_Init (void *hinstance, void *hWnd);
void	R_Shutdown (void);

void R_RenderView (refdef_t *fd);
void GL_ScreenShot_f (void);
void R_DrawAliasModel (entity_t *e);
void R_DrawBrushModel (entity_t *e);
void R_DrawSpriteModel (entity_t *e);
void R_DrawBeam (entity_t *e);
void R_DrawWorld (void);
void R_RenderDlights (void);
void R_DrawAlphaSurfaces (void);
void R_RenderBrushPoly (msurface_t *fa);
void R_InitParticleTexture (void);
qboolean R_CullBox (vec3_t mins, vec3_t maxs);
void R_RotateForEntity (entity_t *e);
void R_MarkLeaves (void);

glpoly_t *WaterWarpPolyVerts (glpoly_t *p);
void R_MarkLights (dlight_t *light, int bit, mnode_t *node);

#ifndef _H2INC
void COM_StripExtension (const char *in, char *out);
#endif

void	R_BeginFrame (float camera_separation);
void	R_SwapBuffers (int);
void	R_SetPalette (const unsigned char *palette);

int		Draw_GetPalette (void);

void GL_ResampleTexture (byte *in, int inwidth, int inheight, unsigned *out,  int outwidth, int outheight);

#ifndef _H2INC
struct image_s *R_RegisterSkin (const char *name);

image_t *GL_LoadPic (const char *name, byte *pic, byte *palette, int width, int height, imagetype_t type, int has_miplevels, qboolean mipmap, int has_alpha );
void GL_SetBilinear(const char *name, qboolean bilinear, imagetype_t type);

image_t	*GL_FindImage (const char *name, imagetype_t type);
#endif

void	GL_InitImages (void);
void	GL_ShutdownImages (void);
void	GL_FreeUnusedImages (void);

void R_GetSurfaceColorAtST
(
	msurface_t *surf,
	float ss,
	float tt,
	vec3_t color
);
#ifndef _H2INC
int GL_TesselateModel (entity_t *ent, triangle_t *tris, int max_tris, int min_size, int max_size, int flags, const vec3_t origin);
#endif
void R_DrawTriangles (void);
#ifndef _H2INC
void  GL_LoadPalFile (const char *name);
#endif
void GL_LoadPortals (void);
void GL_DrawPortals (void);
void R_BurnPoint (vec3_t p, vec3_t dir, int value);
void GL_UpdateLightmap (msurface_t *surf);
extern int ztrickframe;
void SPR_RegisterSprite (model_t *mod);
void GL_LoadPalFile_f (void);

/*
** GL extension emulation functions
*/
void GL_DrawParticles (int num_particles, const particle_t particles[]);

/*
** GL config stuff
*/
#define GL_RENDERER_VOODOO		0x00000001
#define GL_RENDERER_VOODOO2   	0x00000002
#ifndef macintosh
#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
#else
#define GL_RENDERER_VOODOO3		0x00000004

#define GL_RENDERER_RAGE		0x00000010
#define GL_RENDERER_RAGE128		0x00000020
#define GL_RENDERER_ATI			0x000000F0
#endif
#define GL_RENDERER_OTHER		0x80000000

typedef struct
{
	int         renderer;
	const char *renderer_string;
	const char *vendor_string;
	const char *version_string;
	const char *extensions_string;

	qboolean	allow_cds;
	qboolean	have_stencil; /* Knightmare */
	qboolean	havedrawelements;
	qboolean	havedrawrangeelements;

	GLint		max_tmus; /* Knightmare */
} glconfig_t;

typedef struct
{
	float inverse_intensity;
	qboolean fullscreen;

	int prev_mode;

	unsigned char *d_16to8table;

	int lightmap_textures;

	int	currenttextures[2];
	int currenttmu;

	float camera_separation;
	qboolean stereo_enabled;

	qboolean	gammaRamp;	// Knightmare added

	unsigned int	glStateFlags;

	int			nTexnum[MAX_TMUS];
	GLenum		nTexEnv[MAX_TMUS];
	int			nTMU;
	qboolean	TMU_active[MAX_TMUS];
} glstate_t;

extern glconfig_t  gl_config;
extern glstate_t   gl_state;

#ifndef _H2INC
extern	refimport_t	ri;
#endif

void		GLimp_BeginFrame (float camera_separation);
void		GLimp_EndFrame (void);
qboolean	GLimp_Init (void *hinstance, void *hWnd);
void		GLimp_Shutdown (void);
rserr_t GLimp_SetMode (int *pwidth, int *pheight, int mode, qboolean fullscreen);
void		GLimp_AppActivate (qboolean active);
void		GLimp_EnableLogging (qboolean enable);
void		GLimp_LogNewFrame (void);

/* Prototypes */

/* In GL_Console3d.c */

extern conInfo_t consoleInfo;
extern void R_DrawConsole (msurface_t *p, int num_surfaces, vec3_t origin);

/* In GL_Draw.c */

extern image_t *Draw_Chars;
extern void GL_Draw_InitLocal (void);
extern void Draw_Fill3D (float x, float y, float width, float height, float r, float g, float b, float a);
extern void Draw_AltFill3D (float x, float y, float width, float height, float r, float g, float b, float a);
extern void Draw_Char3D (float x, float y, int c, int rows, int cols, float r, float g, float b, float a);
extern void Flush_Char3D (float r, float g, float b, float a); /* FS */
extern void Draw_TilePic3D (float x, float y, float width, float height, const char *picn, float r, float g, float b, float a);
extern void Draw_Pic3D (float x, float y, const char *picn, float scalex, float scaley, float r, float g, float b, float a);
extern void Draw_StretchPic3D (float x, float y, float width, float height, const char *picn, float r, float g, float b, float a);
extern void Draw_Char (int x, int y, int c);
extern image_t *Draw_FindPic (const char *name);
extern void Draw_GetPicSize (int *w, int *h, const char *name);
extern void	Draw_StretchPic (int x, int y, int w, int h, const char *name);
extern void	Draw_Pic (int x, int y, const char *name);
extern void	Draw_TileClear (int x, int y, int w, int h, const char *name);
extern void	Draw_Fill (int x, int y, int w, int h, float r, float g, float b);
extern void	Draw_FadeScreen (float r, float g, float b, float a);
extern void Draw_BeginCinematic (void);
extern void Draw_EndCinematic (void);
extern void Draw_CinematicFrame (int x, int y, int width, int height, int cols, int rows, int pitch, unsigned short *data);

/* In GL_Image.c */

extern image_t gltextures[MAX_GLTEXTURES];
extern int numgltextures;
extern byte d_8to24table[1024];
extern qboolean shared_palette_support;
extern qboolean r_multitexture_enabled;
extern int gl_tex_solid_format;
extern int gl_tex_alpha_format;
extern int gl_filter_min;
extern int gl_filter_max;
extern	qboolean	scrap_dirty;

extern void GL_SetTexturePalette (const byte *palette);
extern void GL_EnableTexture (unsigned tmu, qboolean enable); /* Knightmare */
extern void GL_EnableMultitexture (qboolean enable);
extern void GL_SelectTexture (GLenum);
extern void GL_TexEnv (GLenum value);
extern void GL_Bind (int texnum);
extern void GL_MBind (GLenum target, int texnum);
extern void GL_BindImage (image_t *image);
extern void GL_MBindImage (GLenum target, image_t *image);
extern void GL_TextureMode (const char *string);
extern void GL_SkinTextureMode (const char *string);
extern void GL_TextureAlphaMode (const char *string);
extern void GL_TextureSolidMode (const char *string);
extern void GL_ImageList_f (void);
extern void Scrap_Upload (void);

/* GL_Warp.c */

extern void GL_SubdivideSurface (msurface_t *fa);
extern void EmitWavyPolys (msurface_t *fa);
extern void EmitSolidPolys (msurface_t *fa);
void EmitWavySolidPolys (msurface_t *fa);
extern void EmitWaterPolys (msurface_t *fa);
extern void R_AddSkySurface (msurface_t *fa);
extern void R_ClearSkyBox (void);
extern void R_DrawSkyBox (void);
extern void R_SetSky (const char *name, float rotate, vec3_t axis);

/* */

qboolean SPR_LoadSpriteFile (model_t *mod, void *load_buffer);
void GL_BeginBuildingLightmaps (model_t *m);
void GL_CreateSurfaceLightmap (msurface_t *surf);
void GL_BuildPolygonFromSurface(msurface_t *fa);
void GL_EndBuildingLightmaps (void);

#ifdef __cplusplus
}
#endif

#endif
