2009-11-04 21:16:50 +00:00
# include "quakedef.h"
2010-02-06 01:25:04 +00:00
2012-01-01 02:26:42 +00:00
//#define FORCESTATE
2010-02-06 01:25:04 +00:00
2012-11-27 03:23:19 +00:00
void DumpGLState ( void ) ;
2009-11-04 21:16:50 +00:00
# ifdef GLQUAKE
2013-10-29 17:38:22 +00:00
# define r_refract_fboival (gl_config.ext_framebuffer_objects && r_refract_fbo.ival)
2012-07-05 19:42:36 +00:00
2009-11-04 21:16:50 +00:00
# include "glquake.h"
# include "shader.h"
2012-01-01 02:26:42 +00:00
# ifdef FORCESTATE
# pragma warningmsg("FORCESTATE is active")
# endif
2012-04-09 19:12:12 +00:00
# ifdef ANDROID
/*android appears to have a bug, and requires f and not i*/
# define qglTexEnvi qglTexEnvf
# endif
2011-04-30 17:21:10 +00:00
extern cvar_t gl_overbright ;
2017-02-11 16:14:06 +00:00
extern cvar_t r_tessellation ;
2012-08-04 01:35:52 +00:00
extern cvar_t r_wireframe ;
2013-10-29 17:38:22 +00:00
extern cvar_t r_refract_fbo ;
2011-04-30 17:21:10 +00:00
2015-03-03 00:14:43 +00:00
extern texid_t missing_texture ;
extern texid_t missing_texture_gloss ;
extern texid_t missing_texture_normal ;
extern texid_t scenepp_postproc_cube ;
extern texid_t r_whiteimage ;
2018-01-22 19:18:04 +00:00
# ifdef GLQUAKE
static texid_t shadowmap [ 2 ] ;
static int shadow_fbo_id ;
static int shadow_fbo_depth_num ;
# endif
2015-05-03 19:57:46 +00:00
# ifndef GLSLONLY
static void GenerateTCMods ( const shaderpass_t * pass , int passnum ) ;
# endif
2009-11-04 21:16:50 +00:00
static const char LIGHTPASS_SHADER [ ] = " \
{ \ n \
2011-12-26 15:19:13 +00:00
program rtlight % s \ n \
2009-11-04 21:16:50 +00:00
\
{ \ n \
map $ diffuse \ n \
2011-10-27 16:16:29 +00:00
blendfunc add \ n \
2009-11-04 21:16:50 +00:00
} \ n \
{ \ n \
map $ normalmap \ n \
} \ n \
{ \ n \
map $ specular \ n \
2011-10-27 16:16:29 +00:00
} \ n \
2012-08-04 01:35:52 +00:00
{ \ n \
map $ lightcubemap \ n \
} \ n \
2011-10-27 16:16:29 +00:00
{ \ n \
map $ shadowmap \ n \
2009-11-04 21:16:50 +00:00
} \ n \
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
{ \ n \
map $ loweroverlay \ n \
} \ n \
{ \ n \
map $ upperoverlay \ n \
} \ n \
2009-11-04 21:16:50 +00:00
} " ;
2014-02-14 09:59:32 +00:00
extern cvar_t r_glsl_offsetmapping , r_portalrecursion , r_portalonly ;
2009-11-04 21:16:50 +00:00
2011-02-25 04:22:14 +00:00
static void BE_SendPassBlendDepthMask ( unsigned int sbits ) ;
2011-01-04 02:56:16 +00:00
void GLBE_SubmitBatch ( batch_t * batch ) ;
2013-10-08 16:13:18 +00:00
# ifdef RTLIGHTS
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
static qboolean GLBE_RegisterLightShader ( int mode ) ;
2013-10-08 16:13:18 +00:00
# endif
2009-11-04 21:16:50 +00:00
struct {
//internal state
struct {
int lastpasstmus ;
2012-05-10 01:00:41 +00:00
// int vbo_colour;
// int vbo_texcoords[SHADER_PASS_MAX];
// int vbo_deforms; //holds verticies... in case you didn't realise.
2009-11-04 21:16:50 +00:00
2012-12-04 19:37:57 +00:00
const shader_t * shader_light [ 1u < < LSHADER_MODES ] ;
qboolean inited_shader_light [ 1u < < LSHADER_MODES ] ;
2011-12-05 15:23:40 +00:00
const shader_t * crepskyshader ;
const shader_t * crepopaqueshader ;
2013-10-08 14:28:11 +00:00
const shader_t * depthonlyshader ;
2017-03-06 14:06:12 +00:00
const shader_t * wireframeshader ;
2011-12-05 15:23:40 +00:00
2014-11-05 05:39:24 +00:00
union programhandle_u allblackshader ;
2013-10-08 14:28:11 +00:00
int allblack_mvp ;
2012-04-24 07:59:11 +00:00
2015-08-28 03:13:45 +00:00
program_t * programfixedemu [ 8 ] ;
2017-10-31 22:52:58 +00:00
texid_t tex_gbuf [ GBUFFER_COUNT ] ;
2013-10-29 17:38:22 +00:00
int fbo_current ; //the one currently being rendered to
2011-09-03 03:49:43 +00:00
texid_t tex_sourcecol ; /*this is used by $sourcecolour tgen*/
texid_t tex_sourcedepth ;
2016-07-12 00:40:13 +00:00
texid_t tex_reflectcube ; /*used where $reflectcube was invalid or failed*/
2014-02-07 08:38:40 +00:00
fbostate_t fbo_2dfbo ;
2016-12-07 18:45:25 +00:00
fbostate_t fbo_reflectrefrac [ R_MAX_RECURSE ] ;
2014-02-07 08:38:40 +00:00
fbostate_t fbo_lprepass ;
2016-12-07 18:45:25 +00:00
texid_t tex_reflection [ R_MAX_RECURSE ] ; /*basically a portal rendered to texture*/
texid_t tex_refraction [ R_MAX_RECURSE ] ; /*the (culled) underwater view*/
texid_t tex_refractiondepth [ R_MAX_RECURSE ] ; /*the (culled) underwater view*/
texid_t tex_ripplemap [ R_MAX_RECURSE ] ; /*temp image for waves and things.*/
2011-09-03 03:49:43 +00:00
2014-11-05 05:39:24 +00:00
int curpatchverts ;
2009-11-04 21:16:50 +00:00
qboolean force2d ;
int currenttmu ;
2012-11-27 03:23:19 +00:00
int blendmode [ SHADER_TMU_MAX ] ;
int texenvmode [ SHADER_TMU_MAX ] ;
int currenttextures [ SHADER_TMU_MAX ] ;
GLenum curtexturetype [ SHADER_TMU_MAX ] ;
2009-11-04 21:16:50 +00:00
polyoffset_t curpolyoffset ;
unsigned int curcull ;
texid_t curshadowmap ;
unsigned int shaderbits ;
2011-01-23 03:44:49 +00:00
unsigned int sha_attr ;
int currentprogram ;
2012-01-21 07:53:49 +00:00
int lastuniform ; /*program which was last set, so using the same prog for multiple surfaces on the same ent (ie: world) does not require lots of extra uniform chnges*/
2009-11-04 21:16:50 +00:00
2012-07-05 19:42:36 +00:00
batch_t dummybatch ;
2009-11-04 21:16:50 +00:00
vbo_t dummyvbo ;
int currentvbo ;
int currentebo ;
2012-04-24 07:59:11 +00:00
int currentvao ;
2009-11-04 21:16:50 +00:00
2010-07-11 02:22:39 +00:00
mesh_t * * meshes ;
unsigned int meshcount ;
2011-10-27 16:16:29 +00:00
float modelmatrix [ 16 ] ;
2012-01-17 07:57:46 +00:00
float modelmatrixinv [ 16 ] ;
2011-01-23 03:44:49 +00:00
float modelviewmatrix [ 16 ] ;
2017-12-15 06:56:40 +00:00
float projectionmatrix [ 16 ] ;
2010-07-11 02:22:39 +00:00
2015-08-28 03:13:45 +00:00
int colourarraytype ;
2012-04-24 07:59:11 +00:00
vec4_t pendingcolourflat ;
int pendingcolourvbo ;
void * pendingcolourpointer ;
int curcolourvbo ;
void * curcolourpointer ;
2009-11-04 21:16:50 +00:00
int pendingvertexvbo ;
void * pendingvertexpointer ;
int curvertexvbo ;
void * curvertexpointer ;
2013-04-06 08:38:40 +00:00
int streamvbo [ 64 ] ;
int streamebo [ 64 ] ;
2013-05-03 04:28:08 +00:00
int streamvao [ 64 ] ;
2013-04-06 08:38:40 +00:00
int streamid ;
2013-04-04 16:24:43 +00:00
2012-11-27 03:23:19 +00:00
int pendingtexcoordparts [ SHADER_TMU_MAX ] ;
int pendingtexcoordvbo [ SHADER_TMU_MAX ] ;
void * pendingtexcoordpointer [ SHADER_TMU_MAX ] ;
2013-08-27 13:18:09 +00:00
float identitylighting ; //set to how bright world lighting should be (reduced by realtime_world_lightmaps)
float identitylightmap ; //set to how bright lightmaps should be (reduced by overbrights+realtime_world_lightmaps)
2009-11-04 21:16:50 +00:00
2011-10-27 16:16:29 +00:00
texid_t temptexture ; //$current
2011-02-25 04:22:14 +00:00
texid_t fogtexture ;
2012-05-10 01:00:41 +00:00
texid_t normalisationcubemap ;
2011-02-25 04:22:14 +00:00
float fogfar ;
2012-11-29 13:37:48 +00:00
float depthrange ;
2012-05-14 01:41:08 +00:00
batch_t * * mbatches ; //model batches (ie: not world)
2009-11-04 21:16:50 +00:00
} ;
2011-01-23 03:44:49 +00:00
//exterior state (paramters)
2009-11-04 21:16:50 +00:00
struct {
backendmode_t mode ;
unsigned int flags ;
2012-05-11 01:57:00 +00:00
int oldwidth , oldheight ;
2009-11-04 21:16:50 +00:00
vbo_t * sourcevbo ;
2017-04-18 11:12:17 +00:00
const material_t * curshader ;
2009-11-04 21:16:50 +00:00
const entity_t * curentity ;
2012-07-05 19:42:36 +00:00
const batch_t * curbatch ;
2009-11-04 21:16:50 +00:00
const texnums_t * curtexnums ;
2012-10-08 04:36:10 +00:00
const mfog_t * fog ;
2013-10-08 14:28:11 +00:00
const dlight_t * curdlight ;
2009-11-04 21:16:50 +00:00
float curtime ;
2010-08-28 17:14:38 +00:00
float updatetime ;
2009-11-04 21:16:50 +00:00
2012-10-08 04:36:10 +00:00
int lightmode ;
2009-11-04 21:16:50 +00:00
vec3_t lightorg ;
2018-07-22 11:49:37 +00:00
vec3_t lightdir ;
2009-11-04 21:16:50 +00:00
vec3_t lightcolours ;
2012-01-01 11:22:24 +00:00
vec3_t lightcolourscale ;
2009-11-04 21:16:50 +00:00
float lightradius ;
texid_t lighttexture ;
2011-12-27 08:35:19 +00:00
texid_t lightcubemap ;
float lightprojmatrix [ 16 ] ; /*world space*/
2013-10-08 14:28:11 +00:00
vec2_t lightshadowmapscale ;
2013-03-12 23:13:39 +00:00
vec4_t lightshadowmapinfo ;
2013-10-08 14:28:11 +00:00
vec4_t lightshadowmapproj ;
2009-11-04 21:16:50 +00:00
} ;
2010-08-28 17:14:38 +00:00
int wbatch ;
int maxwbatches ;
batch_t * wbatches ;
2009-11-04 21:16:50 +00:00
} shaderstate ;
2017-10-13 17:50:28 +00:00
static void BE_PolyOffset ( void )
2011-10-27 16:16:29 +00:00
{
2012-08-04 01:35:52 +00:00
polyoffset_t po ;
po . factor = shaderstate . curshader - > polyoffset . factor ;
po . unit = shaderstate . curshader - > polyoffset . unit ;
2017-10-13 17:50:28 +00:00
# ifdef BEF_PUSHDEPTH
if ( shaderstate . flags & BEF_PUSHDEPTH )
2011-10-27 16:16:29 +00:00
{
/*some quake doors etc are flush with the walls that they're meant to be hidden behind, or plats the same height as the floor, etc
we move them back very slightly using polygonoffset to avoid really ugly z - fighting */
extern cvar_t r_polygonoffset_submodel_offset , r_polygonoffset_submodel_factor ;
2012-08-04 01:35:52 +00:00
po . factor + = r_polygonoffset_submodel_factor . value ;
po . unit + = r_polygonoffset_submodel_offset . value ;
2011-10-27 16:16:29 +00:00
}
2016-07-15 12:26:24 +00:00
# endif
2014-11-05 05:39:24 +00:00
if ( shaderstate . mode = = BEM_DEPTHONLY )
{
extern cvar_t r_polygonoffset_shadowmap_offset , r_polygonoffset_shadowmap_factor ;
po . factor + = r_polygonoffset_shadowmap_factor . value ;
po . unit + = r_polygonoffset_shadowmap_offset . value ;
}
2014-11-03 04:45:18 +00:00
# ifndef FORCESTATE
if ( shaderstate . curpolyoffset . factor ! = po . factor | | shaderstate . curpolyoffset . unit ! = po . unit )
# endif
2011-10-27 16:16:29 +00:00
{
2014-11-03 04:45:18 +00:00
shaderstate . curpolyoffset = po ;
if ( shaderstate . curpolyoffset . factor | | shaderstate . curpolyoffset . unit )
{
qglEnable ( GL_POLYGON_OFFSET_FILL ) ;
qglPolygonOffset ( shaderstate . curpolyoffset . factor , shaderstate . curpolyoffset . unit ) ;
}
else
qglDisable ( GL_POLYGON_OFFSET_FILL ) ;
}
}
2017-10-13 17:50:28 +00:00
void GLBE_PolyOffsetStencilShadow
# ifdef BEF_PUSHDEPTH
( qboolean pushdepth )
# else
( void )
# endif
2014-11-03 04:45:18 +00:00
{
extern cvar_t r_polygonoffset_stencil_offset , r_polygonoffset_stencil_factor ;
polyoffset_t po ;
2015-10-27 15:20:15 +00:00
po . factor = r_polygonoffset_stencil_factor . value ;
po . unit = r_polygonoffset_stencil_offset . value ;
2017-10-13 17:50:28 +00:00
# ifdef BEF_PUSHDEPTH
2014-11-03 04:45:18 +00:00
if ( pushdepth )
{
/*some quake doors etc are flush with the walls that they're meant to be hidden behind, or plats the same height as the floor, etc
we move them back very slightly using polygonoffset to avoid really ugly z - fighting */
extern cvar_t r_polygonoffset_submodel_offset , r_polygonoffset_submodel_factor ;
2015-10-27 15:20:15 +00:00
po . factor + = r_polygonoffset_submodel_factor . value ;
po . unit + = r_polygonoffset_submodel_offset . value ;
2014-11-03 04:45:18 +00:00
}
2016-07-15 12:26:24 +00:00
# endif
2014-11-03 04:45:18 +00:00
# ifndef FORCESTATE
if ( shaderstate . curpolyoffset . factor ! = po . factor | | shaderstate . curpolyoffset . unit ! = po . unit )
# endif
{
shaderstate . curpolyoffset = po ;
if ( shaderstate . curpolyoffset . factor | | shaderstate . curpolyoffset . unit )
{
qglEnable ( GL_POLYGON_OFFSET_FILL ) ;
qglPolygonOffset ( shaderstate . curpolyoffset . factor , shaderstate . curpolyoffset . unit ) ;
}
else
qglDisable ( GL_POLYGON_OFFSET_FILL ) ;
}
}
2017-10-31 22:52:58 +00:00
static void GLBE_PolyOffsetShadowMap ( void )
2014-11-03 04:45:18 +00:00
{
extern cvar_t r_polygonoffset_shadowmap_offset , r_polygonoffset_shadowmap_factor ;
polyoffset_t po ;
2017-10-31 22:52:58 +00:00
#if 0 //def BEF_PUSHDEPTH
2014-11-03 04:45:18 +00:00
if ( pushdepth )
{
/*some quake doors etc are flush with the walls that they're meant to be hidden behind, or plats the same height as the floor, etc
we move them back very slightly using polygonoffset to avoid really ugly z - fighting */
extern cvar_t r_polygonoffset_submodel_offset , r_polygonoffset_submodel_factor ;
po . factor = r_polygonoffset_submodel_factor . value + r_polygonoffset_shadowmap_factor . value ;
po . unit = r_polygonoffset_submodel_offset . value + r_polygonoffset_shadowmap_offset . value ;
}
else
2016-07-15 12:26:24 +00:00
# endif
2014-11-03 04:45:18 +00:00
{
po . factor = r_polygonoffset_shadowmap_factor . value ;
po . unit = r_polygonoffset_shadowmap_offset . value ;
2012-08-04 01:35:52 +00:00
}
2011-10-27 16:16:29 +00:00
# ifndef FORCESTATE
2013-03-12 22:47:42 +00:00
if ( shaderstate . curpolyoffset . factor ! = po . factor | | shaderstate . curpolyoffset . unit ! = po . unit )
2011-10-27 16:16:29 +00:00
# endif
2012-08-04 01:35:52 +00:00
{
shaderstate . curpolyoffset = po ;
if ( shaderstate . curpolyoffset . factor | | shaderstate . curpolyoffset . unit )
2011-10-27 16:16:29 +00:00
{
2012-08-04 01:35:52 +00:00
qglEnable ( GL_POLYGON_OFFSET_FILL ) ;
qglPolygonOffset ( shaderstate . curpolyoffset . factor , shaderstate . curpolyoffset . unit ) ;
2011-10-27 16:16:29 +00:00
}
2012-08-04 01:35:52 +00:00
else
qglDisable ( GL_POLYGON_OFFSET_FILL ) ;
2011-10-27 16:16:29 +00:00
}
}
2014-08-27 08:41:31 +00:00
# ifndef GLSLONLY
2009-11-04 21:16:50 +00:00
void GL_TexEnv ( GLenum mode )
{
2010-02-06 01:25:04 +00:00
# ifndef FORCESTATE
2009-11-04 21:16:50 +00:00
if ( mode ! = shaderstate . texenvmode [ shaderstate . currenttmu ] )
2010-02-06 01:25:04 +00:00
# endif
2009-11-04 21:16:50 +00:00
{
qglTexEnvi ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , mode ) ;
shaderstate . texenvmode [ shaderstate . currenttmu ] = mode ;
}
}
2011-04-30 17:21:10 +00:00
static void BE_SetPassBlendMode ( int tmu , int pbm )
{
2011-05-26 16:46:43 +00:00
# ifndef FORCESTATE
2011-04-30 17:21:10 +00:00
if ( shaderstate . blendmode [ tmu ] ! = pbm )
2011-05-26 16:46:43 +00:00
# endif
2011-04-30 17:21:10 +00:00
{
shaderstate . blendmode [ tmu ] = pbm ;
2011-05-26 16:46:43 +00:00
# ifndef FORCESTATE
2011-04-30 17:21:10 +00:00
if ( shaderstate . currenttmu ! = tmu )
2011-05-26 16:46:43 +00:00
# endif
2011-04-30 17:21:10 +00:00
GL_SelectTexture ( tmu ) ;
switch ( pbm )
{
case PBM_DOTPRODUCT :
GL_TexEnv ( GL_COMBINE_ARB ) ;
qglTexEnvi ( GL_TEXTURE_ENV , GL_SOURCE0_RGB_ARB , GL_TEXTURE ) ;
qglTexEnvi ( GL_TEXTURE_ENV , GL_SOURCE1_RGB_ARB , GL_PREVIOUS_ARB ) ;
qglTexEnvi ( GL_TEXTURE_ENV , GL_COMBINE_RGB_ARB , GL_DOT3_RGB_ARB ) ;
qglTexEnvf ( GL_TEXTURE_ENV , GL_RGB_SCALE_ARB , 1 ) ;
break ;
2012-05-10 01:00:41 +00:00
case PBM_MODULATE_PREV_COLOUR :
GL_TexEnv ( GL_COMBINE_ARB ) ;
qglTexEnvi ( GL_TEXTURE_ENV , GL_SOURCE0_RGB_ARB , GL_PRIMARY_COLOR_ARB ) ;
qglTexEnvi ( GL_TEXTURE_ENV , GL_SOURCE1_RGB_ARB , GL_PREVIOUS_ARB ) ;
qglTexEnvi ( GL_TEXTURE_ENV , GL_COMBINE_RGB_ARB , GL_MODULATE ) ;
qglTexEnvf ( GL_TEXTURE_ENV , GL_RGB_SCALE_ARB , 1 ) ;
break ;
2011-04-30 17:21:10 +00:00
case PBM_REPLACELIGHT :
2013-08-27 13:18:09 +00:00
// if (shaderstate.identitylighting != 1)
2011-04-30 17:21:10 +00:00
goto forcemod ;
GL_TexEnv ( GL_REPLACE ) ;
break ;
case PBM_REPLACE :
GL_TexEnv ( GL_REPLACE ) ;
break ;
case PBM_DECAL :
if ( tmu = = 0 )
goto forcemod ;
GL_TexEnv ( GL_DECAL ) ;
break ;
case PBM_ADD :
if ( tmu = = 0 )
goto forcemod ;
GL_TexEnv ( GL_ADD ) ;
break ;
case PBM_OVERBRIGHT :
GL_TexEnv ( GL_COMBINE_ARB ) ;
qglTexEnvi ( GL_TEXTURE_ENV , GL_SOURCE0_RGB_ARB , GL_TEXTURE ) ;
qglTexEnvi ( GL_TEXTURE_ENV , GL_SOURCE1_RGB_ARB , GL_PREVIOUS_ARB ) ;
qglTexEnvi ( GL_TEXTURE_ENV , GL_COMBINE_RGB_ARB , GL_MODULATE ) ;
qglTexEnvf ( GL_TEXTURE_ENV , GL_RGB_SCALE_ARB , 1 < < gl_overbright . ival ) ;
break ;
default :
case PBM_MODULATE :
forcemod :
GL_TexEnv ( GL_MODULATE ) ;
break ;
}
}
}
2014-08-27 08:41:31 +00:00
# endif
2011-04-30 17:21:10 +00:00
2010-03-14 14:35:56 +00:00
/*OpenGL requires glDepthMask(GL_TRUE) or glClear(GL_DEPTH_BUFFER_BIT) will fail*/
void GL_ForceDepthWritable ( void )
2009-11-04 21:16:50 +00:00
{
2011-05-26 16:46:43 +00:00
# ifndef FORCESTATE
2010-03-14 14:35:56 +00:00
if ( ! ( shaderstate . shaderbits & SBITS_MISC_DEPTHWRITE ) )
2011-05-26 16:46:43 +00:00
# endif
2009-11-04 21:16:50 +00:00
{
shaderstate . shaderbits | = SBITS_MISC_DEPTHWRITE ;
2010-03-14 14:35:56 +00:00
qglDepthMask ( GL_TRUE ) ;
2009-11-04 21:16:50 +00:00
}
}
2010-03-14 14:35:56 +00:00
void GL_SetShaderState2D ( qboolean is2d )
{
2010-08-28 17:14:38 +00:00
shaderstate . updatetime = realtime ;
2010-03-14 14:35:56 +00:00
shaderstate . force2d = is2d ;
2011-06-05 23:53:33 +00:00
if ( is2d )
memcpy ( shaderstate . modelviewmatrix , r_refdef . m_view , sizeof ( shaderstate . modelviewmatrix ) ) ;
2011-04-20 23:34:13 +00:00
BE_SelectMode ( BEM_STANDARD ) ;
2012-07-05 19:42:36 +00:00
2014-01-13 02:42:25 +00:00
// if (cl.paused || cls.state < ca_active)
2012-07-05 19:42:36 +00:00
shaderstate . updatetime = r_refdef . time ;
2014-01-13 02:42:25 +00:00
// else
// shaderstate.updatetime = cl.servertime;
2012-07-05 19:42:36 +00:00
BE_SelectEntity ( & r_worldentity ) ;
shaderstate . curtime = shaderstate . updatetime - shaderstate . curentity - > shaderTime ;
2010-03-14 14:35:56 +00:00
}
2011-05-29 04:26:29 +00:00
void GL_SelectTexture ( int target )
2009-11-04 21:16:50 +00:00
{
shaderstate . currenttmu = target ;
2011-02-25 04:22:14 +00:00
if ( qglActiveTextureARB )
2009-11-04 21:16:50 +00:00
qglActiveTextureARB ( target + mtexid0 ) ;
}
void GL_SelectVBO ( int vbo )
{
2010-02-06 01:25:04 +00:00
# ifndef FORCESTATE
2009-11-04 21:16:50 +00:00
if ( shaderstate . currentvbo ! = vbo )
2010-02-06 01:25:04 +00:00
# endif
2009-11-04 21:16:50 +00:00
{
shaderstate . currentvbo = vbo ;
qglBindBufferARB ( GL_ARRAY_BUFFER_ARB , shaderstate . currentvbo ) ;
}
}
2012-07-05 19:42:36 +00:00
void GL_DeselectVAO ( void )
2009-11-04 21:16:50 +00:00
{
2012-04-24 07:59:11 +00:00
if ( shaderstate . currentvao )
2009-11-04 21:16:50 +00:00
{
2012-04-24 07:59:11 +00:00
qglBindVertexArray ( 0 ) ;
shaderstate . currentvao = 0 ;
2009-11-04 21:16:50 +00:00
}
2012-07-05 19:42:36 +00:00
}
void GL_SelectEBO ( int vbo )
{
//EBO is part of the current VAO, so keep things matching that
2010-02-06 01:25:04 +00:00
# ifndef FORCESTATE
2012-04-24 07:59:11 +00:00
if ( shaderstate . currentebo ! = vbo )
2010-02-06 01:25:04 +00:00
# endif
2009-11-04 21:16:50 +00:00
{
2012-04-24 07:59:11 +00:00
shaderstate . currentebo = vbo ;
qglBindBufferARB ( GL_ELEMENT_ARRAY_BUFFER_ARB , shaderstate . currentebo ) ;
2009-11-04 21:16:50 +00:00
}
}
2011-02-25 04:22:14 +00:00
void GL_MTBind ( int tmu , int target , texid_t texnum )
2009-11-04 21:16:50 +00:00
{
2011-02-25 04:22:14 +00:00
GL_SelectTexture ( tmu ) ;
2009-11-04 21:16:50 +00:00
2010-02-06 01:25:04 +00:00
# ifndef FORCESTATE
2014-10-05 20:04:11 +00:00
if ( shaderstate . currenttextures [ tmu ] = = texnum - > num )
2009-11-04 21:16:50 +00:00
return ;
2010-02-06 01:25:04 +00:00
# endif
2009-11-04 21:16:50 +00:00
2014-10-05 20:04:11 +00:00
shaderstate . currenttextures [ tmu ] = texnum - > num ;
2011-02-25 04:22:14 +00:00
if ( target )
2014-10-05 20:04:11 +00:00
qglBindTexture ( target , texnum - > num ) ;
2011-02-25 04:22:14 +00:00
2013-04-04 08:08:49 +00:00
if (
2011-09-05 01:48:23 +00:00
# ifndef FORCESTATE
2013-04-04 08:08:49 +00:00
shaderstate . curtexturetype [ tmu ] ! = target & &
2011-09-05 01:48:23 +00:00
# endif
2014-08-25 07:35:41 +00:00
! gl_config_nofixedfunc )
2011-02-25 04:22:14 +00:00
{
2013-04-04 08:08:49 +00:00
2011-02-25 04:22:14 +00:00
if ( shaderstate . curtexturetype [ tmu ] )
qglDisable ( shaderstate . curtexturetype [ tmu ] ) ;
shaderstate . curtexturetype [ tmu ] = target ;
if ( target )
qglEnable ( target ) ;
}
2009-11-04 21:16:50 +00:00
}
2014-10-22 19:41:20 +00:00
#if 0 //def GLSLONLY
void GL_LazyBind ( int tmu , int target , texid_t texnum )
{
int glnum = texnum ? texnum - > num : 0 ;
if ( shaderstate . currenttextures [ tmu ] ! = glnum )
{
qglBindTextureUnit ( tmu , glnum ) ;
shaderstate . currenttextures [ tmu ] = glnum ;
}
}
# else
2012-04-24 07:59:11 +00:00
void GL_LazyBind ( int tmu , int target , texid_t texnum )
2009-11-04 21:16:50 +00:00
{
2014-10-05 20:04:11 +00:00
int glnum = texnum ? texnum - > num : 0 ;
2010-02-06 01:25:04 +00:00
# ifndef FORCESTATE
2014-10-05 20:04:11 +00:00
if ( shaderstate . currenttextures [ tmu ] ! = glnum )
2010-02-06 01:25:04 +00:00
# endif
2011-02-25 04:22:14 +00:00
{
GL_SelectTexture ( tmu ) ;
2009-11-04 21:16:50 +00:00
2014-10-05 20:04:11 +00:00
shaderstate . currenttextures [ shaderstate . currenttmu ] = glnum ;
2009-11-04 21:16:50 +00:00
2011-09-05 01:48:23 +00:00
# ifndef FORCESTATE
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
if ( shaderstate . curtexturetype [ tmu ] ! = target )
2011-09-05 01:48:23 +00:00
# endif
2011-02-25 04:22:14 +00:00
{
2014-08-25 07:35:41 +00:00
if ( gl_config_nofixedfunc )
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
{
shaderstate . curtexturetype [ tmu ] = target ;
}
else
{
if ( shaderstate . curtexturetype [ tmu ] )
2014-10-23 01:42:05 +00:00
{
qglBindTexture ( shaderstate . curtexturetype [ tmu ] , 0 ) ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
qglDisable ( shaderstate . curtexturetype [ tmu ] ) ;
2014-10-23 01:42:05 +00:00
}
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
shaderstate . curtexturetype [ tmu ] = target ;
if ( target )
qglEnable ( target ) ;
}
2011-02-25 04:22:14 +00:00
}
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
if ( target )
2014-10-05 20:04:11 +00:00
qglBindTexture ( target , glnum ) ;
2011-02-25 04:22:14 +00:00
}
2012-04-24 07:59:11 +00:00
}
2014-10-22 19:41:20 +00:00
# endif
2012-04-24 07:59:11 +00:00
static void BE_ApplyAttributes ( unsigned int bitstochange , unsigned int bitstoendisable )
{
unsigned int i ;
2015-08-28 03:13:45 +00:00
# ifndef GLSLONLY
2012-04-24 07:59:11 +00:00
//legacy colour attribute (including flat shaded)
if ( ( bitstochange ) & ( 1u < < VATTR_LEG_COLOUR ) )
{
if ( ! shaderstate . pendingcolourpointer & & ! shaderstate . pendingcolourvbo )
{
if ( shaderstate . curcolourpointer | | shaderstate . curcolourvbo )
{
qglShadeModel ( GL_FLAT ) ;
qglDisableClientState ( GL_COLOR_ARRAY ) ;
}
shaderstate . curcolourpointer = NULL ;
shaderstate . curcolourvbo = 0 ;
qglColor4fv ( shaderstate . pendingcolourflat ) ;
}
else
{
# ifndef FORCESTATE
if ( shaderstate . curcolourpointer ! = shaderstate . pendingcolourpointer | | shaderstate . pendingcolourvbo ! = shaderstate . curcolourvbo )
# endif
{
if ( ! shaderstate . curcolourpointer & & ! shaderstate . curcolourvbo )
{
2013-03-12 23:09:25 +00:00
if ( qglShadeModel )
qglShadeModel ( GL_SMOOTH ) ;
2012-04-24 07:59:11 +00:00
bitstoendisable | = ( 1u < < VATTR_LEG_COLOUR ) ;
}
shaderstate . curcolourpointer = shaderstate . pendingcolourpointer ;
shaderstate . curcolourvbo = shaderstate . pendingcolourvbo ;
GL_SelectVBO ( shaderstate . curcolourvbo ) ;
qglColorPointer ( 4 , shaderstate . colourarraytype , 0 , shaderstate . curcolourpointer ) ;
}
2009-11-04 21:16:50 +00:00
2012-04-24 07:59:11 +00:00
if ( ( bitstoendisable ) & ( 1u < < VATTR_LEG_COLOUR ) )
{
qglEnableClientState ( GL_COLOR_ARRAY ) ;
}
}
}
else
{
if ( ( bitstoendisable ) & ( 1u < < VATTR_LEG_COLOUR ) )
{
qglDisableClientState ( GL_COLOR_ARRAY ) ;
}
}
2009-11-04 21:16:50 +00:00
2012-04-24 07:59:11 +00:00
//legacy tmus
2012-11-27 03:23:19 +00:00
if ( ( bitstoendisable | bitstochange ) > = ( 1u < < VATTR_LEG_TMU0 ) )
2012-04-24 07:59:11 +00:00
{
2012-11-27 03:23:19 +00:00
for ( i = VATTR_LEG_TMU0 ; ( bitstoendisable | bitstochange ) > = ( 1u < < i ) ; i + + )
2012-04-24 07:59:11 +00:00
{
2012-11-27 03:23:19 +00:00
if ( ( bitstochange ) & ( 1u < < i ) )
{
qglClientActiveTextureARB ( i - VATTR_LEG_TMU0 + mtexid0 ) ;
if ( bitstoendisable & ( 1u < < i ) )
qglEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
GL_SelectVBO ( shaderstate . pendingtexcoordvbo [ i - VATTR_LEG_TMU0 ] ) ;
qglTexCoordPointer ( shaderstate . pendingtexcoordparts [ i - VATTR_LEG_TMU0 ] , GL_FLOAT , 0 , shaderstate . pendingtexcoordpointer [ i - VATTR_LEG_TMU0 ] ) ;
}
2011-09-05 01:48:23 +00:00
# ifndef FORCESTATE
2012-11-27 03:23:19 +00:00
else if ( bitstoendisable & ( 1u < < i ) )
2011-09-05 01:48:23 +00:00
# endif
2012-04-24 07:59:11 +00:00
{
qglClientActiveTextureARB ( i - VATTR_LEG_TMU0 + mtexid0 ) ;
if ( bitstochange & ( 1u < < i ) )
qglEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
else
qglDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
}
}
}
//legacy vertex coords
if ( ( bitstochange ) & ( 1u < < VATTR_LEG_VERTEX ) )
{
# ifndef FORCESTATE
if ( shaderstate . currentvao | | shaderstate . curvertexpointer ! = shaderstate . pendingvertexpointer | | shaderstate . pendingvertexvbo ! = shaderstate . curvertexvbo )
# endif
{
shaderstate . curvertexpointer = shaderstate . pendingvertexpointer ;
shaderstate . curvertexvbo = shaderstate . pendingvertexvbo ;
GL_SelectVBO ( shaderstate . curvertexvbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexPointer ( 3 , GL_FLOAT , VECV_STRIDE , shaderstate . curvertexpointer ) ;
2012-04-24 07:59:11 +00:00
}
if ( ( bitstoendisable ) & ( 1u < < VATTR_LEG_VERTEX ) )
{
qglEnableClientState ( GL_VERTEX_ARRAY ) ;
}
}
else
2011-02-25 04:22:14 +00:00
{
2012-04-24 07:59:11 +00:00
if ( ( bitstoendisable ) & ( 1u < < VATTR_LEG_VERTEX ) )
2011-02-25 04:22:14 +00:00
{
2012-04-24 07:59:11 +00:00
qglDisableClientState ( GL_VERTEX_ARRAY ) ;
}
}
2015-08-28 03:13:45 +00:00
# endif
2012-04-24 07:59:11 +00:00
2015-08-22 02:59:01 +00:00
if ( ! ( ( bitstochange | bitstoendisable ) & ( ( 1u < < VATTR_LEG_FIRST ) - 1 ) ) )
2012-04-24 07:59:11 +00:00
return ;
2013-04-06 04:52:59 +00:00
for ( i = 0 ; i < VATTR_LEG_FIRST ; i + + )
2012-04-24 07:59:11 +00:00
{
if ( ( bitstochange ) & ( 1u < < i ) )
{
switch ( i )
{
case VATTR_VERTEX1 :
/*we still do vertex transforms for billboards and shadows and such*/
GL_SelectVBO ( shaderstate . pendingvertexvbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( i , 3 , GL_FLOAT , GL_FALSE , VECV_STRIDE , shaderstate . pendingvertexpointer ) ;
2012-04-24 07:59:11 +00:00
break ;
case VATTR_VERTEX2 :
if ( ! shaderstate . sourcevbo - > coord2 . gl . vbo & & ! shaderstate . sourcevbo - > coord2 . gl . addr )
{
GL_SelectVBO ( shaderstate . pendingvertexvbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( i , 3 , GL_FLOAT , GL_FALSE , VECV_STRIDE , shaderstate . pendingvertexpointer ) ;
2012-04-24 07:59:11 +00:00
}
else
{
GL_SelectVBO ( shaderstate . sourcevbo - > coord2 . gl . vbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( VATTR_VERTEX2 , 3 , GL_FLOAT , GL_FALSE , VECV_STRIDE , shaderstate . sourcevbo - > coord2 . gl . addr ) ;
2012-04-24 07:59:11 +00:00
}
break ;
case VATTR_COLOUR :
2015-08-28 03:13:45 +00:00
if ( ! shaderstate . pendingcolourvbo & & ! shaderstate . pendingcolourpointer )
2012-04-24 07:59:11 +00:00
{
2015-06-26 13:21:04 +00:00
shaderstate . sha_attr & = ~ ( 1u < < i ) ;
qglDisableVertexAttribArray ( i ) ;
2018-11-27 16:48:19 +00:00
qglVertexAttrib4f ( VATTR_COLOUR , 1 , 1 , 1 , 1 ) ;
2015-06-26 13:21:04 +00:00
continue ;
2012-04-24 07:59:11 +00:00
}
2015-08-28 03:13:45 +00:00
GL_SelectVBO ( shaderstate . pendingcolourvbo ) ;
qglVertexAttribPointer ( VATTR_COLOUR , 4 , shaderstate . colourarraytype , ( ( shaderstate . colourarraytype = = GL_FLOAT ) ? GL_FALSE : GL_TRUE ) , 0 , shaderstate . pendingcolourpointer ) ;
2012-04-24 07:59:11 +00:00
break ;
2013-10-08 14:28:11 +00:00
# if MAXRLIGHTMAPS > 1
2013-08-27 13:18:09 +00:00
case VATTR_COLOUR2 :
GL_SelectVBO ( shaderstate . sourcevbo - > colours [ 1 ] . gl . vbo ) ;
qglVertexAttribPointer ( VATTR_COLOUR2 , 4 , shaderstate . colourarraytype , ( ( shaderstate . colourarraytype = = GL_FLOAT ) ? GL_FALSE : GL_TRUE ) , 0 , shaderstate . sourcevbo - > colours [ 1 ] . gl . addr ) ;
break ;
case VATTR_COLOUR3 :
GL_SelectVBO ( shaderstate . sourcevbo - > colours [ 2 ] . gl . vbo ) ;
qglVertexAttribPointer ( VATTR_COLOUR3 , 4 , shaderstate . colourarraytype , ( ( shaderstate . colourarraytype = = GL_FLOAT ) ? GL_FALSE : GL_TRUE ) , 0 , shaderstate . sourcevbo - > colours [ 2 ] . gl . addr ) ;
break ;
case VATTR_COLOUR4 :
GL_SelectVBO ( shaderstate . sourcevbo - > colours [ 3 ] . gl . vbo ) ;
qglVertexAttribPointer ( VATTR_COLOUR4 , 4 , shaderstate . colourarraytype , ( ( shaderstate . colourarraytype = = GL_FLOAT ) ? GL_FALSE : GL_TRUE ) , 0 , shaderstate . sourcevbo - > colours [ 3 ] . gl . addr ) ;
break ;
2013-10-08 14:28:11 +00:00
# endif
2012-04-24 07:59:11 +00:00
case VATTR_TEXCOORD :
2015-08-04 15:16:24 +00:00
if ( ! shaderstate . pendingtexcoordvbo [ 0 ] & & ! shaderstate . pendingtexcoordpointer [ 0 ] )
{
shaderstate . sha_attr & = ~ ( 1u < < i ) ;
qglDisableVertexAttribArray ( i ) ;
continue ;
}
2015-05-03 19:57:46 +00:00
GL_SelectVBO ( shaderstate . pendingtexcoordvbo [ 0 ] ) ;
qglVertexAttribPointer ( VATTR_TEXCOORD , shaderstate . pendingtexcoordparts [ 0 ] , GL_FLOAT , GL_FALSE , 0 , shaderstate . pendingtexcoordpointer [ 0 ] ) ;
2012-04-24 07:59:11 +00:00
break ;
case VATTR_LMCOORD :
2012-11-27 03:23:19 +00:00
if ( ! shaderstate . sourcevbo - > lmcoord [ 0 ] . gl . vbo & & ! shaderstate . sourcevbo - > lmcoord [ 0 ] . gl . addr )
{
GL_SelectVBO ( shaderstate . sourcevbo - > texcoord . gl . vbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( VATTR_LMCOORD , 2 , GL_FLOAT , GL_FALSE , 0 , shaderstate . sourcevbo - > texcoord . gl . addr ) ;
2012-11-27 03:23:19 +00:00
}
else
{
GL_SelectVBO ( shaderstate . sourcevbo - > lmcoord [ 0 ] . gl . vbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( VATTR_LMCOORD , 2 , GL_FLOAT , GL_FALSE , 0 , shaderstate . sourcevbo - > lmcoord [ 0 ] . gl . addr ) ;
2012-11-27 03:23:19 +00:00
}
2012-07-05 19:42:36 +00:00
break ;
2013-10-08 14:28:11 +00:00
# if MAXRLIGHTMAPS > 1
2012-07-05 19:42:36 +00:00
case VATTR_LMCOORD2 :
GL_SelectVBO ( shaderstate . sourcevbo - > lmcoord [ 1 ] . gl . vbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( VATTR_LMCOORD2 , 2 , GL_FLOAT , GL_FALSE , 0 , shaderstate . sourcevbo - > lmcoord [ 1 ] . gl . addr ) ;
2012-07-05 19:42:36 +00:00
break ;
case VATTR_LMCOORD3 :
GL_SelectVBO ( shaderstate . sourcevbo - > lmcoord [ 2 ] . gl . vbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( VATTR_LMCOORD3 , 2 , GL_FLOAT , GL_FALSE , 0 , shaderstate . sourcevbo - > lmcoord [ 2 ] . gl . addr ) ;
2012-07-05 19:42:36 +00:00
break ;
case VATTR_LMCOORD4 :
GL_SelectVBO ( shaderstate . sourcevbo - > lmcoord [ 3 ] . gl . vbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( VATTR_LMCOORD4 , 2 , GL_FLOAT , GL_FALSE , 0 , shaderstate . sourcevbo - > lmcoord [ 3 ] . gl . addr ) ;
2012-04-24 07:59:11 +00:00
break ;
2013-10-08 14:28:11 +00:00
# endif
2012-04-24 07:59:11 +00:00
case VATTR_NORMALS :
if ( ! shaderstate . sourcevbo - > normals . gl . addr )
2012-11-29 13:37:48 +00:00
{
shaderstate . sha_attr & = ~ ( 1u < < i ) ;
qglDisableVertexAttribArray ( i ) ;
continue ;
}
2012-04-24 07:59:11 +00:00
GL_SelectVBO ( shaderstate . sourcevbo - > normals . gl . vbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( VATTR_NORMALS , 3 , GL_FLOAT , GL_FALSE , 0 , shaderstate . sourcevbo - > normals . gl . addr ) ;
2012-04-24 07:59:11 +00:00
break ;
case VATTR_SNORMALS :
if ( ! shaderstate . sourcevbo - > svector . gl . addr )
2012-11-29 13:37:48 +00:00
{
shaderstate . sha_attr & = ~ ( 1u < < i ) ;
qglDisableVertexAttribArray ( i ) ;
continue ;
}
2012-04-24 07:59:11 +00:00
GL_SelectVBO ( shaderstate . sourcevbo - > svector . gl . vbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( VATTR_SNORMALS , 3 , GL_FLOAT , GL_FALSE , 0 , shaderstate . sourcevbo - > svector . gl . addr ) ;
2012-04-24 07:59:11 +00:00
break ;
case VATTR_TNORMALS :
if ( ! shaderstate . sourcevbo - > tvector . gl . addr )
2012-11-29 13:37:48 +00:00
{
shaderstate . sha_attr & = ~ ( 1u < < i ) ;
qglDisableVertexAttribArray ( i ) ;
continue ;
}
2012-04-24 07:59:11 +00:00
GL_SelectVBO ( shaderstate . sourcevbo - > tvector . gl . vbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( VATTR_TNORMALS , 3 , GL_FLOAT , GL_FALSE , 0 , shaderstate . sourcevbo - > tvector . gl . addr ) ;
2012-04-24 07:59:11 +00:00
break ;
case VATTR_BONENUMS :
2015-06-26 13:21:04 +00:00
if ( ! shaderstate . sourcevbo - > bonenums . gl . vbo & & ! shaderstate . sourcevbo - > bonenums . gl . addr )
2015-04-21 20:08:55 +00:00
{
shaderstate . sha_attr & = ~ ( 1u < < i ) ;
qglDisableVertexAttribArray ( i ) ;
continue ;
2015-06-26 13:21:04 +00:00
}
2012-04-24 07:59:11 +00:00
GL_SelectVBO ( shaderstate . sourcevbo - > bonenums . gl . vbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( VATTR_BONENUMS , 4 , GL_UNSIGNED_BYTE , GL_FALSE , 0 , shaderstate . sourcevbo - > bonenums . gl . addr ) ;
2012-04-24 07:59:11 +00:00
break ;
case VATTR_BONEWEIGHTS :
2015-06-26 13:21:04 +00:00
if ( ! shaderstate . sourcevbo - > boneweights . gl . vbo & & ! shaderstate . sourcevbo - > boneweights . gl . addr )
2015-04-21 20:08:55 +00:00
{
shaderstate . sha_attr & = ~ ( 1u < < i ) ;
qglDisableVertexAttribArray ( i ) ;
continue ;
2015-06-26 13:21:04 +00:00
}
2012-04-24 07:59:11 +00:00
GL_SelectVBO ( shaderstate . sourcevbo - > boneweights . gl . vbo ) ;
2013-04-04 08:08:49 +00:00
qglVertexAttribPointer ( VATTR_BONEWEIGHTS , 4 , GL_FLOAT , GL_FALSE , 0 , shaderstate . sourcevbo - > boneweights . gl . addr ) ;
2012-04-24 07:59:11 +00:00
break ;
}
if ( ( bitstoendisable ) & ( 1u < < i ) )
{
qglEnableVertexAttribArray ( i ) ;
}
2011-02-25 04:22:14 +00:00
}
else
{
2012-04-24 07:59:11 +00:00
if ( ( bitstoendisable ) & ( 1u < < i ) )
{
qglDisableVertexAttribArray ( i ) ;
}
2011-02-25 04:22:14 +00:00
}
}
2009-11-04 21:16:50 +00:00
}
2012-11-27 03:23:19 +00:00
static void BE_EnableShaderAttributes ( unsigned int progattrmask , int usevao )
2011-01-23 03:44:49 +00:00
{
2012-04-24 07:59:11 +00:00
unsigned int bitstochange , bitstoendisable ;
2012-11-27 03:23:19 +00:00
if ( shaderstate . currentvao ! = usevao )
{
shaderstate . currentvao = usevao ;
qglBindVertexArray ( usevao ) ;
}
2012-04-24 07:59:11 +00:00
if ( shaderstate . currentvao )
2011-05-26 16:46:43 +00:00
{
2012-04-24 07:59:11 +00:00
bitstochange = shaderstate . sourcevbo - > vaodynamic & progattrmask ;
2013-05-03 04:28:08 +00:00
#if 0
2012-04-24 07:59:11 +00:00
bitstoendisable = 0 ;
2013-05-03 04:28:08 +00:00
# else
bitstoendisable = shaderstate . sourcevbo - > vaoenabled ^ progattrmask ;
if ( bitstoendisable )
bitstochange | = bitstoendisable ;
shaderstate . sourcevbo - > vaoenabled = progattrmask ;
# endif
2012-04-24 07:59:11 +00:00
if ( bitstochange & ( 1u < < VATTR_LEG_ELEMENTS ) )
{
qglBindBufferARB ( GL_ELEMENT_ARRAY_BUFFER_ARB , shaderstate . sourcevbo - > indicies . gl . vbo ) ;
}
}
else
{
bitstochange = progattrmask ;
bitstoendisable = progattrmask ^ shaderstate . sha_attr ;
shaderstate . sha_attr = progattrmask ;
2014-06-04 16:08:30 +00:00
/*
2011-05-26 16:46:43 +00:00
# ifndef FORCESTATE
2012-04-24 07:59:11 +00:00
if ( shaderstate . currentebo ! = shaderstate . sourcevbo - > indicies . gl . vbo )
2011-05-26 16:46:43 +00:00
# endif
2011-01-23 03:44:49 +00:00
{
2012-04-24 07:59:11 +00:00
shaderstate . currentebo = shaderstate . sourcevbo - > indicies . gl . vbo ;
qglBindBufferARB ( GL_ELEMENT_ARRAY_BUFFER_ARB , shaderstate . currentebo ) ;
2011-01-23 03:44:49 +00:00
}
2014-06-04 16:08:30 +00:00
*/
2011-05-26 16:46:43 +00:00
}
2012-04-24 07:59:11 +00:00
if ( bitstochange | | bitstoendisable )
BE_ApplyAttributes ( bitstochange , bitstoendisable ) ;
}
2013-05-03 04:28:08 +00:00
void GLBE_SetupVAO ( vbo_t * vbo , unsigned int vaodynamic , unsigned int vaostatic )
2012-04-24 07:59:11 +00:00
{
if ( qglGenVertexArrays )
{
qglGenVertexArrays ( 1 , & vbo - > vao ) ;
2014-08-25 07:35:41 +00:00
if ( ( vaostatic & VATTR_VERTEX1 ) & & ! gl_config_nofixedfunc )
2013-05-03 04:28:08 +00:00
vaostatic = ( vaostatic & ~ VATTR_VERTEX1 ) | VATTR_LEG_VERTEX ;
2014-08-25 07:35:41 +00:00
if ( ( vaodynamic & VATTR_VERTEX1 ) & & ! gl_config_nofixedfunc )
2013-05-03 04:28:08 +00:00
vaodynamic = ( vaodynamic & ~ VATTR_VERTEX1 ) | VATTR_LEG_VERTEX ;
2012-04-24 07:59:11 +00:00
shaderstate . curvertexpointer = NULL ;
shaderstate . curvertexvbo = 0 ;
shaderstate . sourcevbo = vbo ;
shaderstate . pendingvertexvbo = shaderstate . sourcevbo - > coord . gl . vbo ;
shaderstate . pendingvertexpointer = shaderstate . sourcevbo - > coord . gl . addr ;
2015-08-28 03:13:45 +00:00
shaderstate . colourarraytype = shaderstate . sourcevbo - > colours_bytes ? GL_UNSIGNED_BYTE : GL_FLOAT ;
2015-08-04 15:16:24 +00:00
shaderstate . pendingtexcoordvbo [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
shaderstate . pendingtexcoordparts [ 0 ] = 2 ;
2012-04-24 07:59:11 +00:00
shaderstate . currentvao = vbo - > vao ;
qglBindVertexArray ( vbo - > vao ) ;
qglBindBufferARB ( GL_ELEMENT_ARRAY_BUFFER_ARB , shaderstate . sourcevbo - > indicies . gl . vbo ) ;
2013-05-03 04:28:08 +00:00
BE_ApplyAttributes ( vaostatic , vaodynamic | vaostatic ) ;
2012-04-24 07:59:11 +00:00
GL_SelectVBO ( shaderstate . sourcevbo - > coord . gl . vbo ) ;
2013-05-03 04:28:08 +00:00
vbo - > vaoenabled = vaodynamic | vaostatic ;
2012-04-24 07:59:11 +00:00
vbo - > vaodynamic = vaodynamic ;
shaderstate . curvertexpointer = NULL ;
shaderstate . curvertexvbo = 0 ;
}
else
{
2012-11-27 03:23:19 +00:00
GL_DeselectVAO ( ) ;
2012-04-24 07:59:11 +00:00
/*always select the coord vbo and indicies ebo, for easy bufferdata*/
2012-05-10 01:00:41 +00:00
GL_SelectEBO ( vbo - > indicies . gl . vbo ) ;
GL_SelectVBO ( vbo - > coord . gl . vbo ) ;
2012-04-24 07:59:11 +00:00
}
2011-01-23 03:44:49 +00:00
}
2012-04-24 07:59:11 +00:00
2011-01-23 03:44:49 +00:00
void GL_SelectProgram ( int program )
{
if ( shaderstate . currentprogram ! = program )
{
qglUseProgramObjectARB ( program ) ;
shaderstate . currentprogram = program ;
}
}
2012-07-07 05:17:43 +00:00
static void GL_DeSelectProgram ( void )
{
if ( shaderstate . currentprogram ! = 0 )
{
qglUseProgramObjectARB ( 0 ) ;
shaderstate . currentprogram = 0 ;
}
}
2011-01-23 03:44:49 +00:00
2012-01-01 02:26:42 +00:00
void GLBE_RenderShadowBuffer ( unsigned int numverts , int vbo , vecV_t * verts , unsigned numindicies , int ibo , index_t * indicies )
{
2012-04-24 07:59:11 +00:00
shaderstate . pendingvertexvbo = vbo ;
shaderstate . pendingvertexpointer = verts ;
shaderstate . sourcevbo = & shaderstate . dummyvbo ;
shaderstate . dummyvbo . indicies . gl . vbo = ibo ;
2015-10-27 15:20:15 +00:00
if ( shaderstate . mode ! = BEM_STENCIL )
2017-10-31 22:52:58 +00:00
GLBE_PolyOffsetShadowMap ( ) ;
2014-11-03 04:45:18 +00:00
2014-11-05 05:39:24 +00:00
if ( shaderstate . allblackshader . glsl . handle )
2012-04-24 07:59:11 +00:00
{
2014-11-05 05:39:24 +00:00
GL_SelectProgram ( shaderstate . allblackshader . glsl . handle ) ;
2012-07-05 19:42:36 +00:00
2014-08-25 07:35:41 +00:00
BE_EnableShaderAttributes ( gl_config_nofixedfunc ? ( 1u < < VATTR_VERTEX1 ) : ( 1u < < VATTR_LEG_VERTEX ) , 0 ) ;
2012-04-24 07:59:11 +00:00
2014-11-05 05:39:24 +00:00
if ( shaderstate . allblackshader . glsl . handle ! = shaderstate . lastuniform & & shaderstate . allblack_mvp ! = - 1 )
2012-04-24 07:59:11 +00:00
{
float m16 [ 16 ] ;
2017-12-15 06:56:40 +00:00
Matrix4_Multiply ( shaderstate . projectionmatrix , shaderstate . modelviewmatrix , m16 ) ;
2013-10-08 14:28:11 +00:00
qglUniformMatrix4fvARB ( shaderstate . allblack_mvp , 1 , false , m16 ) ;
2012-04-24 07:59:11 +00:00
}
2014-11-05 05:39:24 +00:00
shaderstate . lastuniform = shaderstate . allblackshader . glsl . handle ;
2012-04-24 07:59:11 +00:00
2014-10-22 19:41:20 +00:00
GL_SelectEBO ( ibo ) ;
2012-04-24 07:59:11 +00:00
qglDrawRangeElements ( GL_TRIANGLES , 0 , numverts , numindicies , GL_INDEX_TYPE , indicies ) ;
}
else
{
2012-07-07 05:17:43 +00:00
GL_DeSelectProgram ( ) ;
2012-11-27 03:23:19 +00:00
BE_EnableShaderAttributes ( ( 1u < < VATTR_LEG_VERTEX ) , 0 ) ;
2012-04-24 07:59:11 +00:00
//draw cached world shadow mesh
2014-10-22 19:41:20 +00:00
GL_SelectEBO ( ibo ) ;
2012-04-24 07:59:11 +00:00
qglDrawRangeElements ( GL_TRIANGLES , 0 , numverts , numindicies , GL_INDEX_TYPE , indicies ) ;
}
2015-03-03 00:14:43 +00:00
RQuantAdd ( RQUANT_DRAWS , 1 ) ;
RQuantAdd ( RQUANT_SHADOWINDICIES , numindicies ) ;
2012-04-24 07:59:11 +00:00
shaderstate . dummyvbo . indicies . gl . vbo = 0 ;
shaderstate . sourcevbo = NULL ;
2012-01-01 02:26:42 +00:00
}
2009-11-04 21:16:50 +00:00
void GL_CullFace ( unsigned int sflags )
{
Reworked client support for DPP5+. less code now, its much more graceful.
added waterfog command. waterfog overrides regular fog only when the view is in water.
fixed 64bit printf format specifiers. should work better on winxp64.
fixed some spec angle weirdness.
fixed viewsize 99.99 weirdness with ezhud.
fixed extra offset on the console (exhibited in 64bit builds, but not limited to).
fixed .avi playback, can now actually display frames again.
reimplemented line sparks.
fixed r_editlights_save flipping the light's pitch.
fixed issue with oggs failing to load.
fixed condump to cope with unicode properly.
made sv_bigcoords default except in quake. hexen2 kinda needs it for bsp angle precision.
fixed nq server to not stall weirdly on map changes.
fixed qwprogs svc_cdtrack not bugging out with nq clients on the server.
fixed restart command to load the last map run by the server, instead of start.bsp (when idle)
optimised d3d9 renderer a little. now uses less draw calls, especially with complex scenes. seems to get higher framerates than opengl now.
fixed d3d9 renderer to not bug out quite so much when run fullscreen (shader subsystem is now correctly initialised).
fixed a couple of bugs from font change. also now supports utf-8 in a few more places.
r_editlights_reload no longer generates rtlights inside the void. this resolves a few glitches (but should also help framerates a little).
fixed so corona-only lights won't generate shadowmaps and waste lots of time.
removed lots of #defines from qclib. I should never have made them in the first place, but I was lazy. obviously there's more left that I cba to remove yet.
fixed nested calls with variant-vectors. this fixes csaddon's light editor.
fixed qcc hc calling conventions using redundant stores.
disabled keywords can still be used by using __keyword instead.
fixed ftegccgui grep feature.
fixed motionless-dog qcc bug.
tweaked qcc warnings a little. -Wall is now a viable setting. you should be able to fix all those warnings.
fixed qw svc_intermission + dpp5+ clients bug.
fixed annoying spam about disconnecting in hexen2.
rewrote status command a little to cope with ipv6 addresses more gracefully
fixed significant stall when hibernating/debugging a server with a player sitting on it.
fixed truelightning.
fixed rocketlight overriding pflags.
fixed torches vanishing on vid_restart.
fixed issue with decal scaling.
fixed findentityfield builtin.
fixed fteqcc issue with ptr+1
fixed use of arrays inside class functions.
fixed/implemented fteqcc emulation of pointer opcodes.
added __inout keyword to fteqcc, so that it doesn't feel so horrendous.
fixed sizeof(*foo)
fixed *struct = struct;
fixed recursive structs.
fixed fteqcc warning report.
fixed sdl2 controller support, hopefully.
attempted to implement xinput, including per-player audio playback.
slightly fixed relaxed attitude to mouse focus when running fullscreen.
fixed weird warnings/errors with 'ent.arrayhead' terms. now generates sane errors.
implemented bindmaps (for csqc).
fixed crashing bug with eprint builtin.
implemented subset of music_playlist_* functionality. significant changes to music playback.
fixed some more dpcsqc compat.
fixed binds menu. now displays and accepts modifiers.
fixed issues with huge lightmaps.
fixed protocol determinism with dp clients connecting to fte servers. the initial getchallenge request now inhibits vanilla nq connection requests.
implemented support for 'dupe' userinfo key, allowing clients to request client->server packet duplication. should probably queue them tbh.
implemented sv_saveentfile command.
fixed resume after breaking inside a stepped-over function.
fixed erroneous footer after debugging.
(I wonder just how many things I broke with these fixes)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4946 fc73d0e0-1445-4013-8a0c-d673dee63da5
2015-07-26 10:56:18 +00:00
if ( shaderstate . flags & BEF_FORCETWOSIDED )
sflags = 0 ;
else if ( sflags )
sflags ^ = r_refdef . flipcull ;
2010-02-06 01:25:04 +00:00
# ifndef FORCESTATE
2009-11-04 21:16:50 +00:00
if ( shaderstate . curcull = = sflags )
return ;
2010-02-06 01:25:04 +00:00
# endif
2009-11-04 21:16:50 +00:00
shaderstate . curcull = sflags ;
if ( shaderstate . curcull & SHADER_CULL_FRONT )
{
qglEnable ( GL_CULL_FACE ) ;
2013-10-08 14:28:11 +00:00
qglCullFace ( GL_FRONT ) ;
2009-11-04 21:16:50 +00:00
}
else if ( shaderstate . curcull & SHADER_CULL_BACK )
{
qglEnable ( GL_CULL_FACE ) ;
2013-10-08 14:28:11 +00:00
qglCullFace ( GL_BACK ) ;
2009-11-04 21:16:50 +00:00
}
else
{
qglDisable ( GL_CULL_FACE ) ;
}
}
2015-03-03 00:14:43 +00:00
void R_FetchPlayerColour ( unsigned int cv , vec3_t rgb )
2009-11-04 21:16:50 +00:00
{
int i ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
if ( cv > = 16 )
2009-11-04 21:16:50 +00:00
{
2015-03-03 00:14:43 +00:00
rgb [ 0 ] = ( ( ( cv & 0xff0000 ) > > 16 ) * * ( ( unsigned char * ) & d_8to24rgbtable [ 15 ] + 0 ) ) / ( 256.0 * 256 ) ;
rgb [ 1 ] = ( ( ( cv & 0x00ff00 ) > > 8 ) * * ( ( unsigned char * ) & d_8to24rgbtable [ 15 ] + 1 ) ) / ( 256.0 * 256 ) ;
rgb [ 2 ] = ( ( ( cv & 0x0000ff ) > > 0 ) * * ( ( unsigned char * ) & d_8to24rgbtable [ 15 ] + 2 ) ) / ( 256.0 * 256 ) ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
return ;
2009-11-04 21:16:50 +00:00
}
2015-03-03 00:14:43 +00:00
i = cv ;
2014-10-22 19:41:20 +00:00
if ( i > = 8 )
2009-11-04 21:16:50 +00:00
{
i < < = 4 ;
}
else
{
i < < = 4 ;
i + = 15 ;
}
i * = 3 ;
2015-03-03 00:14:43 +00:00
rgb [ 0 ] = host_basepal [ i + 0 ] / 255.0 ;
rgb [ 1 ] = host_basepal [ i + 1 ] / 255.0 ;
rgb [ 2 ] = host_basepal [ i + 2 ] / 255.0 ;
2009-11-04 21:16:50 +00:00
/* if (!gammaworks)
{
* retred = gammatable [ * retred ] ;
* retgreen = gammatable [ * retgreen ] ;
* retblue = gammatable [ * retblue ] ;
} */
}
static void RevertToKnownState ( void )
{
2012-04-24 07:59:11 +00:00
if ( shaderstate . currentvao )
qglBindVertexArray ( 0 ) ;
shaderstate . currentvao = 0 ;
2009-11-04 21:16:50 +00:00
shaderstate . curvertexvbo = ~ 0 ;
GL_SelectVBO ( 0 ) ;
2012-11-27 03:23:19 +00:00
// GL_SelectEBO(0);
2009-11-04 21:16:50 +00:00
while ( shaderstate . lastpasstmus > 0 )
{
2012-04-24 07:59:11 +00:00
GL_LazyBind ( - - shaderstate . lastpasstmus , 0 , r_nulltex ) ;
2009-11-04 21:16:50 +00:00
}
GL_SelectTexture ( 0 ) ;
2014-08-27 08:41:31 +00:00
# ifndef GLSLONLY
2014-08-25 07:35:41 +00:00
if ( ! gl_config_nofixedfunc )
2012-04-24 07:59:11 +00:00
{
BE_SetPassBlendMode ( 0 , PBM_REPLACE ) ;
2015-09-14 10:36:42 +00:00
qglColor4f ( 1 , 1 , 1 , 1 ) ;
2010-03-14 14:35:56 +00:00
2012-04-24 07:59:11 +00:00
GL_DeSelectProgram ( ) ;
}
2014-08-27 08:41:31 +00:00
# endif
2012-04-24 07:59:11 +00:00
2018-04-27 16:40:50 +00:00
shaderstate . shaderbits & = ~ ( SBITS_DEPTHFUNC_BITS | SBITS_MASK_BITS | SBITS_AFFINE ) ;
2010-03-14 14:35:56 +00:00
shaderstate . shaderbits | = SBITS_MISC_DEPTHWRITE ;
2010-08-16 02:03:02 +00:00
shaderstate . shaderbits & = ~ ( SBITS_BLEND_BITS ) ;
qglDisable ( GL_BLEND ) ;
2009-11-04 21:16:50 +00:00
qglDepthFunc ( GL_LEQUAL ) ;
qglDepthMask ( GL_TRUE ) ;
qglColorMask ( GL_TRUE , GL_TRUE , GL_TRUE , GL_TRUE ) ;
}
void PPL_RevertToKnownState ( void )
{
RevertToKnownState ( ) ;
}
2009-11-07 13:29:15 +00:00
# ifdef RTLIGHTS
2018-01-22 19:18:04 +00:00
void GLBE_SetupForShadowMap ( dlight_t * dl , int texwidth , int texheight , float shadowscale )
2009-11-04 21:16:50 +00:00
{
2013-10-08 14:28:11 +00:00
extern cvar_t r_shadow_shadowmapping_bias ;
extern cvar_t r_shadow_shadowmapping_nearclip ;
2013-11-21 23:02:28 +00:00
float n = r_shadow_shadowmapping_nearclip . value ;
2018-01-22 19:18:04 +00:00
float f = dl - > radius ;
2013-11-21 23:02:28 +00:00
float b = r_shadow_shadowmapping_bias . value ;
2018-01-22 19:18:04 +00:00
2013-10-08 14:28:11 +00:00
shaderstate . lightshadowmapproj [ 0 ] = shadowscale * ( 1.0 - ( 1.0 / texwidth ) ) * 0.5 / 3.0 ;
shaderstate . lightshadowmapproj [ 1 ] = shadowscale * ( 1.0 - ( 1.0 / texheight ) ) * 0.5 / 2.0 ;
2013-11-21 23:02:28 +00:00
shaderstate . lightshadowmapproj [ 2 ] = 0.5 * ( f + n ) / ( n - f ) ;
shaderstate . lightshadowmapproj [ 3 ] = ( f * n ) / ( n - f ) - b * n * ( 1024 / texheight ) ;
2013-10-08 14:28:11 +00:00
2018-01-22 19:18:04 +00:00
shaderstate . lightshadowmapscale [ 0 ] = 1.0 / texwidth ;
shaderstate . lightshadowmapscale [ 1 ] = 1.0 / texheight ;
}
int GLBE_BeginRenderBuffer_DepthOnly ( texid_t depthtexture ) ;
qboolean GLBE_BeginShadowMap ( int id , int w , int h , int * restorefbo )
{
if ( ! gl_config . ext_framebuffer_objects )
return false ;
if ( ! TEXVALID ( shadowmap [ id ] ) )
{
2018-11-19 08:47:26 +00:00
uploadfmt_t encoding = PTI_DEPTH16 ;
2018-11-19 06:37:25 +00:00
texid_t tex = shadowmap [ id ] = Image_CreateTexture ( va ( " ***shadowmap2d%i*** " , id ) , NULL , 0 ) ;
qglGenTextures ( 1 , & tex - > num ) ;
GL_MTBind ( 0 , GL_TEXTURE_2D , tex ) ;
2018-01-22 19:18:04 +00:00
# ifdef SHADOWDBG_COLOURNOTDEPTH
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , w , h , 0 , GL_RGBA , GL_UNSIGNED_BYTE , NULL ) ;
# else
2018-11-19 06:37:25 +00:00
if ( qglTexStorage2D )
qglTexStorage2D ( GL_TEXTURE_2D , 1 , gl_config . formatinfo [ encoding ] . sizedformat , w , h ) ;
else if ( gl_config . formatinfo [ encoding ] . type )
qglTexImage2D ( GL_TEXTURE_2D , 0 , gl_config . formatinfo [ encoding ] . sizedformat , w , h , 0 , gl_config . formatinfo [ encoding ] . format , gl_config . formatinfo [ encoding ] . type , NULL ) ;
2018-01-22 19:18:04 +00:00
else
2018-11-19 06:37:25 +00:00
qglCompressedTexImage2D ( GL_TEXTURE_2D , 0 , gl_config . formatinfo [ encoding ] . sizedformat , w , h , 0 , 0 , NULL ) ;
2018-01-22 19:18:04 +00:00
# endif
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
#if 0 //def SHADOWDBG_COLOURNOTDEPTH
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_REPEAT ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_REPEAT ) ;
# else
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
# endif
//in case we're using shadow samplers
if ( gl_config . arb_shadow )
{
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_COMPARE_MODE_ARB , GL_COMPARE_R_TO_TEXTURE_ARB ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_COMPARE_FUNC_ARB , GL_LEQUAL ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_DEPTH_TEXTURE_MODE_ARB , GL_LUMINANCE ) ;
}
}
shaderstate . curshadowmap = shadowmap [ id ] ;
/*set framebuffer*/
* restorefbo = GLBE_BeginRenderBuffer_DepthOnly ( shaderstate . curshadowmap ) ;
shaderstate . depthrange = 0 ; //make sure the projection matrix is updated.
2013-03-12 23:13:39 +00:00
2009-11-04 21:16:50 +00:00
while ( shaderstate . lastpasstmus > 0 )
{
2012-04-24 07:59:11 +00:00
GL_LazyBind ( - - shaderstate . lastpasstmus , 0 , r_nulltex ) ;
2009-11-04 21:16:50 +00:00
}
2012-08-04 01:35:52 +00:00
shaderstate . shaderbits & = ~ SBITS_MISC_DEPTHWRITE ;
2011-04-20 23:34:13 +00:00
BE_SelectMode ( BEM_DEPTHONLY ) ;
2013-10-29 17:38:22 +00:00
2018-01-22 19:18:04 +00:00
BE_Scissor ( NULL ) ;
qglViewport ( 0 , 0 , w , h ) ;
GL_ForceDepthWritable ( ) ;
qglClear ( GL_DEPTH_BUFFER_BIT ) ;
# ifdef SHADOWDBG_COLOURNOTDEPTH
qglColorMask ( TRUE , TRUE , TRUE , TRUE ) ;
qglClearColor ( 1 , 1 , 1 , 1 ) ;
qglClear ( GL_COLOR_BUFFER_BIT ) ;
# endif
return true ;
}
void GLBE_EndShadowMap ( int restorefbo )
{
GLBE_FBO_Pop ( restorefbo ) ;
shaderstate . depthrange = 0 ; //make sure the projection matrix is updated.
2009-11-04 21:16:50 +00:00
}
2009-11-07 13:29:15 +00:00
# endif
2009-11-04 21:16:50 +00:00
2011-02-25 04:22:14 +00:00
static void T_Gen_CurrentRender ( int tmu )
2009-11-04 21:16:50 +00:00
{
int vwidth , vheight ;
2014-08-16 05:33:50 +00:00
int pwidth = vid . fbpwidth ;
int pheight = vid . fbpheight ;
2012-08-04 01:35:52 +00:00
if ( r_refdef . recurse )
return ;
2014-10-11 19:39:45 +00:00
if ( sh_config . texture_non_power_of_two_pic )
2009-11-04 21:16:50 +00:00
{
2014-08-16 05:33:50 +00:00
vwidth = pwidth ;
vheight = pheight ;
2009-11-04 21:16:50 +00:00
}
else
{
vwidth = 1 ;
vheight = 1 ;
2014-08-16 05:33:50 +00:00
while ( vwidth < pwidth )
2009-11-04 21:16:50 +00:00
{
vwidth * = 2 ;
}
2014-08-16 05:33:50 +00:00
while ( vheight < pheight )
2009-11-04 21:16:50 +00:00
{
vheight * = 2 ;
}
}
// copy the scene to texture
if ( ! TEXVALID ( shaderstate . temptexture ) )
2014-10-05 20:04:11 +00:00
{
TEXASSIGN ( shaderstate . temptexture , Image_CreateTexture ( " ***$currentrender*** " , NULL , 0 ) ) ;
qglGenTextures ( 1 , & shaderstate . temptexture - > num ) ;
}
2011-02-25 04:22:14 +00:00
GL_MTBind ( tmu , GL_TEXTURE_2D , shaderstate . temptexture ) ;
2018-03-04 14:41:16 +00:00
if ( vid . flags & VID_FP16 )
qglCopyTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA16F_ARB , 0 , 0 , vwidth , vheight , 0 ) ;
else if ( vid . flags & VID_SRGBAWARE )
qglCopyTexImage2D ( GL_TEXTURE_2D , 0 , GL_SRGB_ALPHA_EXT , 0 , 0 , vwidth , vheight , 0 ) ;
else
qglCopyTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGB , 0 , 0 , vwidth , vheight , 0 ) ;
2009-11-04 21:16:50 +00:00
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
2011-12-05 15:23:40 +00:00
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
2009-11-04 21:16:50 +00:00
}
2012-04-24 07:59:11 +00:00
static void Shader_BindTextureForPass ( int tmu , const shaderpass_t * pass )
2009-11-04 21:16:50 +00:00
{
2015-03-03 00:14:43 +00:00
extern cvar_t gl_specular_fallback ;
2012-07-05 19:42:36 +00:00
2011-02-25 04:22:14 +00:00
texid_t t ;
2009-11-04 21:16:50 +00:00
switch ( pass - > texgen )
{
default :
case T_GEN_SINGLEMAP :
2011-02-25 04:22:14 +00:00
t = pass - > anim_frames [ 0 ] ;
break ;
2009-11-04 21:16:50 +00:00
case T_GEN_ANIMMAP :
2011-02-25 04:22:14 +00:00
t = pass - > anim_frames [ ( int ) ( pass - > anim_fps * shaderstate . curtime ) % pass - > anim_numframes ] ;
break ;
2009-11-04 21:16:50 +00:00
case T_GEN_LIGHTMAP :
2014-03-30 08:55:06 +00:00
if ( ( unsigned short ) shaderstate . curbatch - > lightmap [ 0 ] > = numlightmaps )
2012-07-05 19:42:36 +00:00
t = r_whiteimage ;
else
t = lightmap [ shaderstate . curbatch - > lightmap [ 0 ] ] - > lightmap_texture ;
2011-02-25 04:22:14 +00:00
break ;
2009-11-04 21:16:50 +00:00
case T_GEN_DELUXMAP :
2012-09-30 05:52:03 +00:00
{
2014-03-30 08:55:06 +00:00
unsigned int lmi = shaderstate . curbatch - > lightmap [ 0 ] ;
if ( lmi > = numlightmaps | | ! lightmap [ lmi ] - > hasdeluxe )
2013-07-14 12:22:51 +00:00
t = missing_texture_normal ;
2012-09-30 05:52:03 +00:00
else
t = lightmap [ lmi + 1 ] - > lightmap_texture ;
}
2011-02-25 04:22:14 +00:00
break ;
2009-11-04 21:16:50 +00:00
case T_GEN_DIFFUSE :
2014-10-05 20:04:11 +00:00
if ( shaderstate . curtexnums & & TEXLOADED ( shaderstate . curtexnums - > base ) )
2012-02-12 05:18:31 +00:00
t = shaderstate . curtexnums - > base ;
else
t = missing_texture ;
2011-02-25 04:22:14 +00:00
break ;
2015-02-07 22:34:22 +00:00
case T_GEN_PALETTED :
if ( shaderstate . curtexnums & & TEXLOADED ( shaderstate . curtexnums - > paletted ) )
t = shaderstate . curtexnums - > paletted ;
else
2015-03-03 07:54:10 +00:00
t = r_whiteimage ;
2015-02-07 22:34:22 +00:00
break ;
2009-11-04 21:16:50 +00:00
case T_GEN_NORMALMAP :
2014-10-05 20:04:11 +00:00
t = ( shaderstate . curtexnums & & TEXLOADED ( shaderstate . curtexnums - > bump ) ) ? shaderstate . curtexnums - > bump : missing_texture_normal ;
2011-02-25 04:22:14 +00:00
break ;
2009-11-04 21:16:50 +00:00
case T_GEN_SPECULAR :
2014-10-05 20:04:11 +00:00
if ( shaderstate . curtexnums & & TEXLOADED ( shaderstate . curtexnums - > specular ) )
2012-11-27 03:23:19 +00:00
t = shaderstate . curtexnums - > specular ;
2015-03-03 00:14:43 +00:00
else if ( gl_specular_fallback . value < 0 & & shaderstate . curtexnums & & TEXLOADED ( shaderstate . curtexnums - > base ) )
t = shaderstate . curtexnums - > base ;
2012-11-27 03:23:19 +00:00
else
t = missing_texture_gloss ;
2011-02-25 04:22:14 +00:00
break ;
2009-11-04 21:16:50 +00:00
case T_GEN_UPPEROVERLAY :
2014-10-05 20:04:11 +00:00
if ( shaderstate . curtexnums & & TEXLOADED ( shaderstate . curtexnums - > upperoverlay ) )
2014-03-30 08:55:06 +00:00
t = shaderstate . curtexnums - > upperoverlay ;
else
t = r_nulltex ;
2011-02-25 04:22:14 +00:00
break ;
2009-11-04 21:16:50 +00:00
case T_GEN_LOWEROVERLAY :
2014-10-05 20:04:11 +00:00
if ( shaderstate . curtexnums & & TEXLOADED ( shaderstate . curtexnums - > loweroverlay ) )
2014-03-30 08:55:06 +00:00
t = shaderstate . curtexnums - > loweroverlay ;
else
t = r_nulltex ;
2011-02-25 04:22:14 +00:00
break ;
2009-11-04 21:16:50 +00:00
case T_GEN_FULLBRIGHT :
2011-02-25 04:22:14 +00:00
t = shaderstate . curtexnums - > fullbright ;
break ;
2015-05-03 19:57:46 +00:00
case T_GEN_REFLECTCUBE :
2018-07-24 13:59:42 +00:00
if ( shaderstate . curtexnums & & TEXLOADED ( shaderstate . curtexnums - > reflectcube ) )
t = shaderstate . curtexnums - > reflectcube ;
else if ( shaderstate . curbatch - > envmap )
t = shaderstate . curbatch - > envmap ;
else
t = shaderstate . tex_reflectcube ;
2016-07-12 00:40:13 +00:00
GL_LazyBind ( tmu , GL_TEXTURE_CUBE_MAP_ARB , t ) ;
2015-05-03 19:57:46 +00:00
return ;
case T_GEN_REFLECTMASK :
2017-08-29 02:29:06 +00:00
if ( shaderstate . curtexnums & & TEXLOADED ( shaderstate . curtexnums - > reflectmask ) )
t = shaderstate . curtexnums - > reflectmask ;
else if ( shaderstate . curtexnums & & TEXLOADED ( shaderstate . curtexnums - > base ) )
t = shaderstate . curtexnums - > base ;
else
t = r_whiteimage ;
2015-05-03 19:57:46 +00:00
break ;
2009-11-04 21:16:50 +00:00
case T_GEN_SHADOWMAP :
2011-02-25 04:22:14 +00:00
t = shaderstate . curshadowmap ;
break ;
2009-11-04 21:16:50 +00:00
2011-12-27 08:35:19 +00:00
case T_GEN_LIGHTCUBEMAP :
2012-04-24 07:59:11 +00:00
GL_LazyBind ( tmu , GL_TEXTURE_CUBE_MAP_ARB , shaderstate . lightcubemap ) ;
2011-12-27 08:35:19 +00:00
return ;
2011-12-23 03:12:29 +00:00
case T_GEN_CUBEMAP :
2011-10-27 16:16:29 +00:00
t = pass - > anim_frames [ 0 ] ;
2012-04-24 07:59:11 +00:00
GL_LazyBind ( tmu , GL_TEXTURE_CUBE_MAP_ARB , t ) ;
2011-10-27 16:16:29 +00:00
return ;
case T_GEN_SOURCECUBE :
t = scenepp_postproc_cube ;
2012-04-24 07:59:11 +00:00
GL_LazyBind ( tmu , GL_TEXTURE_CUBE_MAP_ARB , t ) ;
2011-10-27 16:16:29 +00:00
return ;
2011-12-23 03:12:29 +00:00
case T_GEN_3DMAP :
t = pass - > anim_frames [ 0 ] ;
2012-04-24 07:59:11 +00:00
GL_LazyBind ( tmu , GL_TEXTURE_3D , t ) ;
2011-12-23 03:12:29 +00:00
return ;
2009-11-04 21:16:50 +00:00
case T_GEN_VIDEOMAP :
2017-02-21 20:22:07 +00:00
# ifdef HAVE_MEDIA_DECODER
2011-02-25 04:22:14 +00:00
t = Media_UpdateForShader ( pass - > cin ) ;
2017-02-21 20:22:07 +00:00
# else
t = shaderstate . curtexnums ? shaderstate . curtexnums - > base : r_nulltex ;
2009-11-04 21:16:50 +00:00
# endif
2011-02-25 04:22:14 +00:00
break ;
2009-11-04 21:16:50 +00:00
case T_GEN_CURRENTRENDER :
2011-02-25 04:22:14 +00:00
T_Gen_CurrentRender ( tmu ) ;
return ;
2011-09-03 03:49:43 +00:00
case T_GEN_SOURCECOLOUR :
t = shaderstate . tex_sourcecol ;
break ;
case T_GEN_SOURCEDEPTH :
t = shaderstate . tex_sourcedepth ;
break ;
2012-05-09 15:30:53 +00:00
case T_GEN_REFLECTION :
2016-12-07 18:45:25 +00:00
t = shaderstate . tex_reflection [ r_refdef . recurse ] ;
2012-05-09 15:30:53 +00:00
break ;
case T_GEN_REFRACTION :
2012-07-05 19:42:36 +00:00
if ( ! r_refract_fboival )
{
T_Gen_CurrentRender ( tmu ) ;
return ;
}
2016-12-07 18:45:25 +00:00
t = shaderstate . tex_refraction [ r_refdef . recurse ] ;
2012-05-09 15:30:53 +00:00
break ;
2013-03-12 23:13:39 +00:00
case T_GEN_REFRACTIONDEPTH :
2016-12-07 18:45:25 +00:00
t = shaderstate . tex_refractiondepth [ r_refdef . recurse ] ;
2013-03-12 23:13:39 +00:00
break ;
2012-05-14 01:41:08 +00:00
case T_GEN_RIPPLEMAP :
2016-12-07 18:45:25 +00:00
t = shaderstate . tex_ripplemap [ r_refdef . recurse ] ;
2012-05-14 01:41:08 +00:00
break ;
2017-10-31 22:52:58 +00:00
case T_GEN_GBUFFERCASE :
t = shaderstate . tex_gbuf [ pass - > texgen - T_GEN_GBUFFER0 ] ;
break ;
2009-11-04 21:16:50 +00:00
}
2012-04-24 07:59:11 +00:00
GL_LazyBind ( tmu , GL_TEXTURE_2D , t ) ;
2009-11-04 21:16:50 +00:00
}
/*========================================== matrix functions =====================================*/
typedef vec3_t mat3_t [ 3 ] ;
static mat3_t axisDefault = { { 1 , 0 , 0 } ,
{ 0 , 1 , 0 } ,
{ 0 , 0 , 1 } } ;
static void Matrix3_Transpose ( mat3_t in , mat3_t out )
{
out [ 0 ] [ 0 ] = in [ 0 ] [ 0 ] ;
out [ 1 ] [ 1 ] = in [ 1 ] [ 1 ] ;
out [ 2 ] [ 2 ] = in [ 2 ] [ 2 ] ;
out [ 0 ] [ 1 ] = in [ 1 ] [ 0 ] ;
out [ 0 ] [ 2 ] = in [ 2 ] [ 0 ] ;
out [ 1 ] [ 0 ] = in [ 0 ] [ 1 ] ;
out [ 1 ] [ 2 ] = in [ 2 ] [ 1 ] ;
out [ 2 ] [ 0 ] = in [ 0 ] [ 2 ] ;
out [ 2 ] [ 1 ] = in [ 1 ] [ 2 ] ;
}
2015-09-01 04:45:15 +00:00
static void Matrix3_Multiply_Vec3 ( const mat3_t a , const vec3_t b , vec3_t product )
2009-11-04 21:16:50 +00:00
{
product [ 0 ] = a [ 0 ] [ 0 ] * b [ 0 ] + a [ 0 ] [ 1 ] * b [ 1 ] + a [ 0 ] [ 2 ] * b [ 2 ] ;
product [ 1 ] = a [ 1 ] [ 0 ] * b [ 0 ] + a [ 1 ] [ 1 ] * b [ 1 ] + a [ 1 ] [ 2 ] * b [ 2 ] ;
product [ 2 ] = a [ 2 ] [ 0 ] * b [ 0 ] + a [ 2 ] [ 1 ] * b [ 1 ] + a [ 2 ] [ 2 ] * b [ 2 ] ;
}
2015-09-01 04:45:15 +00:00
static int Matrix3_Compare ( const mat3_t in , const mat3_t out )
2009-11-04 21:16:50 +00:00
{
return memcmp ( in , out , sizeof ( mat3_t ) ) ;
}
//end matrix functions
/*========================================== tables for deforms =====================================*/
# define frand() (rand()*(1.0 / RAND_MAX))
# define FTABLE_SIZE 1024
# define FTABLE_CLAMP(x) (((int)((x)*FTABLE_SIZE) & (FTABLE_SIZE-1)))
# define FTABLE_EVALUATE(table,x) (table ? table[FTABLE_CLAMP(x)] : frand()*((x)-floor(x)))
static float r_sintable [ FTABLE_SIZE ] ;
static float r_triangletable [ FTABLE_SIZE ] ;
static float r_squaretable [ FTABLE_SIZE ] ;
static float r_sawtoothtable [ FTABLE_SIZE ] ;
static float r_inversesawtoothtable [ FTABLE_SIZE ] ;
2015-08-25 03:02:19 +00:00
//#define R_FastSin(x) sin((x)*(2*M_PI))
# define R_FastSin(x) r_sintable[FTABLE_CLAMP(x)]
2009-11-04 21:16:50 +00:00
static float * FTableForFunc ( unsigned int func )
{
switch ( func )
{
2018-03-04 14:41:16 +00:00
default :
2009-11-04 21:16:50 +00:00
case SHADER_FUNC_SIN :
return r_sintable ;
case SHADER_FUNC_TRIANGLE :
return r_triangletable ;
case SHADER_FUNC_SQUARE :
return r_squaretable ;
case SHADER_FUNC_SAWTOOTH :
return r_sawtoothtable ;
case SHADER_FUNC_INVERSESAWTOOTH :
return r_inversesawtoothtable ;
2018-03-04 14:41:16 +00:00
case SHADER_FUNC_NOISE :
return NULL ;
}
2009-11-04 21:16:50 +00:00
}
2014-08-15 02:20:41 +00:00
void Shader_LightPass ( const char * shortname , shader_t * s , const void * args )
2009-11-04 21:16:50 +00:00
{
char shadertext [ 8192 * 2 ] ;
2015-08-10 18:28:23 +00:00
extern cvar_t r_drawflat ;
2017-02-21 20:22:07 +00:00
sprintf ( shadertext , LIGHTPASS_SHADER , ( r_lightmap . ival | | r_drawflat . ival ) ? " #FLAT=1.0 " : " " ) ;
2011-12-27 08:35:19 +00:00
Shader_DefaultScript ( shortname , s , shadertext ) ;
}
2009-11-04 21:16:50 +00:00
2011-03-31 02:32:32 +00:00
void GenerateFogTexture ( texid_t * tex , float density , float zscale )
2011-02-25 04:22:14 +00:00
{
# define FOGS 256
# define FOGT 32
byte_vec4_t fogdata [ FOGS * FOGT ] ;
int s , t ;
2011-03-31 02:32:32 +00:00
float f , z ;
2012-10-08 04:36:10 +00:00
static float fogdensity , fogzscale ;
if ( TEXVALID ( * tex ) & & density = = fogdensity & & zscale = = fogzscale )
return ;
fogdensity = density ;
fogzscale = zscale ;
2011-02-25 04:22:14 +00:00
for ( s = 0 ; s < FOGS ; s + + )
for ( t = 0 ; t < FOGT ; t + + )
{
2011-03-31 02:32:32 +00:00
z = ( float ) s / ( FOGS - 1 ) ;
z * = zscale ;
if ( 0 ) //q3
2012-10-08 04:36:10 +00:00
f = pow ( z , 0.5 ) ;
2011-03-31 02:32:32 +00:00
else if ( 1 ) //GL_EXP
f = 1 - exp ( - density * z ) ;
else //GL_EXP2
f = 1 - exp ( - ( density * density ) * z ) ;
2011-02-25 04:22:14 +00:00
if ( f < 0 )
f = 0 ;
if ( f > 1 )
f = 1 ;
2013-11-21 23:02:28 +00:00
f * = ( float ) t / ( FOGT - 1 ) ;
2011-03-31 02:32:32 +00:00
2011-02-25 04:22:14 +00:00
fogdata [ t * FOGS + s ] [ 0 ] = 255 ;
fogdata [ t * FOGS + s ] [ 1 ] = 255 ;
fogdata [ t * FOGS + s ] [ 2 ] = 255 ;
fogdata [ t * FOGS + s ] [ 3 ] = 255 * f ;
}
2011-03-31 02:32:32 +00:00
if ( ! TEXVALID ( * tex ) )
2014-10-05 20:04:11 +00:00
* tex = Image_CreateTexture ( " ***fog*** " , NULL , IF_CLAMP | IF_NOMIPMAP ) ;
Image_Upload ( * tex , TF_RGBA32 , fogdata , NULL , FOGS , FOGT , IF_CLAMP | IF_NOMIPMAP ) ;
2011-02-25 04:22:14 +00:00
}
2014-05-30 03:57:30 +00:00
void GLBE_DestroyFBOs ( void )
{
2016-12-07 18:45:25 +00:00
size_t i ;
2014-05-30 03:57:30 +00:00
GLBE_FBO_Destroy ( & shaderstate . fbo_lprepass ) ;
2016-12-07 18:45:25 +00:00
for ( i = 0 ; i < R_MAX_RECURSE ; i + + )
2014-05-30 03:57:30 +00:00
{
2016-12-07 18:45:25 +00:00
GLBE_FBO_Destroy ( & shaderstate . fbo_reflectrefrac [ i ] ) ;
if ( shaderstate . tex_reflection [ i ] )
{
Image_DestroyTexture ( shaderstate . tex_reflection [ i ] ) ;
shaderstate . tex_reflection [ i ] = r_nulltex ;
}
if ( shaderstate . tex_refraction [ i ] )
{
Image_DestroyTexture ( shaderstate . tex_refraction [ i ] ) ;
shaderstate . tex_refraction [ i ] = r_nulltex ;
}
if ( shaderstate . tex_refractiondepth [ i ] )
{
Image_DestroyTexture ( shaderstate . tex_refractiondepth [ i ] ) ;
shaderstate . tex_refractiondepth [ i ] = r_nulltex ;
}
2014-05-30 03:57:30 +00:00
}
2014-10-05 20:04:11 +00:00
if ( shaderstate . temptexture )
2014-05-30 03:57:30 +00:00
{
2015-03-03 00:14:43 +00:00
Image_DestroyTexture ( shaderstate . temptexture ) ;
2014-05-30 03:57:30 +00:00
shaderstate . temptexture = r_nulltex ;
}
2016-11-20 20:52:41 +00:00
2018-01-22 19:18:04 +00:00
//shadowmapping stuff
if ( shadow_fbo_id )
{
qglDeleteFramebuffersEXT ( 1 , & shadow_fbo_id ) ;
shadow_fbo_id = 0 ;
shadow_fbo_depth_num = 0 ;
}
for ( i = 0 ; i < 2 ; i + + )
{
if ( shadowmap [ i ] )
{
Image_DestroyTexture ( shadowmap [ i ] ) ;
shadowmap [ i ] = r_nulltex ;
}
}
2016-11-20 20:52:41 +00:00
//nuke deferred rendering stuff
2017-10-13 17:50:28 +00:00
for ( i = 0 ; i < countof ( shaderstate . tex_gbuf ) ; i + + )
2016-11-20 20:52:41 +00:00
{
2017-10-13 17:50:28 +00:00
if ( shaderstate . tex_gbuf [ i ] )
{
Image_DestroyTexture ( shaderstate . tex_gbuf [ i ] ) ;
shaderstate . tex_gbuf [ i ] = r_nulltex ;
}
2016-11-20 20:52:41 +00:00
}
2014-05-30 03:57:30 +00:00
}
2012-07-05 19:42:36 +00:00
void GLBE_Shutdown ( void )
{
2018-03-04 14:41:16 +00:00
size_t u ;
dpp7: Treat 'dropped' c2s packets as choked when using dpp7 protocols. This is because the protocol provides no way to disambiguate, and I don't like false reports of packetloss (only reliables loss can be detected, and that's not frequent enough to be meaningful). Pings can still be determined with dpp7, for those few packets which are acked.
package manager: reworked to enable/disable plugins when downloaded, which can also be present-but-disabled.
package manager: display a confirmation prompt before applying changes. do not allow other changes to be made while applying. prompt may be skipped with 'pkg apply' in dedicated servers.
sv: downloads are no longer forced to lower case.
sv: added sv_demoAutoCompress cvar. set to 1 to directly record to *.mvd.gz
cl: properly support directly playing .mvd.gz files
menus: reworked to separate mouse and keyboard focus. mouse focus becomes keyboard focus only on mouse clicks. tooltips follow mouse cursors.
menus: cleaned up menu heirachy a little. now simpler.
server browser: changed 'hide *' filters to 'show *' instead. I felt it was more logical.
deluxmapping: changed to disabled, load, generate, like r_loadlit is.
render targets api now supports negative formats to mean nearest filtering, where filtering is part of texture state.
drawrotpic fixed, now batches and interacts with drawpic correctly.
drawline fixed, no interacts with draw* correctly, but still does not batch.
fixed saving games.
provide proper userinfo to nq clients, where supported.
qcc: catch string table overflows safely, giving errors instead of crashes. switch to 32bit statements if some over-sized function requires it.
qtv: some bigcoords support tweaks
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5073 fc73d0e0-1445-4013-8a0c-d673dee63da5
2017-03-21 05:27:07 +00:00
GLBE_FBO_Destroy ( & shaderstate . fbo_2dfbo ) ;
2014-05-30 03:57:30 +00:00
GLBE_DestroyFBOs ( ) ;
2018-03-04 14:41:16 +00:00
for ( u = 0 ; u < countof ( shaderstate . programfixedemu ) ; u + + )
{
Shader_ReleaseGeneric ( shaderstate . programfixedemu [ u ] ) ;
shaderstate . programfixedemu [ u ] = NULL ;
}
2012-07-05 19:42:36 +00:00
BZ_Free ( shaderstate . wbatches ) ;
shaderstate . wbatches = NULL ;
shaderstate . maxwbatches = 0 ;
2018-04-15 02:48:23 +00:00
//on vid_reload, the gl drivers might have various things bound that have since been destroyed/etc
//so reset that state to avoid any issues with state
2018-04-27 16:40:50 +00:00
BE_EnableShaderAttributes ( 0 , 0 ) ;
2018-04-15 02:48:23 +00:00
GL_SelectVBO ( 0 ) ;
GL_SelectEBO ( 0 ) ;
2018-04-27 16:40:50 +00:00
for ( u = 0 ; u < countof ( shaderstate . currenttextures ) ; u + + )
GL_LazyBind ( u , 0 , r_nulltex ) ;
GL_SelectTexture ( 0 ) ;
2012-07-05 19:42:36 +00:00
}
2011-01-04 02:56:16 +00:00
void GLBE_Init ( void )
2009-11-04 21:16:50 +00:00
{
int i ;
double t ;
2012-07-05 19:42:36 +00:00
GLBE_Shutdown ( ) ;
2012-04-24 07:59:11 +00:00
memset ( & shaderstate , 0 , sizeof ( shaderstate ) ) ;
2011-02-25 04:22:14 +00:00
shaderstate . curentity = & r_worldentity ;
2015-08-28 03:13:45 +00:00
be_maxpasses = gl_config_nofixedfunc ? 1 : gl_mtexarbable ;
2018-04-15 02:48:23 +00:00
be_maxpasses = min ( SHADER_TMU_MAX , min ( be_maxpasses , 32 - VATTR_LEG_TMU0 ) ) ;
2012-04-24 07:59:11 +00:00
gl_stencilbits = 0 ;
2017-07-31 17:15:37 +00:00
# ifndef GLESONLY
if ( ! gl_config_gles & & gl_config . glversion > = 3.0 & & gl_config_nofixedfunc )
2013-05-03 04:28:08 +00:00
{
//docs say this line should be okay in gl3+. nvidia do not seem to agree. GL_STENCIL_BITS is depricated however. so for now, just assume.
2017-07-28 01:49:25 +00:00
qglGetFramebufferAttachmentParameteriv ( GL_FRAMEBUFFER_EXT , GL_STENCIL , GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE , & gl_stencilbits ) ;
if ( qglGetError ( ) )
gl_stencilbits = 8 ;
2013-05-03 04:28:08 +00:00
}
else
2017-07-31 17:15:37 +00:00
# endif
2013-05-03 04:28:08 +00:00
qglGetIntegerv ( GL_STENCIL_BITS , & gl_stencilbits ) ;
2009-11-04 21:16:50 +00:00
for ( i = 0 ; i < FTABLE_SIZE ; i + + )
{
t = ( double ) i / ( double ) FTABLE_SIZE ;
r_sintable [ i ] = sin ( t * 2 * M_PI ) ;
2011-05-29 04:26:29 +00:00
if ( t < 0.25 )
2009-11-04 21:16:50 +00:00
r_triangletable [ i ] = t * 4.0 ;
else if ( t < 0.75 )
r_triangletable [ i ] = 2 - 4.0 * t ;
else
r_triangletable [ i ] = ( t - 0.75 ) * 4.0 - 1.0 ;
2011-05-29 04:26:29 +00:00
if ( t < 0.5 )
2009-11-04 21:16:50 +00:00
r_squaretable [ i ] = 1.0f ;
else
r_squaretable [ i ] = - 1.0f ;
r_sawtoothtable [ i ] = t ;
r_inversesawtoothtable [ i ] = 1.0 - t ;
}
shaderstate . identitylighting = 1 ;
2013-08-27 13:18:09 +00:00
shaderstate . identitylightmap = 1 ;
2013-10-08 14:28:11 +00:00
for ( i = 0 ; i < MAXRLIGHTMAPS ; i + + )
2012-07-05 19:42:36 +00:00
shaderstate . dummybatch . lightmap [ i ] = - 1 ;
2009-11-04 21:16:50 +00:00
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
# ifdef RTLIGHTS
2013-11-21 23:02:28 +00:00
Sh_CheckSettings ( ) ;
2018-01-22 19:18:04 +00:00
if ( ( r_shadow_realtime_dlight . ival & & r_shadow_shadowmapping . ival ) | |
( r_shadow_realtime_world . ival & & r_shadow_shadowmapping . ival ) )
{ //we expect some lights that will need shadowmapped shadows.
GLBE_RegisterLightShader ( LSHADER_SMAP ) ;
GLBE_RegisterLightShader ( LSHADER_SMAP | LSHADER_CUBE ) ;
GLBE_RegisterLightShader ( LSHADER_SMAP | LSHADER_SPOT ) ;
}
if ( ( r_shadow_realtime_dlight . ival & & ( ! r_shadow_shadowmapping . ival | | ! r_shadow_realtime_dlight_shadows . ival ) ) | |
( r_shadow_realtime_world . ival & & ( ! r_shadow_shadowmapping . ival | | ! r_shadow_realtime_world_shadows . ival ) ) )
{ //these are also used when there's no shadow.
//FIXME: should also happen if there's static world lights without shadows. Move elsewhere?
GLBE_RegisterLightShader ( LSHADER_STANDARD ) ;
GLBE_RegisterLightShader ( LSHADER_STANDARD | LSHADER_CUBE ) ;
GLBE_RegisterLightShader ( LSHADER_STANDARD | LSHADER_SPOT ) ;
2009-11-04 21:16:50 +00:00
}
2012-10-08 04:36:10 +00:00
# endif
2009-11-04 21:16:50 +00:00
2012-01-16 06:22:06 +00:00
gl_overbright . modified = true ; /*in case the d3d renderer does the same*/
/*lock the cvar down if the backend can't actually do it*/
2018-11-19 06:37:25 +00:00
if (
# if 1 //defined(QUAKETC)
//TCs are expected to be using glsl and weird overbright things etc, don't take the risk.
( ! sh_config . progs_supported )
# else
//Q3 can get away with tex_env_combine for everything, if only because the content allows everything to be flattened to a single pass if needed...
//some shaders might screw up from our approach though...
( ! gl_config . tex_env_combine & & ! gl_config_nofixedfunc )
# endif
& & gl_overbright . ival )
2012-01-16 06:22:06 +00:00
Cvar_ApplyLatchFlag ( & gl_overbright , " 0 " , CVAR_RENDERERLATCH ) ;
2012-04-24 07:59:11 +00:00
shaderstate . shaderbits = ~ SBITS_ATEST_BITS ;
2011-02-25 04:22:14 +00:00
BE_SendPassBlendDepthMask ( 0 ) ;
2010-07-11 02:22:39 +00:00
currententity = & r_worldentity ;
2011-02-25 04:22:14 +00:00
2011-03-31 02:32:32 +00:00
shaderstate . fogtexture = r_nulltex ;
2011-09-03 03:49:43 +00:00
2013-10-08 14:28:11 +00:00
shaderstate . depthonlyshader = R_RegisterShader ( " depthonly " , SUF_NONE ,
" { \n "
" program depthonly \n "
" { \n "
" depthwrite \n "
2013-10-09 00:16:08 +00:00
" maskcolor \n "
2013-10-08 14:28:11 +00:00
" } \n "
" } \n "
) ;
2013-10-21 04:27:36 +00:00
//if the shader doesn't work, give up with that.
if ( ! shaderstate . depthonlyshader | | ! shaderstate . depthonlyshader - > prog )
shaderstate . depthonlyshader = NULL ;
2011-09-03 03:49:43 +00:00
//make sure the world draws correctly
r_worldentity . shaderRGBAf [ 0 ] = 1 ;
r_worldentity . shaderRGBAf [ 1 ] = 1 ;
r_worldentity . shaderRGBAf [ 2 ] = 1 ;
r_worldentity . shaderRGBAf [ 3 ] = 1 ;
r_worldentity . axis [ 0 ] [ 0 ] = 1 ;
r_worldentity . axis [ 1 ] [ 1 ] = 1 ;
r_worldentity . axis [ 2 ] [ 2 ] = 1 ;
2013-03-12 23:24:15 +00:00
r_worldentity . light_avg [ 0 ] = 1 ;
r_worldentity . light_avg [ 1 ] = 1 ;
r_worldentity . light_avg [ 2 ] = 1 ;
2011-10-27 16:16:29 +00:00
R_InitFlashblends ( ) ;
2013-04-04 16:24:43 +00:00
2015-08-04 15:16:24 +00:00
memset ( & shaderstate . streamvbo , 0 , sizeof ( shaderstate . streamvbo ) ) ;
memset ( & shaderstate . streamebo , 0 , sizeof ( shaderstate . streamebo ) ) ;
memset ( & shaderstate . streamvao , 0 , sizeof ( shaderstate . streamvao ) ) ;
2013-04-04 16:24:43 +00:00
//only do this where we have to.
2018-03-04 14:41:16 +00:00
if ( qglBufferDataARB & & gl_config_nofixedfunc
# ifndef FTE_TARGET_WEB
& & ! gl_config_gles
# endif
)
2013-04-04 16:24:43 +00:00
{
2013-04-06 08:38:40 +00:00
qglGenBuffersARB ( sizeof ( shaderstate . streamvbo ) / sizeof ( shaderstate . streamvbo [ 0 ] ) , shaderstate . streamvbo ) ;
qglGenBuffersARB ( sizeof ( shaderstate . streamebo ) / sizeof ( shaderstate . streamebo [ 0 ] ) , shaderstate . streamebo ) ;
2013-05-03 04:28:08 +00:00
if ( qglGenVertexArrays )
qglGenVertexArrays ( sizeof ( shaderstate . streamvao ) / sizeof ( shaderstate . streamvao [ 0 ] ) , shaderstate . streamvao ) ;
2013-04-04 16:24:43 +00:00
}
2009-11-04 21:16:50 +00:00
}
//end tables
# define MAX_ARRAY_VERTS 65535
2015-08-25 03:02:19 +00:00
static vecV_t vertexarray [ MAX_ARRAY_VERTS ] ;
2015-08-28 03:13:45 +00:00
# if 1 //ndef GLSLONLY
2009-11-04 21:16:50 +00:00
static avec4_t coloursarray [ MAX_ARRAY_VERTS ] ;
2015-08-28 03:13:45 +00:00
# ifdef FTE_TARGET_WEB
static float texcoordarray [ 1 ] [ MAX_ARRAY_VERTS * 2 ] ;
# else
2009-11-04 21:16:50 +00:00
static float texcoordarray [ SHADER_PASS_MAX ] [ MAX_ARRAY_VERTS * 2 ] ;
2015-08-28 03:13:45 +00:00
# endif
2009-11-04 21:16:50 +00:00
/*========================================== texture coord generation =====================================*/
2011-05-29 04:26:29 +00:00
static void tcgen_environment ( float * st , unsigned int numverts , float * xyz , float * normal )
2009-11-04 21:16:50 +00:00
{
int i ;
vec3_t viewer , reflected ;
float d ;
vec3_t rorg ;
RotateLightVector ( shaderstate . curentity - > axis , shaderstate . curentity - > origin , r_origin , rorg ) ;
2011-05-29 04:26:29 +00:00
for ( i = 0 ; i < numverts ; i + + , xyz + = sizeof ( vecV_t ) / sizeof ( vec_t ) , normal + = 3 , st + = 2 )
2009-11-04 21:16:50 +00:00
{
VectorSubtract ( rorg , xyz , viewer ) ;
VectorNormalizeFast ( viewer ) ;
d = DotProduct ( normal , viewer ) ;
reflected [ 0 ] = normal [ 0 ] * 2 * d - viewer [ 0 ] ;
reflected [ 1 ] = normal [ 1 ] * 2 * d - viewer [ 1 ] ;
reflected [ 2 ] = normal [ 2 ] * 2 * d - viewer [ 2 ] ;
st [ 0 ] = 0.5 + reflected [ 1 ] * 0.5 ;
st [ 1 ] = 0.5 - reflected [ 2 ] * 0.5 ;
}
}
2016-07-12 00:40:13 +00:00
# ifndef GLSLONLY
2012-10-08 04:36:10 +00:00
static void tcgen_fog ( float * st , unsigned int numverts , float * xyz , mfog_t * fog )
2011-02-25 04:22:14 +00:00
{
int i ;
float z ;
2013-11-21 23:02:28 +00:00
float eye , point ;
2011-02-25 04:22:14 +00:00
vec4_t zmat ;
//generate a simple matrix to calc only the projected z coord
zmat [ 0 ] = - shaderstate . modelviewmatrix [ 2 ] ;
zmat [ 1 ] = - shaderstate . modelviewmatrix [ 6 ] ;
zmat [ 2 ] = - shaderstate . modelviewmatrix [ 10 ] ;
zmat [ 3 ] = - shaderstate . modelviewmatrix [ 14 ] ;
Vector4Scale ( zmat , shaderstate . fogfar , zmat ) ;
2017-11-30 17:59:11 +00:00
if ( fog & & fog - > visibleplane )
{
2013-11-21 23:02:28 +00:00
eye = ( DotProduct ( r_refdef . vieworg , fog - > visibleplane - > normal ) - fog - > visibleplane - > dist ) ;
2017-11-30 17:59:11 +00:00
if ( eye < 1 )
eye = 1 ; //avoids a nan
2013-11-21 23:02:28 +00:00
2017-11-30 17:59:11 +00:00
for ( i = 0 ; i < numverts ; i + + , xyz + = sizeof ( vecV_t ) / sizeof ( vec_t ) , st + = 2 )
{
z = DotProduct ( xyz , zmat ) + zmat [ 3 ] ;
st [ 0 ] = z ;
2013-11-21 23:02:28 +00:00
2017-11-30 17:59:11 +00:00
if ( fog - > visibleplane )
point = ( DotProduct ( xyz , fog - > visibleplane - > normal ) - fog - > visibleplane - > dist ) ;
else
point = 1 ;
2013-11-21 23:02:28 +00:00
st [ 1 ] = point / ( point - eye ) ;
2017-11-30 17:59:11 +00:00
if ( st [ 1 ] > 31 / 32.0 )
st [ 1 ] = 31 / 32.0 ;
}
}
else
{
for ( i = 0 ; i < numverts ; i + + , xyz + = sizeof ( vecV_t ) / sizeof ( vec_t ) , st + = 2 )
{
z = DotProduct ( xyz , zmat ) + zmat [ 3 ] ;
st [ 0 ] = z ;
2013-11-21 23:02:28 +00:00
st [ 1 ] = 31 / 32.0 ;
2017-11-30 17:59:11 +00:00
}
2011-02-25 04:22:14 +00:00
}
}
2016-07-12 00:40:13 +00:00
static void GenerateTCFog ( int passnum , mfog_t * fog )
{
int m ;
mesh_t * mesh ;
for ( m = 0 ; m < shaderstate . meshcount ; m + + )
{
mesh = shaderstate . meshes [ m ] ;
tcgen_fog ( texcoordarray [ passnum ] + mesh - > vbofirstvert * 2 , mesh - > numvertexes , ( float * ) mesh - > xyz_array , fog ) ;
}
2011-02-25 04:22:14 +00:00
2016-07-12 00:40:13 +00:00
shaderstate . pendingtexcoordparts [ passnum ] = 2 ;
shaderstate . pendingtexcoordvbo [ passnum ] = 0 ;
shaderstate . pendingtexcoordpointer [ passnum ] = texcoordarray [ passnum ] ;
}
# endif
2017-08-29 02:29:06 +00:00
static float * tcgen3 ( const shaderpass_t * pass , int cnt , float * dst , const mesh_t * mesh )
{
int i ;
vecV_t * src ;
switch ( pass - > tcgen )
{
default :
case TC_GEN_SKYBOX :
src = mesh - > xyz_array ;
for ( i = 0 ; i < cnt ; i + + , dst + = 3 )
{
2018-02-09 17:42:09 +00:00
dst [ 0 ] = src [ i ] [ 0 ] - r_refdef . vieworg [ 0 ] ;
dst [ 1 ] = r_refdef . vieworg [ 1 ] - src [ i ] [ 1 ] ;
dst [ 2 ] = src [ i ] [ 2 ] - r_refdef . vieworg [ 2 ] ;
2017-08-29 02:29:06 +00:00
}
return dst - cnt * 3 ;
// case TC_GEN_WOBBLESKY:
// case TC_GEN_REFLECT:
// break;
}
}
2016-07-12 00:40:13 +00:00
static float * tcgen ( const shaderpass_t * pass , int cnt , float * dst , const mesh_t * mesh )
2009-11-04 21:16:50 +00:00
{
int i ;
vecV_t * src ;
2016-07-12 00:40:13 +00:00
switch ( pass - > tcgen )
2009-11-04 21:16:50 +00:00
{
default :
case TC_GEN_BASE :
return ( float * ) mesh - > st_array ;
case TC_GEN_LIGHTMAP :
2016-07-12 00:40:13 +00:00
if ( ! mesh - > lmst_array [ 0 ] )
2011-05-20 04:10:46 +00:00
return ( float * ) mesh - > st_array ;
else
2016-07-12 00:40:13 +00:00
return ( float * ) mesh - > lmst_array [ 0 ] ;
2009-11-04 21:16:50 +00:00
case TC_GEN_NORMAL :
return ( float * ) mesh - > normals_array ;
case TC_GEN_SVECTOR :
return ( float * ) mesh - > snormals_array ;
case TC_GEN_TVECTOR :
return ( float * ) mesh - > tnormals_array ;
case TC_GEN_ENVIRONMENT :
2010-11-02 23:17:25 +00:00
if ( ! mesh - > normals_array )
return ( float * ) mesh - > st_array ;
2009-11-04 21:16:50 +00:00
tcgen_environment ( dst , cnt , ( float * ) mesh - > xyz_array , ( float * ) mesh - > normals_array ) ;
return dst ;
// case TC_GEN_DOTPRODUCT:
// return mesh->st_array[0];
case TC_GEN_VECTOR :
src = mesh - > xyz_array ;
for ( i = 0 ; i < cnt ; i + + , dst + = 2 )
{
2016-07-12 00:40:13 +00:00
dst [ 0 ] = DotProduct ( pass - > tcgenvec [ 0 ] , src [ i ] ) ;
dst [ 1 ] = DotProduct ( pass - > tcgenvec [ 1 ] , src [ i ] ) ;
2009-11-04 21:16:50 +00:00
}
2017-08-29 02:29:06 +00:00
return dst - cnt * 2 ;
2014-02-07 08:38:40 +00:00
// case TC_GEN_SKYBOX:
// case TC_GEN_WOBBLESKY:
// case TC_GEN_REFLECT:
// break;
2009-11-04 21:16:50 +00:00
}
}
/*src and dst can be the same address when tcmods are chained*/
static void tcmod ( const tcmod_t * tcmod , int cnt , const float * src , float * dst , const mesh_t * mesh )
{
float * table ;
float t1 , t2 ;
float cost , sint ;
int j ;
switch ( tcmod - > type )
{
case SHADER_TCMOD_ROTATE :
cost = tcmod - > args [ 0 ] * shaderstate . curtime ;
sint = R_FastSin ( cost ) ;
cost = R_FastSin ( cost + 0.25 ) ;
for ( j = 0 ; j < cnt ; j + + , dst + = 2 , src + = 2 )
{
t1 = cost * ( src [ 0 ] - 0.5f ) - sint * ( src [ 1 ] - 0.5f ) + 0.5f ;
t2 = cost * ( src [ 1 ] - 0.5f ) + sint * ( src [ 0 ] - 0.5f ) + 0.5f ;
dst [ 0 ] = t1 ;
dst [ 1 ] = t2 ;
}
break ;
case SHADER_TCMOD_SCALE :
t1 = tcmod - > args [ 0 ] ;
t2 = tcmod - > args [ 1 ] ;
for ( j = 0 ; j < cnt ; j + + , dst + = 2 , src + = 2 )
{
dst [ 0 ] = src [ 0 ] * t1 ;
dst [ 1 ] = src [ 1 ] * t2 ;
}
break ;
case SHADER_TCMOD_TURB :
t1 = tcmod - > args [ 2 ] + shaderstate . curtime * tcmod - > args [ 3 ] ;
t2 = tcmod - > args [ 1 ] ;
for ( j = 0 ; j < cnt ; j + + , dst + = 2 , src + = 2 )
{
dst [ 0 ] = src [ 0 ] + R_FastSin ( src [ 0 ] * t2 + t1 ) * t2 ;
dst [ 1 ] = src [ 1 ] + R_FastSin ( src [ 1 ] * t2 + t1 ) * t2 ;
}
break ;
2011-05-29 04:26:29 +00:00
2009-11-04 21:16:50 +00:00
case SHADER_TCMOD_STRETCH :
table = FTableForFunc ( tcmod - > args [ 0 ] ) ;
t2 = tcmod - > args [ 3 ] + shaderstate . curtime * tcmod - > args [ 4 ] ;
t1 = FTABLE_EVALUATE ( table , t2 ) * tcmod - > args [ 2 ] + tcmod - > args [ 1 ] ;
t1 = t1 ? 1.0f / t1 : 1.0f ;
t2 = 0.5f - 0.5f * t1 ;
for ( j = 0 ; j < cnt ; j + + , dst + = 2 , src + = 2 )
{
dst [ 0 ] = src [ 0 ] * t1 + t2 ;
dst [ 1 ] = src [ 1 ] * t1 + t2 ;
}
break ;
2011-05-29 04:26:29 +00:00
2009-11-04 21:16:50 +00:00
case SHADER_TCMOD_SCROLL :
t1 = tcmod - > args [ 0 ] * shaderstate . curtime ;
t2 = tcmod - > args [ 1 ] * shaderstate . curtime ;
for ( j = 0 ; j < cnt ; j + + , dst + = 2 , src + = 2 )
{
dst [ 0 ] = src [ 0 ] + t1 ;
dst [ 1 ] = src [ 1 ] + t2 ;
}
break ;
2011-05-29 04:26:29 +00:00
2009-11-04 21:16:50 +00:00
case SHADER_TCMOD_TRANSFORM :
for ( j = 0 ; j < cnt ; j + + , dst + = 2 , src + = 2 )
{
t1 = src [ 0 ] ;
t2 = src [ 1 ] ;
dst [ 0 ] = t1 * tcmod - > args [ 0 ] + t2 * tcmod - > args [ 2 ] + tcmod - > args [ 4 ] ;
2014-02-14 09:59:32 +00:00
dst [ 1 ] = t1 * tcmod - > args [ 1 ] + t2 * tcmod - > args [ 3 ] + tcmod - > args [ 5 ] ;
2009-11-04 21:16:50 +00:00
}
break ;
2017-08-29 02:29:06 +00:00
case SHADER_TCMOD_PAGE :
{ //simple atlas bias with no scaling. use a separate tcmod for that.
int w = tcmod - > args [ 0 ] ;
int h = tcmod - > args [ 1 ] ;
float f = shaderstate . curtime / ( tcmod - > args [ 2 ] * w * h ) ;
int idx = ( f - floor ( f ) ) * w * h ;
t1 = ( idx % w ) / tcmod - > args [ 0 ] ;
t2 = ( idx / w ) / tcmod - > args [ 1 ] ;
for ( j = 0 ; j < cnt ; j + + , dst + = 2 , src + = 2 )
{
dst [ 0 ] = src [ 0 ] + t1 ;
dst [ 1 ] = src [ 1 ] + t2 ;
}
}
break ;
2009-11-04 21:16:50 +00:00
default :
break ;
}
}
2017-08-29 02:29:06 +00:00
static void GenerateTCMods3 ( const shaderpass_t * pass , int passnum )
{
# if 1
int m ;
float * src ;
mesh_t * mesh ;
for ( m = 0 ; m < shaderstate . meshcount ; m + + )
{
mesh = shaderstate . meshes [ m ] ;
src = tcgen3 ( pass , mesh - > numvertexes , texcoordarray [ passnum ] + mesh - > vbofirstvert * 3 , mesh ) ;
if ( src ! = texcoordarray [ passnum ] + mesh - > vbofirstvert * 3 )
{
//this shouldn't actually ever be true
2018-03-04 14:41:16 +00:00
memcpy ( texcoordarray [ passnum ] + mesh - > vbofirstvert * 3 , src , sizeof ( vec3_t ) * mesh - > numvertexes ) ;
2017-08-29 02:29:06 +00:00
}
}
shaderstate . pendingtexcoordparts [ passnum ] = 3 ;
shaderstate . pendingtexcoordvbo [ passnum ] = 0 ;
shaderstate . pendingtexcoordpointer [ passnum ] = texcoordarray [ passnum ] ;
# else
GL_DeselectVAO ( ) ;
if ( ! shaderstate . vbo_texcoords [ passnum ] )
{
shaderstate . vbo_texcoords [ passnum ] = 0 ;
qglGenBuffersARB ( 1 , & shaderstate . vbo_texcoords [ passnum ] ) ;
}
GL_SelectVBO ( shaderstate . vbo_texcoords [ passnum ] ) ;
{
qglBufferDataARB ( GL_ARRAY_BUFFER_ARB , MAX_ARRAY_VERTS * sizeof ( float ) * 3 , NULL , GL_STREAM_DRAW_ARB ) ;
for ( ; meshlist ; meshlist = meshlist - > next )
{
int i ;
float * src ;
src = tcge3n ( pass , meshlist - > numvertexes , texcoordarray [ passnum ] , meshlist ) ;
qglBufferSubDataARB ( GL_ARRAY_BUFFER_ARB , meshlist - > vbofirstvert * 8 , meshlist - > numvertexes * 8 , src ) ;
}
}
shaderstate . pendingtexcoordparts [ passnum ] = 2 ;
shaderstate . pendingtexcoordvbo [ passnum ] = shaderstate . vbo_texcoords [ passnum ] ;
shaderstate . pendingtexcoordpointer [ passnum ] = NULL ;
# endif
}
2010-07-11 02:22:39 +00:00
static void GenerateTCMods ( const shaderpass_t * pass , int passnum )
2009-11-04 21:16:50 +00:00
{
# if 1
2010-07-11 02:22:39 +00:00
int i , m ;
float * src ;
mesh_t * mesh ;
for ( m = 0 ; m < shaderstate . meshcount ; m + + )
2009-11-04 21:16:50 +00:00
{
2010-07-11 02:22:39 +00:00
mesh = shaderstate . meshes [ m ] ;
2004-10-19 16:10:14 +00:00
2016-07-12 00:40:13 +00:00
src = tcgen ( pass , mesh - > numvertexes , texcoordarray [ passnum ] + mesh - > vbofirstvert * 2 , mesh ) ;
2009-11-04 21:16:50 +00:00
//tcgen might return unmodified info
if ( pass - > numtcmods )
{
2010-07-11 02:22:39 +00:00
tcmod ( & pass - > tcmods [ 0 ] , mesh - > numvertexes , src , texcoordarray [ passnum ] + mesh - > vbofirstvert * 2 , mesh ) ;
2009-11-04 21:16:50 +00:00
for ( i = 1 ; i < pass - > numtcmods ; i + + )
{
2010-07-11 02:22:39 +00:00
tcmod ( & pass - > tcmods [ i ] , mesh - > numvertexes , texcoordarray [ passnum ] + mesh - > vbofirstvert * 2 , texcoordarray [ passnum ] + mesh - > vbofirstvert * 2 , mesh ) ;
2009-11-04 21:16:50 +00:00
}
2010-07-11 02:22:39 +00:00
src = texcoordarray [ passnum ] + mesh - > vbofirstvert * 2 ;
2009-11-04 21:16:50 +00:00
}
2010-07-11 02:22:39 +00:00
else if ( src ! = texcoordarray [ passnum ] + mesh - > vbofirstvert * 2 )
2009-11-04 21:16:50 +00:00
{
//this shouldn't actually ever be true
2010-07-11 02:22:39 +00:00
memcpy ( texcoordarray [ passnum ] + mesh - > vbofirstvert * 2 , src , 8 * mesh - > numvertexes ) ;
2009-11-04 21:16:50 +00:00
}
}
2012-11-27 03:23:19 +00:00
shaderstate . pendingtexcoordparts [ passnum ] = 2 ;
shaderstate . pendingtexcoordvbo [ passnum ] = 0 ;
shaderstate . pendingtexcoordpointer [ passnum ] = texcoordarray [ passnum ] ;
2009-11-04 21:16:50 +00:00
# else
2012-11-27 03:23:19 +00:00
GL_DeselectVAO ( ) ;
2009-11-04 21:16:50 +00:00
if ( ! shaderstate . vbo_texcoords [ passnum ] )
{
2013-05-13 13:43:18 +00:00
shaderstate . vbo_texcoords [ passnum ] = 0 ;
2009-11-04 21:16:50 +00:00
qglGenBuffersARB ( 1 , & shaderstate . vbo_texcoords [ passnum ] ) ;
}
GL_SelectVBO ( shaderstate . vbo_texcoords [ passnum ] ) ;
{
qglBufferDataARB ( GL_ARRAY_BUFFER_ARB , MAX_ARRAY_VERTS * sizeof ( float ) * 2 , NULL , GL_STREAM_DRAW_ARB ) ;
for ( ; meshlist ; meshlist = meshlist - > next )
{
int i ;
float * src ;
src = tcgen ( pass , meshlist - > numvertexes , texcoordarray [ passnum ] , meshlist ) ;
//tcgen might return unmodified info
if ( pass - > numtcmods )
{
tcmod ( & pass - > tcmods [ 0 ] , meshlist - > numvertexes , src , texcoordarray [ passnum ] , meshlist ) ;
for ( i = 1 ; i < pass - > numtcmods ; i + + )
{
tcmod ( & pass - > tcmods [ i ] , meshlist - > numvertexes , texcoordarray [ passnum ] , texcoordarray [ passnum ] , meshlist ) ;
}
src = texcoordarray [ passnum ] ;
}
qglBufferSubDataARB ( GL_ARRAY_BUFFER_ARB , meshlist - > vbofirstvert * 8 , meshlist - > numvertexes * 8 , src ) ;
}
}
2012-11-27 03:23:19 +00:00
shaderstate . pendingtexcoordparts [ passnum ] = 2 ;
shaderstate . pendingtexcoordvbo [ passnum ] = shaderstate . vbo_texcoords [ passnum ] ;
shaderstate . pendingtexcoordpointer [ passnum ] = NULL ;
2009-11-04 21:16:50 +00:00
# endif
}
//end texture coords
/*========================================== colour generation =====================================*/
//source is always packed
//dest is packed too
2011-01-29 21:01:40 +00:00
static void colourgen ( const shaderpass_t * pass , int cnt , vec4_t * src , vec4_t * dst , const mesh_t * mesh )
2009-11-04 21:16:50 +00:00
{
switch ( pass - > rgbgen )
{
case RGB_GEN_ENTITY :
while ( ( cnt ) - - )
{
dst [ cnt ] [ 0 ] = shaderstate . curentity - > shaderRGBAf [ 0 ] ;
dst [ cnt ] [ 1 ] = shaderstate . curentity - > shaderRGBAf [ 1 ] ;
dst [ cnt ] [ 2 ] = shaderstate . curentity - > shaderRGBAf [ 2 ] ;
}
break ;
case RGB_GEN_ONE_MINUS_ENTITY :
while ( ( cnt ) - - )
{
dst [ cnt ] [ 0 ] = 1 - shaderstate . curentity - > shaderRGBAf [ 0 ] ;
dst [ cnt ] [ 1 ] = 1 - shaderstate . curentity - > shaderRGBAf [ 1 ] ;
dst [ cnt ] [ 2 ] = 1 - shaderstate . curentity - > shaderRGBAf [ 2 ] ;
}
break ;
2011-10-27 16:16:29 +00:00
case RGB_GEN_VERTEX_LIGHTING :
2016-07-15 12:26:24 +00:00
# if MAXRLIGHTMAPS > 1
2013-08-27 13:18:09 +00:00
if ( mesh - > colors4f_array [ 1 ] )
{
2013-10-08 14:28:11 +00:00
float lm [ MAXRLIGHTMAPS ] ;
2013-08-27 13:18:09 +00:00
lm [ 0 ] = d_lightstylevalue [ shaderstate . curbatch - > vtlightstyle [ 0 ] ] / 256.0f * shaderstate . identitylighting ;
lm [ 1 ] = d_lightstylevalue [ shaderstate . curbatch - > vtlightstyle [ 1 ] ] / 256.0f * shaderstate . identitylighting ;
lm [ 2 ] = d_lightstylevalue [ shaderstate . curbatch - > vtlightstyle [ 2 ] ] / 256.0f * shaderstate . identitylighting ;
lm [ 3 ] = d_lightstylevalue [ shaderstate . curbatch - > vtlightstyle [ 3 ] ] / 256.0f * shaderstate . identitylighting ;
while ( ( cnt ) - - )
{
VectorScale ( mesh - > colors4f_array [ 0 ] [ cnt ] , lm [ 0 ] , dst [ cnt ] ) ;
VectorMA ( dst [ cnt ] , lm [ 1 ] , mesh - > colors4f_array [ 1 ] [ cnt ] , dst [ cnt ] ) ;
VectorMA ( dst [ cnt ] , lm [ 2 ] , mesh - > colors4f_array [ 2 ] [ cnt ] , dst [ cnt ] ) ;
VectorMA ( dst [ cnt ] , lm [ 3 ] , mesh - > colors4f_array [ 3 ] [ cnt ] , dst [ cnt ] ) ;
}
break ;
}
2016-07-15 12:26:24 +00:00
# endif
2013-08-27 13:18:09 +00:00
2011-10-27 16:16:29 +00:00
if ( shaderstate . identitylighting ! = 1 )
{
if ( ! src )
{
while ( ( cnt ) - - )
{
dst [ cnt ] [ 0 ] = shaderstate . identitylighting ;
dst [ cnt ] [ 1 ] = shaderstate . identitylighting ;
dst [ cnt ] [ 2 ] = shaderstate . identitylighting ;
}
break ;
}
while ( ( cnt ) - - )
{
dst [ cnt ] [ 0 ] = src [ cnt ] [ 0 ] * shaderstate . identitylighting ;
dst [ cnt ] [ 1 ] = src [ cnt ] [ 1 ] * shaderstate . identitylighting ;
dst [ cnt ] [ 2 ] = src [ cnt ] [ 2 ] * shaderstate . identitylighting ;
}
break ;
}
case RGB_GEN_VERTEX_EXACT :
2009-11-04 21:16:50 +00:00
if ( ! src )
{
while ( ( cnt ) - - )
{
2011-10-27 16:16:29 +00:00
dst [ cnt ] [ 0 ] = 1 ;
dst [ cnt ] [ 1 ] = 1 ;
dst [ cnt ] [ 2 ] = 1 ;
2009-11-04 21:16:50 +00:00
}
break ;
}
while ( ( cnt ) - - )
{
dst [ cnt ] [ 0 ] = src [ cnt ] [ 0 ] ;
dst [ cnt ] [ 1 ] = src [ cnt ] [ 1 ] ;
dst [ cnt ] [ 2 ] = src [ cnt ] [ 2 ] ;
}
break ;
case RGB_GEN_ONE_MINUS_VERTEX :
while ( ( cnt ) - - )
{
dst [ cnt ] [ 0 ] = 1 - src [ cnt ] [ 0 ] ;
dst [ cnt ] [ 1 ] = 1 - src [ cnt ] [ 1 ] ;
dst [ cnt ] [ 2 ] = 1 - src [ cnt ] [ 2 ] ;
}
break ;
case RGB_GEN_IDENTITY_LIGHTING :
2013-08-27 13:18:09 +00:00
if ( shaderstate . curbatch - > vtlightstyle [ 0 ] ! = 255 & & d_lightstylevalue [ shaderstate . curbatch - > vtlightstyle [ 0 ] ] ! = 256 )
2009-11-04 21:16:50 +00:00
{
2013-08-27 13:18:09 +00:00
//FIXME:
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
while ( ( cnt ) - - )
{
2013-08-27 13:18:09 +00:00
dst [ cnt ] [ 0 ] = shaderstate . identitylighting * d_lightstylevalue [ shaderstate . curbatch - > vtlightstyle [ 0 ] ] / 256.0f ;
dst [ cnt ] [ 1 ] = shaderstate . identitylighting * d_lightstylevalue [ shaderstate . curbatch - > vtlightstyle [ 0 ] ] / 256.0f ;
dst [ cnt ] [ 2 ] = shaderstate . identitylighting * d_lightstylevalue [ shaderstate . curbatch - > vtlightstyle [ 0 ] ] / 256.0f ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
}
}
else
{
//compensate for overbrights
while ( ( cnt ) - - )
{
dst [ cnt ] [ 0 ] = shaderstate . identitylighting ;
dst [ cnt ] [ 1 ] = shaderstate . identitylighting ;
dst [ cnt ] [ 2 ] = shaderstate . identitylighting ;
}
2009-11-04 21:16:50 +00:00
}
break ;
2013-08-27 13:18:09 +00:00
case RGB_GEN_IDENTITY_OVERBRIGHT :
while ( ( cnt ) - - )
{
dst [ cnt ] [ 0 ] = shaderstate . identitylightmap ;
dst [ cnt ] [ 1 ] = shaderstate . identitylightmap ;
dst [ cnt ] [ 2 ] = shaderstate . identitylightmap ;
}
break ;
2009-11-04 21:16:50 +00:00
default :
case RGB_GEN_IDENTITY :
while ( ( cnt ) - - )
{
2013-08-27 13:18:09 +00:00
dst [ cnt ] [ 0 ] = shaderstate . identitylighting ;
dst [ cnt ] [ 1 ] = shaderstate . identitylighting ;
dst [ cnt ] [ 2 ] = shaderstate . identitylighting ;
2009-11-04 21:16:50 +00:00
}
break ;
case RGB_GEN_CONST :
while ( ( cnt ) - - )
{
dst [ cnt ] [ 0 ] = pass - > rgbgen_func . args [ 0 ] ;
dst [ cnt ] [ 1 ] = pass - > rgbgen_func . args [ 1 ] ;
dst [ cnt ] [ 2 ] = pass - > rgbgen_func . args [ 2 ] ;
}
break ;
2017-12-09 21:22:46 +00:00
case RGB_GEN_ENTITY_LIGHTING_DIFFUSE :
R_LightArrays ( shaderstate . curentity , mesh - > xyz_array , dst , cnt , mesh - > normals_array , shaderstate . identitylighting , true ) ;
break ;
2009-11-04 21:16:50 +00:00
case RGB_GEN_LIGHTING_DIFFUSE :
2017-12-09 21:22:46 +00:00
R_LightArrays ( shaderstate . curentity , mesh - > xyz_array , dst , cnt , mesh - > normals_array , shaderstate . identitylighting , false ) ;
2009-11-04 21:16:50 +00:00
break ;
case RGB_GEN_WAVE :
{
float * table ;
float c ;
table = FTableForFunc ( pass - > rgbgen_func . type ) ;
c = pass - > rgbgen_func . args [ 2 ] + shaderstate . curtime * pass - > rgbgen_func . args [ 3 ] ;
c = FTABLE_EVALUATE ( table , c ) * pass - > rgbgen_func . args [ 1 ] + pass - > rgbgen_func . args [ 0 ] ;
c = bound ( 0.0f , c , 1.0f ) ;
while ( ( cnt ) - - )
{
dst [ cnt ] [ 0 ] = c ;
dst [ cnt ] [ 1 ] = c ;
dst [ cnt ] [ 2 ] = c ;
}
}
break ;
case RGB_GEN_TOPCOLOR :
2010-07-11 02:22:39 +00:00
if ( cnt )
{
2015-03-03 00:14:43 +00:00
R_FetchPlayerColour ( shaderstate . curentity - > topcolour , dst [ 0 ] ) ;
2010-07-11 02:22:39 +00:00
while ( ( cnt ) - - )
2004-12-24 08:45:56 +00:00
{
2010-07-11 02:22:39 +00:00
dst [ cnt ] [ 0 ] = dst [ 0 ] [ 0 ] ;
dst [ cnt ] [ 1 ] = dst [ 0 ] [ 1 ] ;
dst [ cnt ] [ 2 ] = dst [ 0 ] [ 2 ] ;
2004-10-19 16:10:14 +00:00
}
2010-07-11 02:22:39 +00:00
}
break ;
2009-11-04 21:16:50 +00:00
case RGB_GEN_BOTTOMCOLOR :
2010-07-11 02:22:39 +00:00
if ( cnt )
2009-11-04 21:16:50 +00:00
{
2015-03-03 00:14:43 +00:00
R_FetchPlayerColour ( shaderstate . curentity - > bottomcolour , dst [ 0 ] ) ;
2010-07-11 02:22:39 +00:00
while ( ( cnt ) - - )
2009-01-15 04:56:44 +00:00
{
2010-07-11 02:22:39 +00:00
dst [ cnt ] [ 0 ] = dst [ 0 ] [ 0 ] ;
dst [ cnt ] [ 1 ] = dst [ 0 ] [ 1 ] ;
dst [ cnt ] [ 2 ] = dst [ 0 ] [ 2 ] ;
2005-02-06 02:47:36 +00:00
}
2009-11-04 21:16:50 +00:00
}
break ;
}
}
2015-08-25 03:02:19 +00:00
# endif
2009-11-04 21:16:50 +00:00
2018-01-22 19:18:04 +00:00
static qboolean BE_GenTempMeshVBO ( vbo_t * * vbo , mesh_t * m ) ;
static void DeformGen_Text ( int stringid , int cnt , vecV_t * src , vecV_t * dst , const mesh_t * mesh )
{
# define maxlen 32
vecV_t * textverts = vertexarray ;
static vec2_t texttc [ maxlen * 4 ] ;
extern index_t r_quad_indexes [ ] ;
static mesh_t textmesh , * meshptr = & textmesh ;
int i ;
vec3_t org ;
vec3_t right ;
vec3_t down ;
float s , t , d ;
char cvarname [ 64 ] ;
const char * text ;
Q_snprintfz ( cvarname , sizeof ( cvarname ) , " r_shadertext_%i " , stringid ) ;
text = Cvar_Get ( cvarname , " " , 0 , " Shader System " ) - > string ;
VectorCopy ( mesh - > snormals_array [ 0 ] , right ) ;
VectorNegate ( mesh - > tnormals_array [ 0 ] , down ) ;
CrossProduct ( right , down , org ) ;
if ( DotProduct ( mesh - > normals_array [ 0 ] , org ) > 0 )
VectorNegate ( right , right ) ;
VectorClear ( org ) ;
for ( i = 0 ; i < cnt ; i + + )
VectorAdd ( org , src [ i ] , org ) ;
VectorScale ( org , 1.0 / i , org ) ;
for ( i = 0 , s = 0 ; i < 4 ; i + + )
{
d = DotProduct ( right , src [ i ] ) - DotProduct ( right , org ) ;
if ( s < d )
s = d ;
}
i = strlen ( text ) ;
VectorScale ( right , 2 * s / i , right ) ;
VectorScale ( down , 2 * s / i , down ) ;
VectorMA ( org , - i * 0.5 , right , org ) ;
memset ( & textmesh , 0 , sizeof ( textmesh ) ) ;
textmesh . indexes = r_quad_indexes ;
textmesh . xyz_array = textverts ;
textmesh . st_array = texttc ;
org [ 1 ] + = 0 ;
for ( i = 0 ; i < maxlen ; )
{
qbyte c = * text + + ;
if ( ! c )
break ;
if ( c ! = ' ' )
{
const float sz = 1 / 16.0f ;
s = ( c & 15 ) * sz ;
t = ( c > > 4 ) * sz ;
VectorCopy ( org , textverts [ i * 4 + 0 ] ) ;
Vector2Set ( texttc [ i * 4 + 0 ] , s , t ) ;
VectorAdd ( textverts [ i * 4 + 0 ] , right , textverts [ i * 4 + 1 ] ) ;
Vector2Set ( texttc [ i * 4 + 1 ] , s + sz , t ) ;
VectorAdd ( textverts [ i * 4 + 1 ] , down , textverts [ i * 4 + 2 ] ) ;
Vector2Set ( texttc [ i * 4 + 2 ] , s + sz , t + sz ) ;
VectorAdd ( textverts [ i * 4 + 0 ] , down , textverts [ i * 4 + 3 ] ) ;
Vector2Set ( texttc [ i * 4 + 3 ] , s , t + sz ) ;
i + + ;
}
VectorAdd ( org , right , org ) ;
}
textmesh . numindexes = i * 6 ;
textmesh . numvertexes = i * 4 ;
if ( ! BE_GenTempMeshVBO ( & shaderstate . sourcevbo , & textmesh ) )
return ;
shaderstate . meshcount = 1 ;
shaderstate . meshes = & meshptr ;
# undef maxlen
}
2011-01-29 21:01:40 +00:00
static void deformgen ( const deformv_t * deformv , int cnt , vecV_t * src , vecV_t * dst , const mesh_t * mesh )
2009-11-04 21:16:50 +00:00
{
float * table ;
int j , k ;
float args [ 4 ] ;
float deflect ;
switch ( deformv - > type )
{
default :
case DEFORMV_NONE :
2011-01-29 21:01:40 +00:00
if ( src ! = dst )
2009-11-04 21:16:50 +00:00
memcpy ( dst , src , sizeof ( * src ) * cnt ) ;
break ;
case DEFORMV_WAVE :
if ( ! mesh - > normals_array )
{
2011-01-29 21:01:40 +00:00
if ( src ! = dst )
2009-11-04 21:16:50 +00:00
memcpy ( dst , src , sizeof ( * src ) * cnt ) ;
return ;
}
args [ 0 ] = deformv - > func . args [ 0 ] ;
args [ 1 ] = deformv - > func . args [ 1 ] ;
args [ 3 ] = deformv - > func . args [ 2 ] + deformv - > func . args [ 3 ] * shaderstate . curtime ;
table = FTableForFunc ( deformv - > func . type ) ;
for ( j = 0 ; j < cnt ; j + + )
{
deflect = deformv - > args [ 0 ] * ( src [ j ] [ 0 ] + src [ j ] [ 1 ] + src [ j ] [ 2 ] ) + args [ 3 ] ;
deflect = FTABLE_EVALUATE ( table , deflect ) * args [ 1 ] + args [ 0 ] ;
// Deflect vertex along its normal by wave amount
VectorMA ( src [ j ] , deflect , mesh - > normals_array [ j ] , dst [ j ] ) ;
}
break ;
case DEFORMV_NORMAL :
//normal does not actually move the verts, but it does change the normals array
//we don't currently support that.
2011-01-29 21:01:40 +00:00
if ( src ! = dst )
2009-11-04 21:16:50 +00:00
memcpy ( dst , src , sizeof ( * src ) * cnt ) ;
/*
args [ 0 ] = deformv - > args [ 1 ] * shaderstate . curtime ;
for ( j = 0 ; j < cnt ; j + + )
{
args [ 1 ] = normalsArray [ j ] [ 2 ] * args [ 0 ] ;
deflect = deformv - > args [ 0 ] * R_FastSin ( args [ 1 ] ) ;
normalsArray [ j ] [ 0 ] * = deflect ;
deflect = deformv - > args [ 0 ] * R_FastSin ( args [ 1 ] + 0.25 ) ;
normalsArray [ j ] [ 1 ] * = deflect ;
VectorNormalizeFast ( normalsArray [ j ] ) ;
}
*/ break ;
case DEFORMV_MOVE :
table = FTableForFunc ( deformv - > func . type ) ;
deflect = deformv - > func . args [ 2 ] + shaderstate . curtime * deformv - > func . args [ 3 ] ;
deflect = FTABLE_EVALUATE ( table , deflect ) * deformv - > func . args [ 1 ] + deformv - > func . args [ 0 ] ;
for ( j = 0 ; j < cnt ; j + + )
VectorMA ( src [ j ] , deflect , deformv - > args , dst [ j ] ) ;
break ;
case DEFORMV_BULGE :
2016-07-12 00:40:13 +00:00
if ( ! mesh - > normals_array )
{
if ( src ! = dst )
memcpy ( dst , src , sizeof ( * src ) * cnt ) ;
break ;
}
2009-11-04 21:16:50 +00:00
args [ 0 ] = deformv - > args [ 0 ] / ( 2 * M_PI ) ;
args [ 1 ] = deformv - > args [ 1 ] ;
args [ 2 ] = shaderstate . curtime * deformv - > args [ 2 ] / ( 2 * M_PI ) ;
for ( j = 0 ; j < cnt ; j + + )
{
deflect = R_FastSin ( mesh - > st_array [ j ] [ 0 ] * args [ 0 ] + args [ 2 ] ) * args [ 1 ] ;
dst [ j ] [ 0 ] = src [ j ] [ 0 ] + deflect * mesh - > normals_array [ j ] [ 0 ] ;
dst [ j ] [ 1 ] = src [ j ] [ 1 ] + deflect * mesh - > normals_array [ j ] [ 1 ] ;
dst [ j ] [ 2 ] = src [ j ] [ 2 ] + deflect * mesh - > normals_array [ j ] [ 2 ] ;
}
break ;
case DEFORMV_AUTOSPRITE :
if ( mesh - > numindexes < 6 )
break ;
2018-01-22 19:18:04 +00:00
for ( j = 0 ; j + 3 < cnt ; j + = 4 , src + = 4 , dst + = 4 )
2009-11-04 21:16:50 +00:00
{
vec3_t mid , d ;
2018-09-29 17:31:58 +00:00
vec2_t mid2 ;
float radius , s , t ;
vec2_t * fte_restrict st = & mesh - > st_array [ j ] ;
2009-11-04 21:16:50 +00:00
mid [ 0 ] = 0.25 * ( src [ 0 ] [ 0 ] + src [ 1 ] [ 0 ] + src [ 2 ] [ 0 ] + src [ 3 ] [ 0 ] ) ;
mid [ 1 ] = 0.25 * ( src [ 0 ] [ 1 ] + src [ 1 ] [ 1 ] + src [ 2 ] [ 1 ] + src [ 3 ] [ 1 ] ) ;
mid [ 2 ] = 0.25 * ( src [ 0 ] [ 2 ] + src [ 1 ] [ 2 ] + src [ 2 ] [ 2 ] + src [ 3 ] [ 2 ] ) ;
VectorSubtract ( src [ 0 ] , mid , d ) ;
2018-09-29 17:31:58 +00:00
radius = VectorLength ( d ) ;
mid2 [ 0 ] = 0.25 * ( st [ 0 ] [ 0 ] + st [ 1 ] [ 0 ] + st [ 2 ] [ 0 ] + st [ 3 ] [ 0 ] ) ;
mid2 [ 1 ] = 0.25 * ( st [ 0 ] [ 1 ] + st [ 1 ] [ 1 ] + st [ 2 ] [ 1 ] + st [ 3 ] [ 1 ] ) ;
2009-11-04 21:16:50 +00:00
for ( k = 0 ; k < 4 ; k + + )
{
2018-09-29 17:31:58 +00:00
//q3 fully regenerates verts. we don't because that destroys ST coords.
//even so, if the ST coords are non-centered for some reason then we still need to get the right values as if they were.
//hence the mid2.
s = ( st [ k ] [ 0 ] > mid2 [ 0 ] ) ? 1 : - 1 ;
t = ( st [ k ] [ 1 ] > mid2 [ 1 ] ) ? 1 : - 1 ;
dst [ k ] [ 0 ] = mid [ 0 ] + radius * ( s * shaderstate . modelviewmatrix [ 0 + 0 ] - t * shaderstate . modelviewmatrix [ 0 + 1 ] ) ;
dst [ k ] [ 1 ] = mid [ 1 ] + radius * ( s * shaderstate . modelviewmatrix [ 4 + 0 ] - t * shaderstate . modelviewmatrix [ 4 + 1 ] ) ;
dst [ k ] [ 2 ] = mid [ 2 ] + radius * ( s * shaderstate . modelviewmatrix [ 8 + 0 ] - t * shaderstate . modelviewmatrix [ 8 + 1 ] ) ;
2009-11-04 21:16:50 +00:00
}
}
break ;
case DEFORMV_AUTOSPRITE2 :
if ( mesh - > numindexes < 6 )
break ;
for ( k = 0 ; k < mesh - > numindexes ; k + = 6 )
{
int long_axis , short_axis ;
vec3_t axis ;
float len [ 3 ] ;
mat3_t m0 , m1 , m2 , result ;
float * quad [ 4 ] ;
2018-01-22 19:18:04 +00:00
vec3_t rot_centre , tv , tv2 ;
2009-11-04 21:16:50 +00:00
2018-01-22 19:18:04 +00:00
quad [ 0 ] = ( float * ) ( src + mesh - > indexes [ k + 0 ] ) ;
quad [ 1 ] = ( float * ) ( src + mesh - > indexes [ k + 1 ] ) ;
quad [ 2 ] = ( float * ) ( src + mesh - > indexes [ k + 2 ] ) ;
2009-11-04 21:16:50 +00:00
for ( j = 2 ; j > = 0 ; j - - )
{
2018-01-22 19:18:04 +00:00
quad [ 3 ] = ( float * ) ( src + mesh - > indexes [ k + 3 + j ] ) ;
2011-05-29 04:26:29 +00:00
if ( ! VectorEquals ( quad [ 3 ] , quad [ 0 ] ) & &
2009-11-04 21:16:50 +00:00
! VectorEquals ( quad [ 3 ] , quad [ 1 ] ) & &
! VectorEquals ( quad [ 3 ] , quad [ 2 ] ) )
{
break ;
}
}
// build a matrix were the longest axis of the billboard is the Y-Axis
VectorSubtract ( quad [ 1 ] , quad [ 0 ] , m0 [ 0 ] ) ;
VectorSubtract ( quad [ 2 ] , quad [ 0 ] , m0 [ 1 ] ) ;
VectorSubtract ( quad [ 2 ] , quad [ 1 ] , m0 [ 2 ] ) ;
len [ 0 ] = DotProduct ( m0 [ 0 ] , m0 [ 0 ] ) ;
len [ 1 ] = DotProduct ( m0 [ 1 ] , m0 [ 1 ] ) ;
len [ 2 ] = DotProduct ( m0 [ 2 ] , m0 [ 2 ] ) ;
if ( ( len [ 2 ] > len [ 1 ] ) & & ( len [ 2 ] > len [ 0 ] ) )
{
if ( len [ 1 ] > len [ 0 ] )
{
long_axis = 1 ;
short_axis = 0 ;
}
else
{
long_axis = 0 ;
short_axis = 1 ;
}
}
else if ( ( len [ 1 ] > len [ 2 ] ) & & ( len [ 1 ] > len [ 0 ] ) )
{
if ( len [ 2 ] > len [ 0 ] )
{
long_axis = 2 ;
short_axis = 0 ;
}
else
{
long_axis = 0 ;
short_axis = 2 ;
}
}
else //if ( (len[0] > len[1]) && (len[0] > len[2]) )
{
if ( len [ 2 ] > len [ 1 ] )
{
long_axis = 2 ;
short_axis = 1 ;
}
else
{
long_axis = 1 ;
short_axis = 2 ;
}
}
if ( DotProduct ( m0 [ long_axis ] , m0 [ short_axis ] ) )
{
VectorNormalize2 ( m0 [ long_axis ] , axis ) ;
VectorCopy ( axis , m0 [ 1 ] ) ;
if ( axis [ 0 ] | | axis [ 1 ] )
{
VectorVectors ( m0 [ 1 ] , m0 [ 2 ] , m0 [ 0 ] ) ;
}
else
{
VectorVectors ( m0 [ 1 ] , m0 [ 0 ] , m0 [ 2 ] ) ;
}
}
else
{
VectorNormalize2 ( m0 [ long_axis ] , axis ) ;
VectorNormalize2 ( m0 [ short_axis ] , m0 [ 0 ] ) ;
VectorCopy ( axis , m0 [ 1 ] ) ;
CrossProduct ( m0 [ 0 ] , m0 [ 1 ] , m0 [ 2 ] ) ;
}
for ( j = 0 ; j < 3 ; j + + )
rot_centre [ j ] = ( quad [ 0 ] [ j ] + quad [ 1 ] [ j ] + quad [ 2 ] [ j ] + quad [ 3 ] [ j ] ) * 0.25 ;
if ( shaderstate . curentity )
{
VectorAdd ( shaderstate . curentity - > origin , rot_centre , tv ) ;
}
else
{
VectorCopy ( rot_centre , tv ) ;
}
VectorSubtract ( r_origin , tv , tv ) ;
// filter any longest-axis-parts off the camera-direction
deflect = - DotProduct ( tv , axis ) ;
VectorMA ( tv , deflect , axis , m1 [ 2 ] ) ;
VectorNormalizeFast ( m1 [ 2 ] ) ;
VectorCopy ( axis , m1 [ 1 ] ) ;
CrossProduct ( m1 [ 1 ] , m1 [ 2 ] , m1 [ 0 ] ) ;
Matrix3_Transpose ( m1 , m2 ) ;
Matrix3_Multiply ( m2 , m0 , result ) ;
for ( j = 0 ; j < 4 ; j + + )
{
2018-01-22 19:18:04 +00:00
int v = ( ( vecV_t * ) quad [ j ] - src ) ;
2009-11-04 21:16:50 +00:00
VectorSubtract ( quad [ j ] , rot_centre , tv ) ;
2018-01-22 19:18:04 +00:00
Matrix3_Multiply_Vec3 ( ( const vec3_t * ) result , tv , tv2 ) ;
VectorAdd ( rot_centre , tv2 , dst [ v ] ) ;
2009-11-04 21:16:50 +00:00
}
}
break ;
// case DEFORMV_PROJECTION_SHADOW:
// break;
2018-01-22 19:18:04 +00:00
case DEFORMV_TEXT :
DeformGen_Text ( deformv - > args [ 0 ] , cnt , src , dst , mesh ) ;
break ;
2009-11-04 21:16:50 +00:00
}
}
2012-05-09 15:30:53 +00:00
static void GenerateVertexBlends ( const shader_t * shader )
{
int i , m ;
mesh_t * meshlist ;
vecV_t * ov , * iv1 , * iv2 ;
float w1 , w2 ;
for ( m = 0 ; m < shaderstate . meshcount ; m + + )
{
meshlist = shaderstate . meshes [ m ] ;
ov = vertexarray + meshlist - > vbofirstvert ;
iv1 = meshlist - > xyz_array ;
iv2 = meshlist - > xyz2_array ;
w1 = meshlist - > xyz_blendw [ 0 ] ;
w2 = meshlist - > xyz_blendw [ 1 ] ;
for ( i = 0 ; i < meshlist - > numvertexes ; i + + )
{
ov [ i ] [ 0 ] = iv1 [ i ] [ 0 ] * w1 + iv2 [ i ] [ 0 ] * w2 ;
ov [ i ] [ 1 ] = iv1 [ i ] [ 1 ] * w1 + iv2 [ i ] [ 1 ] * w2 ;
ov [ i ] [ 2 ] = iv1 [ i ] [ 2 ] * w1 + iv2 [ i ] [ 2 ] * w2 ;
}
for ( i = 0 ; i < shader - > numdeforms ; i + + )
{
deformgen ( & shader - > deforms [ i ] , meshlist - > numvertexes , vertexarray + meshlist - > vbofirstvert , vertexarray + meshlist - > vbofirstvert , meshlist ) ;
}
}
shaderstate . pendingvertexpointer = vertexarray ;
shaderstate . pendingvertexvbo = 0 ;
}
2010-07-11 02:22:39 +00:00
static void GenerateVertexDeforms ( const shader_t * shader )
2009-11-04 21:16:50 +00:00
{
2010-07-11 02:22:39 +00:00
int i , m ;
mesh_t * meshlist ;
for ( m = 0 ; m < shaderstate . meshcount ; m + + )
2009-11-04 21:16:50 +00:00
{
2010-07-11 02:22:39 +00:00
meshlist = shaderstate . meshes [ m ] ;
2004-10-19 16:10:14 +00:00
2009-11-04 21:16:50 +00:00
deformgen ( & shader - > deforms [ 0 ] , meshlist - > numvertexes , meshlist - > xyz_array , vertexarray + meshlist - > vbofirstvert , meshlist ) ;
for ( i = 1 ; i < shader - > numdeforms ; i + + )
{
deformgen ( & shader - > deforms [ i ] , meshlist - > numvertexes , vertexarray + meshlist - > vbofirstvert , vertexarray + meshlist - > vbofirstvert , meshlist ) ;
}
}
shaderstate . pendingvertexpointer = vertexarray ;
shaderstate . pendingvertexvbo = 0 ;
}
2015-08-28 03:13:45 +00:00
# if 1 //ndef GLSLONLY
2015-08-25 03:02:19 +00:00
2009-11-04 21:16:50 +00:00
/*======================================alpha ===============================*/
2011-01-29 21:01:40 +00:00
static void alphagen ( const shaderpass_t * pass , int cnt , avec4_t * const src , avec4_t * dst , const mesh_t * mesh )
2009-11-04 21:16:50 +00:00
{
float * table ;
float t ;
float f ;
vec3_t v1 , v2 ;
int i ;
switch ( pass - > alphagen )
{
default :
case ALPHA_GEN_IDENTITY :
2010-07-11 02:22:39 +00:00
if ( shaderstate . flags & BEF_FORCETRANSPARENT )
2004-10-19 16:10:14 +00:00
{
2010-07-11 02:22:39 +00:00
while ( cnt - - )
dst [ cnt ] [ 3 ] = shaderstate . curentity - > shaderRGBAf [ 3 ] ;
}
else
{
while ( cnt - - )
dst [ cnt ] [ 3 ] = 1 ;
2004-10-19 16:10:14 +00:00
}
2009-11-04 21:16:50 +00:00
break ;
case ALPHA_GEN_CONST :
t = pass - > alphagen_func . args [ 0 ] ;
while ( cnt - - )
dst [ cnt ] [ 3 ] = t ;
break ;
case ALPHA_GEN_WAVE :
table = FTableForFunc ( pass - > alphagen_func . type ) ;
f = pass - > alphagen_func . args [ 2 ] + shaderstate . curtime * pass - > alphagen_func . args [ 3 ] ;
f = FTABLE_EVALUATE ( table , f ) * pass - > alphagen_func . args [ 1 ] + pass - > alphagen_func . args [ 0 ] ;
t = bound ( 0.0f , f , 1.0f ) ;
while ( cnt - - )
dst [ cnt ] [ 3 ] = t ;
break ;
case ALPHA_GEN_PORTAL :
//FIXME: should this be per-vert?
2010-07-11 02:22:39 +00:00
if ( r_refdef . recurse )
f = 1 ;
2004-10-19 16:10:14 +00:00
else
{
2010-07-11 02:22:39 +00:00
VectorAdd ( mesh - > xyz_array [ 0 ] , shaderstate . curentity - > origin , v1 ) ;
VectorSubtract ( r_origin , v1 , v2 ) ;
f = VectorLength ( v2 ) * ( 1.0 / shaderstate . curshader - > portaldist ) ;
f = bound ( 0.0f , f , 1.0f ) ;
}
2009-11-04 21:16:50 +00:00
while ( cnt - - )
dst [ cnt ] [ 3 ] = f ;
break ;
case ALPHA_GEN_VERTEX :
if ( ! src )
{
while ( cnt - - )
{
dst [ cnt ] [ 3 ] = 1 ;
}
break ;
}
while ( cnt - - )
{
dst [ cnt ] [ 3 ] = src [ cnt ] [ 3 ] ;
}
break ;
case ALPHA_GEN_ENTITY :
f = bound ( 0 , shaderstate . curentity - > shaderRGBAf [ 3 ] , 1 ) ;
while ( cnt - - )
{
dst [ cnt ] [ 3 ] = f ;
}
break ;
case ALPHA_GEN_SPECULAR :
2016-07-12 00:40:13 +00:00
if ( ! mesh - > normals_array )
{
while ( cnt - - )
dst [ cnt ] [ 3 ] = 0.2 ;
}
else
2011-05-29 04:26:29 +00:00
{
2009-11-04 21:16:50 +00:00
VectorSubtract ( r_origin , shaderstate . curentity - > origin , v1 ) ;
2016-02-15 06:01:17 +00:00
if ( ! Matrix3_Compare ( ( const vec3_t * ) shaderstate . curentity - > axis , ( const vec3_t * ) axisDefault ) )
2009-11-04 21:16:50 +00:00
{
2015-09-01 04:45:15 +00:00
Matrix3_Multiply_Vec3 ( shaderstate . curentity - > axis , v1 , v2 ) ;
2009-11-04 21:16:50 +00:00
}
else
{
VectorCopy ( v1 , v2 ) ;
}
for ( i = 0 ; i < cnt ; i + + )
{
VectorSubtract ( v2 , mesh - > xyz_array [ i ] , v1 ) ;
f = DotProduct ( v1 , mesh - > normals_array [ i ] ) * Q_rsqrt ( DotProduct ( v1 , v1 ) ) ;
f = f * f * f * f * f ;
dst [ i ] [ 3 ] = bound ( 0.0f , f , 1.0f ) ;
}
}
break ;
}
}
2010-07-11 02:22:39 +00:00
static void GenerateColourMods ( const shaderpass_t * pass )
2009-11-04 21:16:50 +00:00
{
2010-07-11 02:22:39 +00:00
unsigned int m ;
mesh_t * meshlist ;
meshlist = shaderstate . meshes [ 0 ] ;
2015-08-28 03:13:45 +00:00
if ( pass - > flags & SHADER_PASS_NOCOLORARRAY )
2009-11-04 21:16:50 +00:00
{
2013-08-27 13:18:09 +00:00
colourgen ( pass , 1 , meshlist - > colors4f_array [ 0 ] , & shaderstate . pendingcolourflat , meshlist ) ;
alphagen ( pass , 1 , meshlist - > colors4f_array [ 0 ] , & shaderstate . pendingcolourflat , meshlist ) ;
2015-08-28 03:13:45 +00:00
shaderstate . colourarraytype = 0 ;
2012-04-24 07:59:11 +00:00
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = NULL ;
2009-11-04 21:16:50 +00:00
}
else
{
extern cvar_t r_nolightdir ;
2017-12-09 21:22:46 +00:00
if ( pass - > rgbgen = = RGB_GEN_LIGHTING_DIFFUSE | | pass - > rgbgen = = RGB_GEN_ENTITY_LIGHTING_DIFFUSE )
2009-11-04 21:16:50 +00:00
{
2010-08-28 17:14:38 +00:00
if ( shaderstate . mode = = BEM_DEPTHDARK | | shaderstate . mode = = BEM_DEPTHONLY )
{
2012-04-24 07:59:11 +00:00
shaderstate . pendingcolourflat [ 0 ] = shaderstate . pendingcolourflat [ 1 ] = shaderstate . pendingcolourflat [ 2 ] = 0 ;
2013-08-27 13:18:09 +00:00
alphagen ( pass , 1 , meshlist - > colors4f_array [ 0 ] , & shaderstate . pendingcolourflat , meshlist ) ;
2015-08-28 03:13:45 +00:00
shaderstate . colourarraytype = 0 ;
2012-04-24 07:59:11 +00:00
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = NULL ;
2010-08-28 17:14:38 +00:00
return ;
}
if ( shaderstate . mode = = BEM_LIGHT )
{
2012-04-24 07:59:11 +00:00
shaderstate . pendingcolourflat [ 0 ] = shaderstate . pendingcolourflat [ 1 ] = shaderstate . pendingcolourflat [ 2 ] = 1 ;
2013-08-27 13:18:09 +00:00
alphagen ( pass , 1 , meshlist - > colors4f_array [ 0 ] , & shaderstate . pendingcolourflat , meshlist ) ;
2015-08-28 03:13:45 +00:00
shaderstate . colourarraytype = 0 ;
2012-04-24 07:59:11 +00:00
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = NULL ;
2010-08-28 17:14:38 +00:00
return ;
}
2018-01-03 04:40:06 +00:00
if ( r_nolightdir . ival | | ( ! shaderstate . curentity - > light_range [ 0 ] & & ! shaderstate . curentity - > light_range [ 1 ] & & ! shaderstate . curentity - > light_range [ 2 ] ) )
2010-08-28 17:14:38 +00:00
{
2012-04-24 07:59:11 +00:00
VectorCopy ( shaderstate . curentity - > light_avg , shaderstate . pendingcolourflat ) ;
2018-01-22 19:18:04 +00:00
alphagen ( pass , 1 , meshlist - > colors4f_array [ 0 ] , & shaderstate . pendingcolourflat , meshlist ) ;
2015-08-28 03:13:45 +00:00
shaderstate . colourarraytype = 0 ;
2012-04-24 07:59:11 +00:00
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = NULL ;
2010-08-28 17:14:38 +00:00
return ;
}
2009-11-04 21:16:50 +00:00
}
//if its vetex lighting, just use the vbo
2011-10-27 16:16:29 +00:00
if ( ( ( pass - > rgbgen = = RGB_GEN_VERTEX_LIGHTING & & shaderstate . identitylighting = = 1 ) | | pass - > rgbgen = = RGB_GEN_VERTEX_EXACT ) & & pass - > alphagen = = ALPHA_GEN_VERTEX )
2009-11-04 21:16:50 +00:00
{
2015-08-28 03:13:45 +00:00
shaderstate . colourarraytype = shaderstate . sourcevbo - > colours_bytes ? GL_UNSIGNED_BYTE : GL_FLOAT ;
2013-08-27 13:18:09 +00:00
shaderstate . pendingcolourvbo = shaderstate . sourcevbo - > colours [ 0 ] . gl . vbo ;
shaderstate . pendingcolourpointer = shaderstate . sourcevbo - > colours [ 0 ] . gl . addr ;
2009-11-04 21:16:50 +00:00
return ;
}
2010-07-11 02:22:39 +00:00
for ( m = 0 ; m < shaderstate . meshcount ; m + + )
2009-11-04 21:16:50 +00:00
{
2010-07-11 02:22:39 +00:00
meshlist = shaderstate . meshes [ m ] ;
2013-08-27 13:18:09 +00:00
colourgen ( pass , meshlist - > numvertexes , meshlist - > colors4f_array [ 0 ] , coloursarray + meshlist - > vbofirstvert , meshlist ) ;
alphagen ( pass , meshlist - > numvertexes , meshlist - > colors4f_array [ 0 ] , coloursarray + meshlist - > vbofirstvert , meshlist ) ;
2009-11-04 21:16:50 +00:00
}
2012-04-24 07:59:11 +00:00
2012-05-09 15:30:53 +00:00
shaderstate . colourarraytype = GL_FLOAT ;
2012-04-24 07:59:11 +00:00
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = coloursarray ;
2009-11-04 21:16:50 +00:00
}
}
2012-07-05 19:42:36 +00:00
static void BE_GeneratePassTC ( const shaderpass_t * pass , int tmu )
2009-11-04 21:16:50 +00:00
{
if ( ! pass - > numtcmods )
{
//if there are no tcmods, pass through here as fast as possible
2014-02-07 08:38:40 +00:00
switch ( pass - > tcgen )
2009-11-04 21:16:50 +00:00
{
2014-02-07 08:38:40 +00:00
case TC_GEN_BASE :
2012-11-27 03:23:19 +00:00
shaderstate . pendingtexcoordparts [ tmu ] = 2 ;
shaderstate . pendingtexcoordvbo [ tmu ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ tmu ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
2014-02-07 08:38:40 +00:00
break ;
case TC_GEN_LIGHTMAP :
2012-07-05 19:42:36 +00:00
if ( ! shaderstate . sourcevbo - > lmcoord [ 0 ] . gl . addr )
2011-05-20 04:10:46 +00:00
{
2012-11-27 03:23:19 +00:00
shaderstate . pendingtexcoordparts [ tmu ] = 2 ;
shaderstate . pendingtexcoordvbo [ tmu ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ tmu ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
2011-05-20 04:10:46 +00:00
}
else
{
2012-11-27 03:23:19 +00:00
shaderstate . pendingtexcoordparts [ tmu ] = 2 ;
shaderstate . pendingtexcoordvbo [ tmu ] = shaderstate . sourcevbo - > lmcoord [ 0 ] . gl . vbo ;
shaderstate . pendingtexcoordpointer [ tmu ] = shaderstate . sourcevbo - > lmcoord [ 0 ] . gl . addr ;
2011-05-20 04:10:46 +00:00
}
2014-02-07 08:38:40 +00:00
break ;
case TC_GEN_NORMAL :
2012-11-27 03:23:19 +00:00
shaderstate . pendingtexcoordparts [ tmu ] = 3 ;
shaderstate . pendingtexcoordvbo [ tmu ] = shaderstate . sourcevbo - > normals . gl . vbo ;
shaderstate . pendingtexcoordpointer [ tmu ] = shaderstate . sourcevbo - > normals . gl . addr ;
2014-02-07 08:38:40 +00:00
break ;
case TC_GEN_SVECTOR :
2012-11-27 03:23:19 +00:00
shaderstate . pendingtexcoordparts [ tmu ] = 3 ;
shaderstate . pendingtexcoordvbo [ tmu ] = shaderstate . sourcevbo - > svector . gl . vbo ;
shaderstate . pendingtexcoordpointer [ tmu ] = shaderstate . sourcevbo - > svector . gl . addr ;
2014-02-07 08:38:40 +00:00
break ;
case TC_GEN_TVECTOR :
2012-11-27 03:23:19 +00:00
shaderstate . pendingtexcoordparts [ tmu ] = 3 ;
shaderstate . pendingtexcoordvbo [ tmu ] = shaderstate . sourcevbo - > tvector . gl . vbo ;
shaderstate . pendingtexcoordpointer [ tmu ] = shaderstate . sourcevbo - > tvector . gl . addr ;
2014-02-07 08:38:40 +00:00
break ;
2017-08-29 02:29:06 +00:00
case TC_GEN_SKYBOX :
GenerateTCMods3 ( pass , tmu ) ;
break ;
2014-02-07 08:38:40 +00:00
//position - viewpos
// case TC_GEN_WOBBLESKY:
// case TC_GEN_REFLECT:
default :
2009-11-04 21:16:50 +00:00
//specular highlights and reflections have no fixed data, and must be generated.
2012-07-05 19:42:36 +00:00
GenerateTCMods ( pass , tmu ) ;
2014-02-07 08:38:40 +00:00
break ;
2009-11-04 21:16:50 +00:00
}
}
else
{
2012-07-05 19:42:36 +00:00
GenerateTCMods ( pass , tmu ) ;
2009-11-04 21:16:50 +00:00
}
}
2014-08-25 07:35:41 +00:00
# endif
2009-11-04 21:16:50 +00:00
2011-02-25 04:22:14 +00:00
static void BE_SendPassBlendDepthMask ( unsigned int sbits )
2009-11-04 21:16:50 +00:00
{
unsigned int delta ;
/*2d mode doesn't depth test or depth write*/
2012-07-05 19:42:36 +00:00
if ( shaderstate . force2d )
{
2011-10-27 16:16:29 +00:00
# ifdef warningmsg
# pragma warningmsg("fixme: q3 doesn't seem to have this, why do we need it?")
2011-05-29 04:26:29 +00:00
# endif
2018-04-27 16:40:50 +00:00
sbits & = ~ ( SBITS_MISC_DEPTHWRITE | SBITS_DEPTHFUNC_BITS ) ;
2009-11-04 21:16:50 +00:00
sbits | = SBITS_MISC_NODEPTHTEST ;
}
2011-04-23 20:37:20 +00:00
if ( shaderstate . flags & ( BEF_FORCEADDITIVE | BEF_FORCETRANSPARENT | BEF_FORCENODEPTH | BEF_FORCEDEPTHTEST | BEF_FORCEDEPTHWRITE ) )
2010-03-14 14:35:56 +00:00
{
2010-07-18 08:42:59 +00:00
if ( shaderstate . flags & BEF_FORCEADDITIVE )
sbits = ( sbits & ~ ( SBITS_MISC_DEPTHWRITE | SBITS_BLEND_BITS | SBITS_ATEST_BITS ) )
2011-04-23 20:37:20 +00:00
| ( SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE ) ;
else if ( shaderstate . flags & BEF_FORCETRANSPARENT )
{
2016-07-12 00:40:13 +00:00
if ( ( sbits & SBITS_BLEND_BITS ) = = ( SBITS_SRCBLEND_ONE | SBITS_DSTBLEND_ZERO ) | | ! ( sbits & SBITS_BLEND_BITS ) | | ( sbits & SBITS_ATEST_GE128 ) ) /*if transparency is forced, clear alpha test bits*/
2012-09-30 05:52:03 +00:00
sbits = ( sbits & ~ ( SBITS_BLEND_BITS | SBITS_ATEST_BITS ) )
2013-03-12 23:09:25 +00:00
| ( SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | SBITS_ATEST_GT0 ) ;
2011-04-23 20:37:20 +00:00
}
2010-03-14 14:35:56 +00:00
if ( shaderstate . flags & BEF_FORCENODEPTH ) /*EF_NODEPTHTEST dp extension*/
sbits | = SBITS_MISC_NODEPTHTEST ;
else
{
2010-05-01 22:47:47 +00:00
if ( shaderstate . flags & BEF_FORCEDEPTHTEST )
2010-03-14 14:35:56 +00:00
sbits & = ~ SBITS_MISC_NODEPTHTEST ;
2010-05-01 22:47:47 +00:00
if ( shaderstate . flags & BEF_FORCEDEPTHWRITE )
2010-03-14 14:35:56 +00:00
sbits | = SBITS_MISC_DEPTHWRITE ;
}
}
2009-11-04 21:16:50 +00:00
delta = sbits ^ shaderstate . shaderbits ;
2010-02-06 01:25:04 +00:00
# ifdef FORCESTATE
delta | = ~ 0 ;
# endif
2009-11-04 21:16:50 +00:00
if ( ! delta )
return ;
shaderstate . shaderbits = sbits ;
if ( delta & SBITS_BLEND_BITS )
{
if ( sbits & SBITS_BLEND_BITS )
{
int src , dst ;
/*unpack the src and dst factors*/
switch ( sbits & SBITS_SRCBLEND_BITS )
{
case SBITS_SRCBLEND_ZERO : src = GL_ZERO ; break ;
2010-04-09 10:49:04 +00:00
default :
2009-11-04 21:16:50 +00:00
case SBITS_SRCBLEND_ONE : src = GL_ONE ; break ;
case SBITS_SRCBLEND_DST_COLOR : src = GL_DST_COLOR ; break ;
case SBITS_SRCBLEND_ONE_MINUS_DST_COLOR : src = GL_ONE_MINUS_DST_COLOR ; break ;
case SBITS_SRCBLEND_SRC_ALPHA : src = GL_SRC_ALPHA ; break ;
case SBITS_SRCBLEND_ONE_MINUS_SRC_ALPHA : src = GL_ONE_MINUS_SRC_ALPHA ; break ;
case SBITS_SRCBLEND_DST_ALPHA : src = GL_DST_ALPHA ; break ;
case SBITS_SRCBLEND_ONE_MINUS_DST_ALPHA : src = GL_ONE_MINUS_DST_ALPHA ; break ;
case SBITS_SRCBLEND_ALPHA_SATURATE : src = GL_SRC_ALPHA_SATURATE ; break ;
}
2012-07-05 19:42:36 +00:00
switch ( ( sbits & SBITS_DSTBLEND_BITS ) > > 4 )
2009-11-04 21:16:50 +00:00
{
2012-07-05 19:42:36 +00:00
case SBITS_DSTBLEND_ZERO > > 4 : dst = GL_ZERO ; break ;
2010-04-09 10:49:04 +00:00
default :
2012-07-05 19:42:36 +00:00
case SBITS_DSTBLEND_ONE > > 4 : dst = GL_ONE ; break ;
case SBITS_DSTBLEND_SRC_COLOR > > 4 : dst = GL_SRC_COLOR ; break ;
case SBITS_DSTBLEND_ONE_MINUS_SRC_COLOR > > 4 : dst = GL_ONE_MINUS_SRC_COLOR ; break ;
case SBITS_DSTBLEND_SRC_ALPHA > > 4 : dst = GL_SRC_ALPHA ; break ;
case SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA > > 4 : dst = GL_ONE_MINUS_SRC_ALPHA ; break ;
case SBITS_DSTBLEND_DST_ALPHA > > 4 : dst = GL_DST_ALPHA ; break ;
case SBITS_DSTBLEND_ONE_MINUS_DST_ALPHA > > 4 : dst = GL_ONE_MINUS_DST_ALPHA ; break ;
2009-11-04 21:16:50 +00:00
}
qglEnable ( GL_BLEND ) ;
qglBlendFunc ( src , dst ) ;
}
else
qglDisable ( GL_BLEND ) ;
}
2012-04-09 19:12:12 +00:00
# ifdef GL_ALPHA_TEST //alpha test doesn't exist in gles2
2014-08-25 07:35:41 +00:00
if ( ( delta & SBITS_ATEST_BITS ) & & ! gl_config_nofixedfunc )
2009-11-04 21:16:50 +00:00
{
switch ( sbits & SBITS_ATEST_BITS )
{
default :
qglDisable ( GL_ALPHA_TEST ) ;
break ;
case SBITS_ATEST_GT0 :
qglEnable ( GL_ALPHA_TEST ) ;
qglAlphaFunc ( GL_GREATER , 0 ) ;
2010-03-14 14:35:56 +00:00
break ;
2009-11-04 21:16:50 +00:00
case SBITS_ATEST_LT128 :
qglEnable ( GL_ALPHA_TEST ) ;
qglAlphaFunc ( GL_LESS , 0.5f ) ;
break ;
case SBITS_ATEST_GE128 :
qglEnable ( GL_ALPHA_TEST ) ;
qglAlphaFunc ( GL_GEQUAL , 0.5f ) ;
break ;
}
}
2012-04-09 19:12:12 +00:00
# endif
2009-11-04 21:16:50 +00:00
if ( delta & SBITS_MISC_NODEPTHTEST )
{
if ( sbits & SBITS_MISC_NODEPTHTEST )
qglDisable ( GL_DEPTH_TEST ) ;
else
qglEnable ( GL_DEPTH_TEST ) ;
}
2010-03-14 14:35:56 +00:00
if ( delta & SBITS_MISC_DEPTHWRITE )
{
if ( sbits & SBITS_MISC_DEPTHWRITE )
qglDepthMask ( GL_TRUE ) ;
else
qglDepthMask ( GL_FALSE ) ;
}
2018-04-27 16:40:50 +00:00
if ( delta & ( SBITS_DEPTHFUNC_BITS ) )
2009-11-04 21:16:50 +00:00
{
extern int gldepthfunc ;
2018-04-27 16:40:50 +00:00
switch ( sbits & SBITS_DEPTHFUNC_BITS )
2009-11-04 21:16:50 +00:00
{
2018-04-27 16:40:50 +00:00
case SBITS_DEPTHFUNC_EQUAL :
2009-11-04 21:16:50 +00:00
qglDepthFunc ( GL_EQUAL ) ;
break ;
2018-04-27 16:40:50 +00:00
case SBITS_DEPTHFUNC_FURTHER :
2016-07-12 00:40:13 +00:00
if ( gldepthfunc = = GL_LEQUAL )
qglDepthFunc ( GL_GREATER ) ;
else
qglDepthFunc ( GL_LESS ) ;
break ;
2018-04-27 16:40:50 +00:00
case SBITS_DEPTHFUNC_CLOSER :
2009-11-04 21:16:50 +00:00
if ( gldepthfunc = = GL_LEQUAL )
qglDepthFunc ( GL_LESS ) ;
else
qglDepthFunc ( GL_GREATER ) ;
break ;
default :
2018-04-27 16:40:50 +00:00
case SBITS_DEPTHFUNC_CLOSEREQUAL :
2009-11-04 21:16:50 +00:00
qglDepthFunc ( gldepthfunc ) ;
break ;
}
}
2011-02-25 04:22:14 +00:00
if ( delta & ( SBITS_MASK_BITS ) )
{
qglColorMask (
( sbits & SBITS_MASK_RED ) ? GL_FALSE : GL_TRUE ,
( sbits & SBITS_MASK_GREEN ) ? GL_FALSE : GL_TRUE ,
( sbits & SBITS_MASK_BLUE ) ? GL_FALSE : GL_TRUE ,
( sbits & SBITS_MASK_ALPHA ) ? GL_FALSE : GL_TRUE
) ;
}
2017-02-11 16:14:06 +00:00
if ( ( delta & SBITS_TESSELLATION ) & & qglPNTrianglesiATI )
2012-04-09 19:12:12 +00:00
{
2017-02-11 16:14:06 +00:00
if ( ( sbits & SBITS_TESSELLATION ) & & r_tessellation . ival )
2012-04-09 19:12:12 +00:00
qglEnable ( GL_PN_TRIANGLES_ATI ) ;
else
qglDisable ( GL_PN_TRIANGLES_ATI ) ;
}
2014-03-30 08:55:06 +00:00
2014-08-15 02:20:41 +00:00
# ifdef GL_PERSPECTIVE_CORRECTION_HINT
if ( ( delta & SBITS_AFFINE ) & & qglHint )
2014-03-30 08:55:06 +00:00
{
2014-08-25 07:35:41 +00:00
if ( ! qglHint | | ( gl_config_gles & & gl_config . glversion > = 2 ) | | ( ! gl_config_gles & & gl_config_nofixedfunc ) )
2014-08-15 02:20:41 +00:00
; //doesn't exist in gles2 nor gl3+core contexts
else if ( sbits & SBITS_AFFINE )
2014-03-30 08:55:06 +00:00
qglHint ( GL_PERSPECTIVE_CORRECTION_HINT , GL_FASTEST ) ;
else
qglHint ( GL_PERSPECTIVE_CORRECTION_HINT , GL_NICEST ) ;
}
2014-08-15 02:20:41 +00:00
# endif
2009-11-04 21:16:50 +00:00
}
2014-11-05 05:39:24 +00:00
static void BE_SubmitMeshChain ( qboolean usetesselation )
2009-11-04 21:16:50 +00:00
{
int startv , starti , endv , endi ;
2010-07-11 02:22:39 +00:00
int m ;
mesh_t * mesh ;
2014-11-05 05:39:24 +00:00
int batchtype ;
if ( usetesselation )
{
m = ( shaderstate . flags & BEF_LINES ) ? 2 : 3 ;
if ( shaderstate . curpatchverts ! = m )
{
shaderstate . curpatchverts = m ;
2014-11-05 05:54:29 +00:00
qglPatchParameteriARB ( GL_PATCH_VERTICES_ARB , m ) ;
2014-11-05 05:39:24 +00:00
}
batchtype = GL_PATCHES_ARB ;
}
else
batchtype = ( shaderstate . flags & BEF_LINES ) ? GL_LINES : GL_TRIANGLES ;
2010-07-18 12:52:24 +00:00
2014-06-04 16:08:30 +00:00
if ( ! shaderstate . streamvbo [ 0 ] ) //only if we're not forcing vbos elsewhere.
2010-10-02 02:25:39 +00:00
{
2014-06-04 16:08:30 +00:00
//q3map2 sucks. it splits static meshes randomly rather than with any pvs consistancy, and then splays them out over 1000 different surfaces.
//this means we end up needing a boatload of draw calls whenever the batch got split.
//so skip all that and splurge out a usable index list on demand.
if ( shaderstate . meshcount = = 1 )
2010-10-02 02:25:39 +00:00
{
2014-06-04 16:08:30 +00:00
GL_SelectEBO ( shaderstate . sourcevbo - > indicies . gl . vbo ) ;
mesh = shaderstate . meshes [ 0 ] ;
qglDrawRangeElements ( batchtype , mesh - > vbofirstvert , mesh - > vbofirstvert + mesh - > numvertexes , mesh - > numindexes , GL_INDEX_TYPE , ( index_t * ) shaderstate . sourcevbo - > indicies . gl . addr + mesh - > vbofirstelement ) ;
RQuantAdd ( RQUANT_DRAWS , 1 ) ;
2015-03-03 00:14:43 +00:00
RQuantAdd ( RQUANT_PRIMITIVEINDICIES , mesh - > numindexes ) ;
2014-06-04 16:08:30 +00:00
return ;
2010-10-02 02:25:39 +00:00
}
2014-06-04 16:08:30 +00:00
else
2010-10-02 02:25:39 +00:00
{
2014-06-04 16:08:30 +00:00
index_t * fte_restrict ilst ; //FIXME: this should be cached for multiple-pass shaders.
GL_SelectEBO ( 0 ) ;
2018-03-04 14:41:16 +00:00
//FIXME: use a coherant persistently mapped buffer.
2014-06-04 16:08:30 +00:00
mesh = shaderstate . meshes [ 0 ] ;
startv = mesh - > vbofirstvert ;
endv = startv + mesh - > numvertexes ;
endi = mesh - > numindexes ;
for ( m = 1 ; m < shaderstate . meshcount ; m + + )
{
mesh = shaderstate . meshes [ m ] ;
endi + = mesh - > numindexes ;
2010-10-02 02:25:39 +00:00
2014-06-04 16:08:30 +00:00
if ( startv > mesh - > vbofirstvert )
startv = mesh - > vbofirstvert ;
if ( endv < mesh - > vbofirstvert + mesh - > numvertexes )
endv = mesh - > vbofirstvert + mesh - > numvertexes ;
}
2010-10-02 02:25:39 +00:00
2014-06-04 16:08:30 +00:00
ilst = alloca ( endi * sizeof ( index_t ) ) ;
endi = 0 ;
for ( m = 0 ; m < shaderstate . meshcount ; m + + )
{
mesh = shaderstate . meshes [ m ] ;
for ( starti = 0 ; starti < mesh - > numindexes ; )
ilst [ endi + + ] = mesh - > vbofirstvert + mesh - > indexes [ starti + + ] ;
}
qglDrawRangeElements ( batchtype , startv , endv , endi , GL_INDEX_TYPE , ilst ) ;
RQuantAdd ( RQUANT_DRAWS , 1 ) ;
2015-03-03 00:14:43 +00:00
RQuantAdd ( RQUANT_PRIMITIVEINDICIES , endi ) ;
2014-06-04 16:08:30 +00:00
}
return ;
2010-10-02 02:25:39 +00:00
}
2019-01-13 16:51:50 +00:00
else if ( qglMultiDrawElements )
{ //if we're drawing via a VBO then we don't really need DrawRangeElements any more.
//and avoiding so many calls into the driver also gives the driver a chance to optimise the draws instead of constantly checking if anything changed.
static GLsizei counts [ 1024 ] ;
static const GLvoid * indicies [ countof ( counts ) ] ;
GLsizei drawcount = 0 ;
GL_SelectEBO ( shaderstate . sourcevbo - > indicies . gl . vbo ) ;
for ( m = 0 , mesh = shaderstate . meshes [ 0 ] ; m < shaderstate . meshcount ; )
{
startv = mesh - > vbofirstvert ;
starti = mesh - > vbofirstelement ;
endv = startv + mesh - > numvertexes ;
endi = starti + mesh - > numindexes ;
//find consecutive surfaces
for ( + + m ; m < shaderstate . meshcount ; m + + )
{
mesh = shaderstate . meshes [ m ] ;
if ( endi = = mesh - > vbofirstelement )
{
endv = mesh - > vbofirstvert + mesh - > numvertexes ;
endi = mesh - > vbofirstelement + mesh - > numindexes ;
}
else
{
break ;
}
}
if ( drawcount = = countof ( counts ) )
{
qglMultiDrawElements ( batchtype , counts , GL_INDEX_TYPE , indicies , drawcount ) ;
drawcount = 0 ;
}
counts [ drawcount ] = endi - starti ;
indicies [ drawcount ] = ( index_t * ) shaderstate . sourcevbo - > indicies . gl . addr + starti ;
drawcount + + ;
}
qglMultiDrawElements ( batchtype , counts , GL_INDEX_TYPE , indicies , drawcount ) ;
}
2014-06-04 16:08:30 +00:00
else
{
GL_SelectEBO ( shaderstate . sourcevbo - > indicies . gl . vbo ) ;
2010-10-02 02:25:39 +00:00
2010-07-18 12:52:24 +00:00
/*
2014-06-04 16:08:30 +00:00
if ( qglLockArraysEXT )
2010-07-18 08:42:59 +00:00
{
2014-06-04 16:08:30 +00:00
endv = 0 ;
startv = 0x7fffffff ;
for ( m = 0 ; m < shaderstate . meshcount ; m + + )
{
mesh = shaderstate . meshes [ m ] ;
starti = mesh - > vbofirstvert ;
if ( starti < startv )
startv = starti ;
endi = mesh - > vbofirstvert + mesh - > numvertexes ;
if ( endi > endv )
endv = endi ;
}
qglLockArraysEXT ( startv , endv ) ;
2010-07-18 08:42:59 +00:00
}
2010-07-18 12:52:24 +00:00
*/
2012-04-24 07:59:11 +00:00
2014-06-04 16:08:30 +00:00
for ( m = 0 , mesh = shaderstate . meshes [ 0 ] ; m < shaderstate . meshcount ; )
{
startv = mesh - > vbofirstvert ;
starti = mesh - > vbofirstelement ;
2009-11-04 21:16:50 +00:00
2014-06-04 16:08:30 +00:00
endv = startv + mesh - > numvertexes ;
endi = starti + mesh - > numindexes ;
2009-11-04 21:16:50 +00:00
2014-06-04 16:08:30 +00:00
//find consecutive surfaces
for ( + + m ; m < shaderstate . meshcount ; m + + )
2009-11-04 21:16:50 +00:00
{
2014-06-04 16:08:30 +00:00
mesh = shaderstate . meshes [ m ] ;
if ( endi = = mesh - > vbofirstelement )
{
endv = mesh - > vbofirstvert + mesh - > numvertexes ;
endi = mesh - > vbofirstelement + mesh - > numindexes ;
}
else
{
break ;
}
2009-11-04 21:16:50 +00:00
}
2014-06-04 16:08:30 +00:00
qglDrawRangeElements ( batchtype , startv , endv , endi - starti , GL_INDEX_TYPE , ( index_t * ) shaderstate . sourcevbo - > indicies . gl . addr + starti ) ;
RQuantAdd ( RQUANT_DRAWS , 1 ) ;
2015-03-03 00:14:43 +00:00
RQuantAdd ( RQUANT_PRIMITIVEINDICIES , endi - starti ) ;
2014-06-04 16:08:30 +00:00
}
2010-07-18 12:52:24 +00:00
/*
2014-06-04 16:08:30 +00:00
if ( qglUnlockArraysEXT )
qglUnlockArraysEXT ( ) ;
2010-07-18 12:52:24 +00:00
*/
2014-06-04 16:08:30 +00:00
}
2009-11-04 21:16:50 +00:00
}
2014-08-25 07:35:41 +00:00
# ifndef GLSLONLY
2010-07-11 02:22:39 +00:00
static void DrawPass ( const shaderpass_t * pass )
2009-11-04 21:16:50 +00:00
{
2016-02-15 06:01:17 +00:00
int i ;
# if MAXRLIGHTMAPS > 1
int j , k ;
# endif
2009-11-04 21:16:50 +00:00
int tmu ;
int lastpass = pass - > numMergedPasses ;
2012-04-24 07:59:11 +00:00
unsigned int attr = ( 1u < < VATTR_LEG_VERTEX ) | ( 1u < < VATTR_LEG_COLOUR ) ;
2009-11-04 21:16:50 +00:00
for ( i = 0 ; i < lastpass ; i + + )
{
2014-10-05 20:04:11 +00:00
if ( pass [ i ] . texgen = = T_GEN_UPPEROVERLAY & & ! TEXLOADED ( shaderstate . curtexnums - > upperoverlay ) )
2009-11-04 21:16:50 +00:00
continue ;
2014-10-05 20:04:11 +00:00
if ( pass [ i ] . texgen = = T_GEN_LOWEROVERLAY & & ! TEXLOADED ( shaderstate . curtexnums - > loweroverlay ) )
2009-11-04 21:16:50 +00:00
continue ;
2014-10-05 20:04:11 +00:00
if ( pass [ i ] . texgen = = T_GEN_FULLBRIGHT & & ! TEXLOADED ( shaderstate . curtexnums - > fullbright ) )
2009-11-04 21:16:50 +00:00
continue ;
break ;
}
if ( i = = lastpass )
return ;
2011-02-25 04:22:14 +00:00
BE_SendPassBlendDepthMask ( pass [ i ] . shaderbits ) ;
2010-07-11 02:22:39 +00:00
GenerateColourMods ( pass + i ) ;
2009-11-04 21:16:50 +00:00
tmu = 0 ;
for ( ; i < lastpass ; i + + )
{
2014-10-05 20:04:11 +00:00
if ( pass [ i ] . texgen = = T_GEN_UPPEROVERLAY & & ! TEXLOADED ( shaderstate . curtexnums - > upperoverlay ) )
2009-11-04 21:16:50 +00:00
continue ;
2014-10-05 20:04:11 +00:00
if ( pass [ i ] . texgen = = T_GEN_LOWEROVERLAY & & ! TEXLOADED ( shaderstate . curtexnums - > loweroverlay ) )
2009-11-04 21:16:50 +00:00
continue ;
2014-10-05 20:04:11 +00:00
if ( pass [ i ] . texgen = = T_GEN_FULLBRIGHT & & ! TEXLOADED ( shaderstate . curtexnums - > fullbright ) )
2009-11-04 21:16:50 +00:00
continue ;
2012-04-24 07:59:11 +00:00
Shader_BindTextureForPass ( tmu , pass + i ) ;
attr | = ( 1u < < ( VATTR_LEG_TMU0 + tmu ) ) ;
2009-11-04 21:16:50 +00:00
2012-07-05 19:42:36 +00:00
BE_GeneratePassTC ( pass + i , tmu ) ;
2009-11-04 21:16:50 +00:00
2011-04-30 17:21:10 +00:00
BE_SetPassBlendMode ( tmu , pass [ i ] . blendmode ) ;
2012-07-05 19:42:36 +00:00
2009-11-04 21:16:50 +00:00
tmu + + ;
2012-07-05 19:42:36 +00:00
//add in
if ( pass [ i ] . texgen = = T_GEN_LIGHTMAP )
{
//first pass should have been REPLACE
//second pass should be an ADD
//this depends upon rgbgens for light levels, so each pass *must* be pushed to hardware individually
2015-07-14 14:47:00 +00:00
# if MAXRLIGHTMAPS > 1
2013-10-08 14:28:11 +00:00
for ( j = 1 ; j < MAXRLIGHTMAPS & & shaderstate . curbatch - > lightmap [ j ] > = 0 ; j + + )
2012-07-05 19:42:36 +00:00
{
if ( j = = 1 )
BE_SetPassBlendMode ( tmu , PBM_REPLACE ) ;
/*make sure no textures linger*/
for ( k = tmu ; k < shaderstate . lastpasstmus ; k + + )
{
GL_LazyBind ( k , 0 , r_nulltex ) ;
}
shaderstate . lastpasstmus = tmu ;
/*push it*/
2012-11-27 03:23:19 +00:00
BE_EnableShaderAttributes ( attr , 0 ) ;
2014-11-05 05:39:24 +00:00
BE_SubmitMeshChain ( false ) ;
2012-07-05 19:42:36 +00:00
tmu = 0 ;
/*bind the light texture*/
GL_LazyBind ( tmu , GL_TEXTURE_2D , lightmap [ shaderstate . curbatch - > lightmap [ j ] ] - > lightmap_texture ) ;
/*set up the colourmod for this style's lighting*/
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = NULL ;
2013-08-27 13:18:09 +00:00
shaderstate . pendingcolourflat [ 0 ] = shaderstate . identitylighting * d_lightstylevalue [ shaderstate . curbatch - > lmlightstyle [ j ] ] / 256.0f ;
shaderstate . pendingcolourflat [ 1 ] = shaderstate . identitylighting * d_lightstylevalue [ shaderstate . curbatch - > lmlightstyle [ j ] ] / 256.0f ;
shaderstate . pendingcolourflat [ 2 ] = shaderstate . identitylighting * d_lightstylevalue [ shaderstate . curbatch - > lmlightstyle [ j ] ] / 256.0f ;
2012-07-05 19:42:36 +00:00
shaderstate . pendingcolourflat [ 3 ] = 1 ;
/*pick the correct st coords for this lightmap pass*/
2012-11-27 03:23:19 +00:00
shaderstate . pendingtexcoordparts [ tmu ] = 2 ;
shaderstate . pendingtexcoordvbo [ tmu ] = shaderstate . sourcevbo - > lmcoord [ j ] . gl . vbo ;
shaderstate . pendingtexcoordpointer [ tmu ] = shaderstate . sourcevbo - > lmcoord [ j ] . gl . addr ;
2012-07-05 19:42:36 +00:00
BE_SetPassBlendMode ( tmu , PBM_ADD ) ;
BE_SendPassBlendDepthMask ( ( pass [ 0 ] . shaderbits & ~ SBITS_BLEND_BITS ) | SBITS_SRCBLEND_ONE | SBITS_DSTBLEND_ONE ) ;
attr = ( 1u < < VATTR_LEG_VERTEX ) | ( 1u < < VATTR_LEG_COLOUR ) ;
attr | = ( 1u < < ( VATTR_LEG_TMU0 + tmu ) ) ;
tmu + + ;
}
//might need to break the pass here
if ( j > 1 & & i ! = lastpass )
{
for ( k = tmu ; k < shaderstate . lastpasstmus ; k + + )
{
GL_LazyBind ( k , 0 , r_nulltex ) ;
}
shaderstate . lastpasstmus = tmu ;
2012-11-27 03:23:19 +00:00
BE_EnableShaderAttributes ( attr , 0 ) ;
2012-07-05 19:42:36 +00:00
2014-11-05 05:39:24 +00:00
BE_SubmitMeshChain ( false ) ;
2012-07-05 19:42:36 +00:00
tmu = 0 ;
BE_SendPassBlendDepthMask ( pass [ i + 1 ] . shaderbits ) ;
GenerateColourMods ( & pass [ i + 1 ] ) ;
}
Reworked client support for DPP5+. less code now, its much more graceful.
added waterfog command. waterfog overrides regular fog only when the view is in water.
fixed 64bit printf format specifiers. should work better on winxp64.
fixed some spec angle weirdness.
fixed viewsize 99.99 weirdness with ezhud.
fixed extra offset on the console (exhibited in 64bit builds, but not limited to).
fixed .avi playback, can now actually display frames again.
reimplemented line sparks.
fixed r_editlights_save flipping the light's pitch.
fixed issue with oggs failing to load.
fixed condump to cope with unicode properly.
made sv_bigcoords default except in quake. hexen2 kinda needs it for bsp angle precision.
fixed nq server to not stall weirdly on map changes.
fixed qwprogs svc_cdtrack not bugging out with nq clients on the server.
fixed restart command to load the last map run by the server, instead of start.bsp (when idle)
optimised d3d9 renderer a little. now uses less draw calls, especially with complex scenes. seems to get higher framerates than opengl now.
fixed d3d9 renderer to not bug out quite so much when run fullscreen (shader subsystem is now correctly initialised).
fixed a couple of bugs from font change. also now supports utf-8 in a few more places.
r_editlights_reload no longer generates rtlights inside the void. this resolves a few glitches (but should also help framerates a little).
fixed so corona-only lights won't generate shadowmaps and waste lots of time.
removed lots of #defines from qclib. I should never have made them in the first place, but I was lazy. obviously there's more left that I cba to remove yet.
fixed nested calls with variant-vectors. this fixes csaddon's light editor.
fixed qcc hc calling conventions using redundant stores.
disabled keywords can still be used by using __keyword instead.
fixed ftegccgui grep feature.
fixed motionless-dog qcc bug.
tweaked qcc warnings a little. -Wall is now a viable setting. you should be able to fix all those warnings.
fixed qw svc_intermission + dpp5+ clients bug.
fixed annoying spam about disconnecting in hexen2.
rewrote status command a little to cope with ipv6 addresses more gracefully
fixed significant stall when hibernating/debugging a server with a player sitting on it.
fixed truelightning.
fixed rocketlight overriding pflags.
fixed torches vanishing on vid_restart.
fixed issue with decal scaling.
fixed findentityfield builtin.
fixed fteqcc issue with ptr+1
fixed use of arrays inside class functions.
fixed/implemented fteqcc emulation of pointer opcodes.
added __inout keyword to fteqcc, so that it doesn't feel so horrendous.
fixed sizeof(*foo)
fixed *struct = struct;
fixed recursive structs.
fixed fteqcc warning report.
fixed sdl2 controller support, hopefully.
attempted to implement xinput, including per-player audio playback.
slightly fixed relaxed attitude to mouse focus when running fullscreen.
fixed weird warnings/errors with 'ent.arrayhead' terms. now generates sane errors.
implemented bindmaps (for csqc).
fixed crashing bug with eprint builtin.
implemented subset of music_playlist_* functionality. significant changes to music playback.
fixed some more dpcsqc compat.
fixed binds menu. now displays and accepts modifiers.
fixed issues with huge lightmaps.
fixed protocol determinism with dp clients connecting to fte servers. the initial getchallenge request now inhibits vanilla nq connection requests.
implemented support for 'dupe' userinfo key, allowing clients to request client->server packet duplication. should probably queue them tbh.
implemented sv_saveentfile command.
fixed resume after breaking inside a stepped-over function.
fixed erroneous footer after debugging.
(I wonder just how many things I broke with these fixes)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4946 fc73d0e0-1445-4013-8a0c-d673dee63da5
2015-07-26 10:56:18 +00:00
# endif
2012-07-05 19:42:36 +00:00
}
2009-11-04 21:16:50 +00:00
}
2012-07-05 19:42:36 +00:00
if ( ! tmu )
return ;
2009-11-04 21:16:50 +00:00
for ( i = tmu ; i < shaderstate . lastpasstmus ; i + + )
{
2012-04-24 07:59:11 +00:00
GL_LazyBind ( i , 0 , r_nulltex ) ;
2009-11-04 21:16:50 +00:00
}
shaderstate . lastpasstmus = tmu ;
2012-11-27 03:23:19 +00:00
BE_EnableShaderAttributes ( attr , 0 ) ;
2009-11-04 21:16:50 +00:00
2014-11-05 05:39:24 +00:00
BE_SubmitMeshChain ( false ) ;
2009-11-04 21:16:50 +00:00
}
2014-08-25 07:35:41 +00:00
# endif
2009-11-04 21:16:50 +00:00
2018-11-27 16:48:19 +00:00
static void BE_Program_Set_Attributes ( const program_t * prog , struct programpermu_s * perm , qboolean entunchanged )
2009-11-04 21:16:50 +00:00
{
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
vec4_t param4 ;
2015-03-03 00:14:43 +00:00
int r , g ; //, b;
2012-01-21 07:53:49 +00:00
int i ;
2012-11-27 03:23:19 +00:00
unsigned int ph ;
2012-01-21 07:53:49 +00:00
const shaderprogparm_t * p ;
2009-11-04 21:16:50 +00:00
2012-04-24 07:59:11 +00:00
/*don't bother setting it if the ent properties are unchanged (but do if the mesh changed)*/
if ( entunchanged )
return ;
2018-11-27 16:48:19 +00:00
p = perm - > parm ;
for ( i = perm - > numparms ; i > 0 ; i - - , p + + )
2009-11-04 21:16:50 +00:00
{
2015-08-07 17:49:49 +00:00
ph = p - > handle ;
2012-01-21 07:53:49 +00:00
switch ( p - > type )
2012-01-17 07:57:46 +00:00
{
2015-03-03 00:14:43 +00:00
/*
case SP_UBO_ENTITYINFO :
struct
{
vec2_t blendweights ;
vec2_t pad1 ;
vec3_t glowmod ;
vec_t pad2 ;
vec3_t origin ;
vec_t pad3 ;
vec4_t colormod ;
vec3_t glowmod ;
vec_t pad4 ;
vec3_t uppercolour ;
vec_t pad5 ;
vec3_t lowercolour ;
vec_t pad6 ;
vec3_t fogcolours ;
vec_t fogalpha ;
vec3_t vlightdir ;
vec_t fogdensity ;
vec3_t vlightmul ;
vec_t fogdepthbias ;
vec3_t vlightadd ;
vec_t time ;
} u_entityinfo ;
Vector2Copy ( shaderstate . meshes [ 0 ] - > xyz_blendw , u_entityinfo . blendweights ) ;
VectorCopy ( shaderstate . curentity - > glowmod , u_entityinfo . glowmod ) ;
VectorCopy ( shaderstate . curentity - > origin , u_entityinfo . origin ) ;
Vector4Copy ( shaderstate . curentity - > shaderRGBAf , u_entityinfo . colormod ) ;
R_FetchPlayerColour ( shaderstate . curentity - > topcolour , u_entityinfo . uppercolour ) ;
R_FetchPlayerColour ( shaderstate . curentity - > bottomcolour , u_entityinfo . lowercolour ) ;
Vector3Copy ( r_refdef . globalfog . colour , u_entityinfo . fogcolours ) ;
u_entityinfo . fogalpha = r_refdef . globalfog . alpha ;
u_entityinfo . fogdensity = r_refdef . globalfog . density ;
u_entityinfo . fogdepthbias = r_refdef . globalfog . depthbias ;
u_entityinfo . time = shaderstate . curtime ;
Vector3Copy ( shaderstate . curentity - > light_dir , u_entityinfo . vlightdir ) ;
Vector3Copy ( shaderstate . curentity - > light_range , u_entityinfo . vlightmul ) ;
Vector3Copy ( shaderstate . curentity - > light_avg , u_entityinfo . vlightadd ) ;
break ;
*/
/*
case SP_UBO_LIGHTINFO :
struct
{
vec3_t toscreen ;
vec_t lightradius ;
vec3_t lightcolours ;
vec_t pad1 ;
vec3_t lightcolourscale ;
vec_t pad2 ;
vec3_t lightorigin_modelspace ;
vec_t pad3 ;
matrix4x4_t lightcubematrix ;
vec4_t lightshadowmapproj ;
vec2_t lightshadowmapscale ;
vec2_t pad4 ;
} u_lightinfo ;
{
float v [ 4 ] , tempv [ 4 ] ;
v [ 0 ] = shaderstate . lightorg [ 0 ] ;
v [ 1 ] = shaderstate . lightorg [ 1 ] ;
v [ 2 ] = shaderstate . lightorg [ 2 ] ;
v [ 3 ] = 1 ;
Matrix4x4_CM_Transform4 ( shaderstate . modelviewmatrix , v , tempv ) ;
Matrix4x4_CM_Transform4 ( r_refdef . m_projection , tempv , v ) ;
v [ 3 ] * = 2 ;
u_lightinfo . toscreen [ 0 ] = ( v [ 0 ] / v [ 3 ] ) + 0.5 ;
u_lightinfo . toscreen [ 1 ] = ( v [ 1 ] / v [ 3 ] ) + 0.5 ;
u_lightinfo . toscreen [ 2 ] = ( v [ 2 ] / v [ 3 ] ) + 0.5 ;
}
u_lightinfo . lightradius = shaderstate . lightradius ;
Vector3Copy ( shaderstate . lightcolours , u_lightinfo . lightcolours ) ;
Matrix4x4_CM_Transform3 ( shaderstate . modelmatrixinv , shaderstate . lightorg , u_lightinfo . lightorigin_modelspace ) ;
Vector3Copy ( shaderstate . lightcolourscale , u_lightinfo . lightcolourscale ) ;
Matrix4_Multiply ( shaderstate . lightprojmatrix , shaderstate . modelmatrix , u_lightinfo . lightcubematrix ) ;
Vector4Copy ( shaderstate . lightshadowmapproj , u_lightinfo . lightshadowmapproj ) ;
Vector2Copy ( shaderstate . lightshadowmapscale , u_lightinfo . lightshadowmapscale ) ;
break ;
*/
2012-01-21 07:53:49 +00:00
case SP_M_VIEW :
2012-11-27 03:23:19 +00:00
qglUniformMatrix4fvARB ( ph , 1 , false , r_refdef . m_view ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_M_PROJECTION :
2017-12-15 06:56:40 +00:00
qglUniformMatrix4fvARB ( ph , 1 , false , shaderstate . projectionmatrix ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_M_MODELVIEW :
2012-11-27 03:23:19 +00:00
qglUniformMatrix4fvARB ( ph , 1 , false , shaderstate . modelviewmatrix ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_M_MODELVIEWPROJECTION :
{
float m16 [ 16 ] ;
2017-12-15 06:56:40 +00:00
Matrix4_Multiply ( shaderstate . projectionmatrix , shaderstate . modelviewmatrix , m16 ) ;
2012-11-27 03:23:19 +00:00
qglUniformMatrix4fvARB ( ph , 1 , false , m16 ) ;
2012-01-17 07:57:46 +00:00
}
2012-01-21 07:53:49 +00:00
break ;
case SP_M_INVMODELVIEWPROJECTION :
{
float m16 [ 16 ] , inv [ 16 ] ;
2017-12-15 06:56:40 +00:00
Matrix4_Multiply ( shaderstate . projectionmatrix , shaderstate . modelviewmatrix , m16 ) ;
2012-01-21 07:53:49 +00:00
Matrix4_Invert ( m16 , inv ) ;
2012-11-27 03:23:19 +00:00
qglUniformMatrix4fvARB ( ph , 1 , false , inv ) ;
2012-01-21 07:53:49 +00:00
}
break ;
case SP_M_MODEL :
2012-11-27 03:23:19 +00:00
qglUniformMatrix4fvARB ( ph , 1 , false , shaderstate . modelmatrix ) ;
2012-01-21 07:53:49 +00:00
break ;
2018-12-28 00:04:36 +00:00
case SP_M_ENTBONES_PACKED :
qglUniform4fvARB ( ph , shaderstate . sourcevbo - > numbones * 3 , shaderstate . sourcevbo - > bones ) ;
break ;
case SP_M_ENTBONES_MAT3X4 :
qglUniformMatrix3x4fv ( ph , shaderstate . sourcevbo - > numbones , false , shaderstate . sourcevbo - > bones ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_M_INVVIEWPROJECTION :
{
float m16 [ 16 ] , inv [ 16 ] ;
2017-12-15 06:56:40 +00:00
Matrix4_Multiply ( shaderstate . projectionmatrix , r_refdef . m_view , m16 ) ;
2012-01-21 07:53:49 +00:00
Matrix4_Invert ( m16 , inv ) ;
2012-11-27 03:23:19 +00:00
qglUniformMatrix4fvARB ( ph , 1 , false , inv ) ;
2012-01-21 07:53:49 +00:00
}
break ;
2012-01-17 07:57:46 +00:00
2012-04-24 07:59:11 +00:00
case SP_E_VBLEND :
2012-11-27 03:23:19 +00:00
qglUniform2fvARB ( ph , 1 , shaderstate . meshes [ 0 ] - > xyz_blendw ) ;
2012-04-24 07:59:11 +00:00
break ;
2013-08-27 13:18:09 +00:00
case SP_E_VLSCALE :
2013-10-08 14:28:11 +00:00
# if MAXRLIGHTMAPS > 1
2018-11-27 16:48:19 +00:00
if ( perm - > permutation & PERMUTATION_LIGHTSTYLES )
2013-08-27 13:18:09 +00:00
{
2013-10-08 14:28:11 +00:00
vec4_t colscale [ MAXRLIGHTMAPS ] ;
2013-08-27 13:18:09 +00:00
int j , s ;
2013-10-08 14:28:11 +00:00
for ( j = 0 ; j < MAXRLIGHTMAPS ; j + + )
2013-08-27 13:18:09 +00:00
{
s = shaderstate . curbatch - > vtlightstyle [ j ] ;
if ( s = = 255 )
{
2013-10-08 14:28:11 +00:00
for ( ; j < MAXRLIGHTMAPS ; j + + )
2013-08-27 13:18:09 +00:00
{
colscale [ j ] [ 0 ] = 0 ;
colscale [ j ] [ 1 ] = 0 ;
colscale [ j ] [ 2 ] = 0 ;
colscale [ j ] [ 3 ] = 1 ;
}
break ;
}
if ( shaderstate . curentity - > model & & shaderstate . curentity - > model - > engineflags & MDLF_NEEDOVERBRIGHT )
{
float sc = ( 1 < < bound ( 0 , gl_overbright . ival , 2 ) ) * shaderstate . identitylighting ;
VectorSet ( colscale [ j ] , sc , sc , sc ) ;
}
else
{
VectorSet ( colscale [ j ] , shaderstate . identitylighting , shaderstate . identitylighting , shaderstate . identitylighting ) ;
}
colscale [ j ] [ 3 ] = 1 ;
VectorScale ( colscale [ j ] , d_lightstylevalue [ s ] / 256.0f , colscale [ j ] ) ;
}
qglUniform4fvARB ( ph , j , ( GLfloat * ) colscale ) ;
shaderstate . lastuniform = 0 ;
}
2017-07-04 05:07:51 +00:00
else
2017-07-04 05:13:44 +00:00
# endif
2017-07-04 05:07:51 +00:00
{
vec4_t param4 ;
2018-01-22 19:18:04 +00:00
if ( shaderstate . curbatch - > flags & BEF_NODLIGHT )
{
Vector4Set ( param4 , 1 , 1 , 1 , 1 ) ;
}
else
{
Vector4Set ( param4 , shaderstate . identitylighting , shaderstate . identitylighting , shaderstate . identitylighting , 1 ) ;
}
2017-07-04 05:07:51 +00:00
qglUniform4fvARB ( ph , 1 , ( GLfloat * ) param4 ) ;
}
break ;
2012-01-21 07:53:49 +00:00
case SP_E_LMSCALE :
2013-10-08 14:28:11 +00:00
# if MAXRLIGHTMAPS > 1
2018-11-27 16:48:19 +00:00
if ( perm - > permutation & PERMUTATION_LIGHTSTYLES )
2012-01-21 07:53:49 +00:00
{
2013-10-08 14:28:11 +00:00
vec4_t colscale [ MAXRLIGHTMAPS ] ;
2012-07-07 05:17:43 +00:00
int j , s ;
2013-10-08 14:28:11 +00:00
for ( j = 0 ; j < MAXRLIGHTMAPS ; j + + )
2012-07-05 19:42:36 +00:00
{
2013-08-27 13:18:09 +00:00
s = shaderstate . curbatch - > lmlightstyle [ j ] ;
2012-07-07 05:17:43 +00:00
if ( s = = 255 )
{
2013-10-08 14:28:11 +00:00
for ( ; j < MAXRLIGHTMAPS ; j + + )
2012-07-07 05:17:43 +00:00
{
colscale [ j ] [ 0 ] = 0 ;
colscale [ j ] [ 1 ] = 0 ;
colscale [ j ] [ 2 ] = 0 ;
colscale [ j ] [ 3 ] = 1 ;
}
break ;
}
2016-07-12 00:40:13 +00:00
if ( shaderstate . curentity - > model & & ( shaderstate . curentity - > model - > engineflags & MDLF_NEEDOVERBRIGHT ) & & ! shaderstate . force2d )
2012-07-05 19:42:36 +00:00
{
float sc = ( 1 < < bound ( 0 , gl_overbright . ival , 2 ) ) * shaderstate . identitylighting ;
VectorSet ( colscale [ j ] , sc , sc , sc ) ;
}
else
{
VectorSet ( colscale [ j ] , shaderstate . identitylighting , shaderstate . identitylighting , shaderstate . identitylighting ) ;
}
colscale [ j ] [ 3 ] = 1 ;
2012-07-07 05:17:43 +00:00
VectorScale ( colscale [ j ] , d_lightstylevalue [ s ] / 256.0f , colscale [ j ] ) ;
2012-07-05 19:42:36 +00:00
}
2012-07-07 05:17:43 +00:00
2012-11-27 03:23:19 +00:00
qglUniform4fvARB ( ph , j , ( GLfloat * ) colscale ) ;
2012-07-07 05:17:43 +00:00
shaderstate . lastuniform = 0 ;
2012-07-05 19:42:36 +00:00
}
else
2013-10-08 14:28:11 +00:00
# endif
2012-07-05 19:42:36 +00:00
{
2016-07-12 00:40:13 +00:00
if ( shaderstate . curentity - > model & & ( shaderstate . curentity - > model - > engineflags & MDLF_NEEDOVERBRIGHT ) & & ! shaderstate . force2d )
2012-01-21 07:53:49 +00:00
{
2012-04-24 07:59:11 +00:00
float sc = ( 1 < < bound ( 0 , gl_overbright . ival , 2 ) ) * shaderstate . identitylighting ;
2017-07-04 05:07:51 +00:00
Vector4Set ( param4 , sc , sc , sc , 1 ) ;
2012-01-21 07:53:49 +00:00
}
2012-04-24 07:59:11 +00:00
else
{
2017-07-04 05:07:51 +00:00
Vector4Set ( param4 , shaderstate . identitylighting , shaderstate . identitylighting , shaderstate . identitylighting , 1 ) ;
2012-04-24 07:59:11 +00:00
}
2011-12-26 15:19:13 +00:00
2017-07-04 05:07:51 +00:00
qglUniform4fvARB ( ph , 1 , ( GLfloat * ) param4 ) ;
2012-01-21 07:53:49 +00:00
}
break ;
case SP_E_GLOWMOD :
2012-11-27 03:23:19 +00:00
qglUniform3fvARB ( ph , 1 , ( GLfloat * ) shaderstate . curentity - > glowmod ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_E_ORIGIN :
2012-11-27 03:23:19 +00:00
qglUniform3fvARB ( ph , 1 , ( GLfloat * ) shaderstate . curentity - > origin ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_E_COLOURS :
2012-11-27 03:23:19 +00:00
qglUniform4fvARB ( ph , 1 , ( GLfloat * ) shaderstate . curentity - > shaderRGBAf ) ;
2012-01-21 07:53:49 +00:00
break ;
2015-08-28 03:13:45 +00:00
case SP_S_COLOUR :
if ( shaderstate . colourarraytype )
qglUniform4fARB ( ph , 1 , 1 , 1 , 1 ) ; //invalid use
else
qglUniform4fvARB ( ph , 1 , ( GLfloat * ) shaderstate . pendingcolourflat ) ;
break ;
2012-01-21 07:53:49 +00:00
case SP_E_COLOURSIDENT :
if ( shaderstate . flags & BEF_FORCECOLOURMOD )
2012-11-27 03:23:19 +00:00
qglUniform4fvARB ( ph , 1 , ( GLfloat * ) shaderstate . curentity - > shaderRGBAf ) ;
2012-01-21 07:53:49 +00:00
else
2012-11-27 03:23:19 +00:00
qglUniform4fARB ( ph , 1 , 1 , 1 , shaderstate . curentity - > shaderRGBAf [ 3 ] ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_E_TOPCOLOURS :
2015-03-03 00:14:43 +00:00
R_FetchPlayerColour ( shaderstate . curentity - > topcolour , param4 ) ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
qglUniform3fvARB ( ph , 1 , param4 ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_E_BOTTOMCOLOURS :
2015-03-03 00:14:43 +00:00
R_FetchPlayerColour ( shaderstate . curentity - > bottomcolour , param4 ) ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
qglUniform3fvARB ( ph , 1 , param4 ) ;
2012-01-21 07:53:49 +00:00
break ;
2011-01-23 03:44:49 +00:00
2015-07-14 14:47:00 +00:00
case SP_SOURCESIZE :
if ( shaderstate . tex_sourcecol )
{
param4 [ 0 ] = shaderstate . tex_sourcecol - > width ;
param4 [ 1 ] = shaderstate . tex_sourcecol - > height ;
}
else if ( shaderstate . tex_sourcedepth )
{
param4 [ 0 ] = shaderstate . tex_sourcedepth - > width ;
param4 [ 1 ] = shaderstate . tex_sourcedepth - > height ;
}
else
{
param4 [ 0 ] = 1 ;
param4 [ 1 ] = 1 ;
}
qglUniform2fvARB ( ph , 1 , param4 ) ;
break ;
2012-01-21 07:53:49 +00:00
case SP_RENDERTEXTURESCALE :
2014-10-11 19:39:45 +00:00
if ( sh_config . texture_non_power_of_two_pic )
2012-01-21 07:53:49 +00:00
{
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
param4 [ 0 ] = 1 ;
param4 [ 1 ] = 1 ;
2012-01-21 07:53:49 +00:00
}
else
{
r = 1 ;
g = 1 ;
while ( r < vid . pixelwidth )
2015-03-03 00:14:43 +00:00
param4 [ 0 ] * = 2 ;
2012-01-21 07:53:49 +00:00
while ( g < vid . pixelheight )
2015-03-03 00:14:43 +00:00
param4 [ 1 ] * = 2 ;
param4 [ 0 ] = vid . pixelwidth / param4 [ 0 ] ;
param4 [ 1 ] = vid . pixelheight / param4 [ 1 ] ;
2012-01-21 07:53:49 +00:00
}
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
param4 [ 2 ] = 0 ;
param4 [ 3 ] = 0 ;
qglUniform4fvARB ( ph , 1 , param4 ) ;
2012-01-21 07:53:49 +00:00
break ;
2011-01-23 03:44:49 +00:00
2012-01-21 07:53:49 +00:00
case SP_LIGHTSCREEN :
{
float v [ 4 ] , tempv [ 4 ] ;
2011-12-05 15:23:40 +00:00
2012-01-21 07:53:49 +00:00
v [ 0 ] = shaderstate . lightorg [ 0 ] ;
v [ 1 ] = shaderstate . lightorg [ 1 ] ;
v [ 2 ] = shaderstate . lightorg [ 2 ] ;
v [ 3 ] = 1 ;
2011-12-05 15:23:40 +00:00
2012-01-21 07:53:49 +00:00
Matrix4x4_CM_Transform4 ( shaderstate . modelviewmatrix , v , tempv ) ;
2017-12-15 06:56:40 +00:00
Matrix4x4_CM_Transform4 ( shaderstate . projectionmatrix , tempv , v ) ;
2011-12-05 15:23:40 +00:00
2012-01-21 07:53:49 +00:00
v [ 3 ] * = 2 ;
v [ 0 ] = ( v [ 0 ] / v [ 3 ] ) + 0.5 ;
v [ 1 ] = ( v [ 1 ] / v [ 3 ] ) + 0.5 ;
v [ 2 ] = ( v [ 2 ] / v [ 3 ] ) + 0.5 ;
2011-12-05 15:23:40 +00:00
2012-11-27 03:23:19 +00:00
qglUniform3fvARB ( ph , 1 , v ) ;
2012-01-21 07:53:49 +00:00
}
break ;
case SP_LIGHTRADIUS :
2012-11-27 03:23:19 +00:00
qglUniform1fARB ( ph , shaderstate . lightradius ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_LIGHTCOLOUR :
2012-11-27 03:23:19 +00:00
qglUniform3fvARB ( ph , 1 , shaderstate . lightcolours ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_W_FOG :
2014-03-30 08:55:06 +00:00
qglUniform4fvARB ( ph , 2 , r_refdef . globalfog . colour ) ; //and density
2012-01-21 07:53:49 +00:00
break ;
2017-12-03 08:27:27 +00:00
case SP_W_USER :
2017-12-09 21:22:46 +00:00
qglUniform4fvARB ( ph , countof ( r_refdef . userdata ) , r_refdef . userdata [ 0 ] ) ; //and density
2017-12-03 08:27:27 +00:00
break ;
2012-01-21 07:53:49 +00:00
case SP_V_EYEPOS :
2012-11-27 03:23:19 +00:00
qglUniform3fvARB ( ph , 1 , r_origin ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_E_EYEPOS :
{
/*eye position in model space*/
vec3_t t2 ;
Matrix4x4_CM_Transform3 ( shaderstate . modelmatrixinv , r_origin , t2 ) ;
2012-11-27 03:23:19 +00:00
qglUniform3fvARB ( ph , 1 , t2 ) ;
2012-01-21 07:53:49 +00:00
}
break ;
case SP_LIGHTPOSITION :
{
/*light position in model space*/
vec3_t t2 ;
Matrix4x4_CM_Transform3 ( shaderstate . modelmatrixinv , shaderstate . lightorg , t2 ) ;
2012-11-27 03:23:19 +00:00
qglUniform3fvARB ( ph , 1 , t2 ) ;
2012-01-21 07:53:49 +00:00
}
break ;
2018-07-22 11:49:37 +00:00
case SP_LIGHTDIRECTION :
{
/*light position in model space*/
vec3_t t2 ;
Matrix4x4_CM_Transform3x3 ( shaderstate . modelmatrixinv , shaderstate . lightdir , t2 ) ;
qglUniform3fvARB ( ph , 1 , t2 ) ;
}
break ;
2012-01-21 07:53:49 +00:00
case SP_LIGHTCOLOURSCALE :
2012-11-27 03:23:19 +00:00
qglUniform3fvARB ( ph , 1 , shaderstate . lightcolourscale ) ;
2012-01-21 07:53:49 +00:00
break ;
2012-08-04 01:35:52 +00:00
case SP_LIGHTCUBEMATRIX :
2012-01-21 07:53:49 +00:00
/*light's texture projection matrix*/
{
float t [ 16 ] ;
2013-10-08 14:28:11 +00:00
Matrix4_Multiply ( shaderstate . lightprojmatrix , shaderstate . modelmatrix , t ) ;
2012-11-27 03:23:19 +00:00
qglUniformMatrix4fvARB ( ph , 1 , false , t ) ;
2012-01-21 07:53:49 +00:00
}
break ;
2013-10-08 14:28:11 +00:00
case SP_LIGHTSHADOWMAPPROJ :
qglUniform4fvARB ( ph , 1 , shaderstate . lightshadowmapproj ) ;
break ;
case SP_LIGHTSHADOWMAPSCALE :
qglUniform2fvARB ( ph , 1 , shaderstate . lightshadowmapscale ) ;
2013-03-12 23:13:39 +00:00
break ;
2011-12-27 08:35:19 +00:00
2012-01-21 07:53:49 +00:00
/*static lighting info*/
case SP_E_L_DIR :
2012-11-27 03:23:19 +00:00
qglUniform3fvARB ( ph , 1 , ( float * ) shaderstate . curentity - > light_dir ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_E_L_MUL :
2012-11-27 03:23:19 +00:00
qglUniform3fvARB ( ph , 1 , ( float * ) shaderstate . curentity - > light_range ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_E_L_AMBIENT :
2012-11-27 03:23:19 +00:00
qglUniform3fvARB ( ph , 1 , ( float * ) shaderstate . curentity - > light_avg ) ;
2012-01-21 07:53:49 +00:00
break ;
2011-09-03 03:49:43 +00:00
2012-01-21 07:53:49 +00:00
case SP_E_TIME :
2012-11-27 03:23:19 +00:00
qglUniform1fARB ( ph , shaderstate . curtime ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_CONSTI :
case SP_TEXTURE :
2012-11-27 03:23:19 +00:00
qglUniform1iARB ( ph , p - > ival ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_CONSTF :
2012-11-27 03:23:19 +00:00
qglUniform1fARB ( ph , p - > fval ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_CVARI :
2012-11-27 03:23:19 +00:00
qglUniform1iARB ( ph , ( ( cvar_t * ) p - > pval ) - > ival ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_CVARF :
2012-11-27 03:23:19 +00:00
qglUniform1fARB ( ph , ( ( cvar_t * ) p - > pval ) - > value ) ;
2012-01-21 07:53:49 +00:00
break ;
case SP_CVAR3F :
{
cvar_t * var = ( cvar_t * ) p - > pval ;
char * vs = var - > string ;
vs = COM_Parse ( vs ) ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
param4 [ 0 ] = atof ( com_token ) ;
2012-01-21 07:53:49 +00:00
vs = COM_Parse ( vs ) ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
param4 [ 1 ] = atof ( com_token ) ;
2012-01-21 07:53:49 +00:00
vs = COM_Parse ( vs ) ;
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
param4 [ 2 ] = atof ( com_token ) ;
qglUniform3fvARB ( ph , 1 , param4 ) ;
2012-01-21 07:53:49 +00:00
}
break ;
2011-01-23 03:44:49 +00:00
2012-01-21 07:53:49 +00:00
default :
Host_EndGame ( " Bad shader program parameter type (%i) " , p - > type ) ;
break ;
}
2011-01-23 03:44:49 +00:00
}
}
2015-08-28 03:13:45 +00:00
static void BE_RenderMeshProgram ( const shader_t * shader , const shaderpass_t * pass , program_t * p )
2011-01-23 03:44:49 +00:00
{
int i ;
int perm ;
2018-11-27 16:48:19 +00:00
struct programpermu_s * permu ;
2011-01-23 03:44:49 +00:00
perm = 0 ;
2018-07-22 11:49:37 +00:00
if ( shaderstate . sourcevbo - > numbones )
perm | = PERMUTATION_SKELETAL ;
# ifdef NONSKELETALMODELS
if ( shaderstate . sourcevbo - > coord2 . gl . addr )
perm | = PERMUTATION_FRAMEBLEND ;
# endif
if ( TEXLOADED ( shaderstate . curtexnums - > bump ) )
perm | = PERMUTATION_BUMPMAP ;
if ( TEXLOADED ( shaderstate . curtexnums - > fullbright ) )
perm | = PERMUTATION_FULLBRIGHT ;
if ( ( TEXLOADED ( shaderstate . curtexnums - > loweroverlay ) | | TEXLOADED ( shaderstate . curtexnums - > upperoverlay ) ) )
perm | = PERMUTATION_UPPERLOWER ;
if ( r_refdef . globalfog . density )
perm | = PERMUTATION_FOG ;
2018-11-27 16:48:19 +00:00
// if (TEXLOADED(shaderstate.curtexnums->bump) && shaderstate.curbatch->lightmap[0] >= 0 && lightmap[shaderstate.curbatch->lightmap[0]]->hasdeluxe)
2018-07-22 11:49:37 +00:00
// perm |= PERMUTATION_DELUXE;
if ( ( TEXLOADED ( shaderstate . curtexnums - > reflectcube ) | | TEXLOADED ( shaderstate . curtexnums - > reflectmask ) ) )
perm | = PERMUTATION_REFLECTCUBEMASK ;
# if MAXRLIGHTMAPS > 1
if ( shaderstate . curbatch - > lightmap [ 1 ] > = 0 )
perm | = PERMUTATION_LIGHTSTYLES ;
# endif
perm & = p - > supportedpermutations ;
2018-11-27 16:48:19 +00:00
permu = p - > permu [ perm ] ;
if ( ! permu )
2011-07-30 14:14:56 +00:00
{
2018-11-27 16:48:19 +00:00
p - > permu [ perm ] = permu = Shader_LoadPermutation ( p , perm ) ;
if ( ! permu )
2018-11-28 05:41:39 +00:00
{ //failed? copy from 0 so we don't keep re-failing
permu = p - > permu [ perm ] = p - > permu [ 0 ] ;
}
2011-07-30 14:14:56 +00:00
}
2017-02-19 00:15:42 +00:00
2018-11-27 16:48:19 +00:00
GL_SelectProgram ( permu - > h . glsl . handle ) ;
2012-11-27 03:23:19 +00:00
# ifndef FORCESTATE
2015-08-07 17:49:49 +00:00
if ( shaderstate . lastuniform = = shaderstate . currentprogram )
2012-01-21 07:53:49 +00:00
i = true ;
else
2012-11-27 03:23:19 +00:00
# endif
2011-01-23 03:44:49 +00:00
{
2012-01-21 07:53:49 +00:00
i = false ;
2015-08-07 17:49:49 +00:00
shaderstate . lastuniform = shaderstate . currentprogram ;
2011-01-23 03:44:49 +00:00
}
2018-11-27 16:48:19 +00:00
BE_Program_Set_Attributes ( p , permu , i ) ;
2012-01-21 07:53:49 +00:00
BE_SendPassBlendDepthMask ( pass - > shaderbits ) ;
2015-05-03 19:57:46 +00:00
2014-08-25 07:35:41 +00:00
# ifndef GLSLONLY
if ( ! p - > nofixedcompat )
{
GenerateColourMods ( pass ) ;
for ( i = 0 ; i < pass - > numMergedPasses ; i + + )
{
Shader_BindTextureForPass ( i , pass + i ) ;
BE_GeneratePassTC ( pass + i , i ) ;
}
for ( ; i < shaderstate . lastpasstmus ; i + + )
{
GL_LazyBind ( i , 0 , r_nulltex ) ;
}
shaderstate . lastpasstmus = pass - > numMergedPasses ;
}
else
# endif
2011-01-23 03:44:49 +00:00
{
for ( i = 0 ; i < pass - > numMergedPasses ; i + + )
{
2012-04-24 07:59:11 +00:00
Shader_BindTextureForPass ( i , pass + i ) ;
2011-01-23 03:44:49 +00:00
}
2013-10-08 14:28:11 +00:00
# if MAXRLIGHTMAPS > 1
2012-07-05 19:42:36 +00:00
if ( perm & PERMUTATION_LIGHTSTYLES )
2011-01-23 03:44:49 +00:00
{
2015-03-03 00:14:43 +00:00
GL_LazyBind ( i + + , GL_TEXTURE_2D , shaderstate . curbatch - > lightmap [ 1 ] > = 0 ? lightmap [ shaderstate . curbatch - > lightmap [ 1 ] ] - > lightmap_texture : r_nulltex ) ;
GL_LazyBind ( i + + , GL_TEXTURE_2D , shaderstate . curbatch - > lightmap [ 2 ] > = 0 ? lightmap [ shaderstate . curbatch - > lightmap [ 2 ] ] - > lightmap_texture : r_nulltex ) ;
GL_LazyBind ( i + + , GL_TEXTURE_2D , shaderstate . curbatch - > lightmap [ 3 ] > = 0 ? lightmap [ shaderstate . curbatch - > lightmap [ 3 ] ] - > lightmap_texture : r_nulltex ) ;
GL_LazyBind ( i + + , GL_TEXTURE_2D , ( shaderstate . curbatch - > lightmap [ 1 ] > = 0 & & lightmap [ shaderstate . curbatch - > lightmap [ 1 ] ] - > hasdeluxe ) ? lightmap [ shaderstate . curbatch - > lightmap [ 1 ] + 1 ] - > lightmap_texture : missing_texture_normal ) ;
GL_LazyBind ( i + + , GL_TEXTURE_2D , ( shaderstate . curbatch - > lightmap [ 2 ] > = 0 & & lightmap [ shaderstate . curbatch - > lightmap [ 2 ] ] - > hasdeluxe ) ? lightmap [ shaderstate . curbatch - > lightmap [ 2 ] + 1 ] - > lightmap_texture : missing_texture_normal ) ;
GL_LazyBind ( i + + , GL_TEXTURE_2D , ( shaderstate . curbatch - > lightmap [ 3 ] > = 0 & & lightmap [ shaderstate . curbatch - > lightmap [ 3 ] ] - > hasdeluxe ) ? lightmap [ shaderstate . curbatch - > lightmap [ 3 ] + 1 ] - > lightmap_texture : missing_texture_normal ) ;
2012-07-05 19:42:36 +00:00
}
2013-10-08 14:28:11 +00:00
# endif
2015-03-03 00:14:43 +00:00
while ( shaderstate . lastpasstmus > i )
GL_LazyBind ( - - shaderstate . lastpasstmus , 0 , r_nulltex ) ;
shaderstate . lastpasstmus = i ; //in case it was already lower
2011-01-23 03:44:49 +00:00
}
2018-11-27 16:48:19 +00:00
BE_EnableShaderAttributes ( permu - > attrmask , shaderstate . sourcevbo - > vao ) ;
BE_SubmitMeshChain ( permu - > h . glsl . usetesselation ) ;
2009-11-04 21:16:50 +00:00
}
2011-01-04 02:56:16 +00:00
qboolean GLBE_LightCullModel ( vec3_t org , model_t * model )
2009-11-04 21:16:50 +00:00
{
2011-01-23 03:52:52 +00:00
# ifdef RTLIGHTS
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
if ( ( shaderstate . mode = = BEM_LIGHT | | shaderstate . mode = = BEM_STENCIL | | shaderstate . mode = = BEM_DEPTHONLY ) )
2009-11-04 21:16:50 +00:00
{
float dist ;
vec3_t disp ;
if ( model - > type = = mod_alias )
{
VectorSubtract ( org , shaderstate . lightorg , disp ) ;
dist = DotProduct ( disp , disp ) ;
if ( dist > model - > radius * model - > radius + shaderstate . lightradius * shaderstate . lightradius )
return true ;
}
else
{
int i ;
for ( i = 0 ; i < 3 ; i + + )
{
if ( shaderstate . lightorg [ i ] - shaderstate . lightradius > org [ i ] + model - > maxs [ i ] )
return true ;
if ( shaderstate . lightorg [ i ] + shaderstate . lightradius < org [ i ] + model - > mins [ i ] )
return true ;
}
}
}
2011-01-23 03:52:52 +00:00
# endif
2009-11-04 21:16:50 +00:00
return false ;
}
2011-10-27 16:16:29 +00:00
//Note: Be cautious about using BEM_LIGHT here, as it won't select the light.
2011-04-20 23:34:13 +00:00
void GLBE_SelectMode ( backendmode_t mode )
2009-11-04 21:16:50 +00:00
{
extern int gldepthfunc ;
2013-12-29 22:48:28 +00:00
// shaderstate.lastuniform = 0;
2014-10-23 01:42:05 +00:00
# ifndef FORCESTATE
2009-11-04 21:16:50 +00:00
if ( mode ! = shaderstate . mode )
2014-10-23 01:42:05 +00:00
# endif
2009-11-04 21:16:50 +00:00
{
2011-04-20 23:34:13 +00:00
shaderstate . mode = mode ;
2011-04-23 20:37:20 +00:00
shaderstate . flags = 0 ;
2011-10-27 16:16:29 +00:00
switch ( mode )
2009-11-04 21:16:50 +00:00
{
2013-03-12 22:47:42 +00:00
default :
break ;
2014-09-02 02:44:43 +00:00
case BEM_WIREFRAME :
2017-03-06 14:06:12 +00:00
if ( ! shaderstate . wireframeshader & & gl_config . arb_shader_objects )
shaderstate . wireframeshader = R_RegisterShader ( " wireframe " , SUF_NONE ,
" { \n "
" program wireframe \n "
" { \n "
" nodepthtest \n "
" } \n "
" } \n "
) ;
2014-09-02 02:44:43 +00:00
break ;
2011-10-27 16:16:29 +00:00
case BEM_DEPTHONLY :
2014-08-27 08:41:31 +00:00
# ifndef GLSLONLY
if ( ! gl_config_nofixedfunc )
{
BE_SetPassBlendMode ( 0 , PBM_REPLACE ) ;
GL_DeSelectProgram ( ) ;
}
else
# endif
2014-11-05 05:39:24 +00:00
if ( ! shaderstate . allblackshader . glsl . handle )
2014-08-27 08:41:31 +00:00
{
const char * defs [ ] = { NULL } ;
2017-11-14 14:37:04 +00:00
shaderstate . allblackshader = GLSlang_CreateProgram ( NULL , " allblackprogram " , sh_config . minver , defs , " #include \" sys/skeletal.h \" \n void main(){gl_Position = skeletaltransform();} " , NULL , NULL , NULL , " void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);} " , false , NULL ) ;
2014-11-05 05:39:24 +00:00
shaderstate . allblack_mvp = qglGetUniformLocationARB ( shaderstate . allblackshader . glsl . handle , " m_modelviewprojection " ) ;
2014-08-27 08:41:31 +00:00
}
2011-10-27 16:16:29 +00:00
/*BEM_DEPTHONLY does support mesh writing, but its not the only way its used... FIXME!*/
2009-11-04 21:16:50 +00:00
while ( shaderstate . lastpasstmus > 0 )
{
2012-04-24 07:59:11 +00:00
GL_LazyBind ( - - shaderstate . lastpasstmus , 0 , r_nulltex ) ;
2009-11-04 21:16:50 +00:00
}
//we don't write or blend anything (maybe alpha test... but mneh)
2011-10-27 16:16:29 +00:00
BE_SendPassBlendDepthMask ( SBITS_MISC_DEPTHWRITE | SBITS_MASK_BITS ) ;
2009-11-04 21:16:50 +00:00
2014-11-03 04:45:18 +00:00
// BE_PolyOffset(false);
2014-10-23 01:42:05 +00:00
2011-10-27 16:16:29 +00:00
GL_CullFace ( SHADER_CULL_FRONT ) ;
break ;
# ifdef RTLIGHTS
case BEM_STENCIL :
2012-04-24 07:59:11 +00:00
/*BEM_STENCIL doesn't support mesh writing*/
2017-10-31 22:52:58 +00:00
# ifdef BEF_PUSHDEPTH
2014-11-03 04:45:18 +00:00
GLBE_PolyOffsetStencilShadow ( false ) ;
2017-10-31 22:52:58 +00:00
# else
GLBE_PolyOffsetStencilShadow ( ) ;
# endif
2011-10-27 16:16:29 +00:00
2014-11-05 05:39:24 +00:00
if ( gl_config_nofixedfunc & & ! shaderstate . allblackshader . glsl . handle )
2012-04-24 07:59:11 +00:00
{
2014-08-25 07:35:41 +00:00
const char * defs [ ] = { NULL } ;
2017-11-14 14:37:04 +00:00
shaderstate . allblackshader = GLSlang_CreateProgram ( NULL , " allblackprogram " , sh_config . minver , defs , " #include \" sys/skeletal.h \" \n void main(){gl_Position = skeletaltransform();} " , NULL , NULL , NULL , " void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);} " , false , NULL ) ;
2014-11-05 05:39:24 +00:00
shaderstate . allblack_mvp = qglGetUniformLocationARB ( shaderstate . allblackshader . glsl . handle , " m_modelviewprojection " ) ;
2012-04-24 07:59:11 +00:00
}
2011-10-27 16:16:29 +00:00
//disable all tmus
2009-11-04 21:16:50 +00:00
while ( shaderstate . lastpasstmus > 0 )
{
2012-04-24 07:59:11 +00:00
GL_LazyBind ( - - shaderstate . lastpasstmus , 0 , r_nulltex ) ;
2009-11-04 21:16:50 +00:00
}
2014-08-27 08:41:31 +00:00
# ifndef GLSLONLY
2014-08-25 07:35:41 +00:00
if ( ! gl_config_nofixedfunc )
2012-04-24 07:59:11 +00:00
{
GL_DeSelectProgram ( ) ;
2011-10-27 16:16:29 +00:00
//replace mode please
2012-04-24 07:59:11 +00:00
BE_SetPassBlendMode ( 0 , PBM_REPLACE ) ;
}
2014-08-27 08:41:31 +00:00
# endif
2009-11-04 21:16:50 +00:00
//we don't write or blend anything (maybe alpha test... but mneh)
2018-04-27 16:40:50 +00:00
BE_SendPassBlendDepthMask ( SBITS_DEPTHFUNC_CLOSER | SBITS_MASK_BITS ) ;
2011-12-05 15:23:40 +00:00
GL_CullFace ( 0 ) ;
2009-11-04 21:16:50 +00:00
2011-10-27 16:16:29 +00:00
//don't change cull stuff, and
//don't actually change stencil stuff - caller needs to be
//aware of how many times stuff is drawn, so they can do that themselves.
break ;
2011-12-05 15:23:40 +00:00
case BEM_CREPUSCULAR :
if ( ! shaderstate . crepopaqueshader )
{
2013-08-21 07:14:39 +00:00
shaderstate . crepopaqueshader = R_RegisterShader ( " crepuscular_opaque " , SUF_NONE ,
2011-12-05 15:23:40 +00:00
" { \n "
" program crepuscular_opaque \n "
" } \n "
) ;
}
if ( ! shaderstate . crepskyshader )
{
2013-08-21 07:14:39 +00:00
shaderstate . crepskyshader = R_RegisterShader ( " crepuscular_sky " , SUF_NONE ,
2011-12-05 15:23:40 +00:00
" { \n "
" program crepuscular_sky \n "
2015-04-14 23:12:17 +00:00
" { \n "
" map $diffuse \n "
" } \n "
" { \n "
" map $fullbright \n "
" } \n "
2011-12-05 15:23:40 +00:00
" } \n "
) ;
}
break ;
2011-10-27 16:16:29 +00:00
# endif
case BEM_FOG :
2011-02-25 04:22:14 +00:00
while ( shaderstate . lastpasstmus > 0 )
{
2012-04-24 07:59:11 +00:00
GL_LazyBind ( - - shaderstate . lastpasstmus , 0 , r_nulltex ) ;
2011-02-25 04:22:14 +00:00
}
2012-04-24 07:59:11 +00:00
GL_LazyBind ( 0 , GL_TEXTURE_2D , shaderstate . fogtexture ) ;
2011-02-25 04:22:14 +00:00
shaderstate . lastpasstmus = 1 ;
2012-04-24 07:59:11 +00:00
Vector4Set ( shaderstate . pendingcolourflat , 1 , 1 , 1 , 1 ) ;
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = NULL ;
2014-08-27 08:41:31 +00:00
# ifndef GLSLONLY
if ( ! gl_config_nofixedfunc )
BE_SetPassBlendMode ( 0 , PBM_MODULATE ) ;
# endif
2018-04-27 16:40:50 +00:00
BE_SendPassBlendDepthMask ( SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | SBITS_DEPTHFUNC_EQUAL ) ;
2011-10-27 16:16:29 +00:00
break ;
2011-02-25 04:22:14 +00:00
}
2004-10-19 16:10:14 +00:00
}
2009-11-04 21:16:50 +00:00
}
2011-01-04 02:56:16 +00:00
void GLBE_SelectEntity ( entity_t * ent )
2010-08-28 17:14:38 +00:00
{
2012-11-29 13:37:48 +00:00
float nd ;
2010-08-28 17:14:38 +00:00
shaderstate . curentity = ent ;
currententity = ent ;
2011-10-27 16:16:29 +00:00
R_RotateForEntity ( shaderstate . modelmatrix , shaderstate . modelviewmatrix , shaderstate . curentity , shaderstate . curentity - > model ) ;
2012-01-17 07:57:46 +00:00
Matrix4_Invert ( shaderstate . modelmatrix , shaderstate . modelmatrixinv ) ;
2011-01-23 03:44:49 +00:00
if ( qglLoadMatrixf )
qglLoadMatrixf ( shaderstate . modelviewmatrix ) ;
2012-11-29 13:37:48 +00:00
2014-03-31 17:06:41 +00:00
if ( shaderstate . curentity - > flags & RF_DEPTHHACK )
2012-11-29 13:37:48 +00:00
nd = 0.3 ;
else
nd = 1 ;
if ( shaderstate . depthrange ! = nd )
2012-04-24 07:59:11 +00:00
{
2017-12-15 06:56:40 +00:00
if ( nd < 1 )
memcpy ( shaderstate . projectionmatrix , r_refdef . m_projection_view , sizeof ( shaderstate . projectionmatrix ) ) ;
else
memcpy ( shaderstate . projectionmatrix , r_refdef . m_projection_std , sizeof ( shaderstate . projectionmatrix ) ) ;
if ( qglLoadMatrixf )
{
qglMatrixMode ( GL_PROJECTION ) ;
qglLoadMatrixf ( shaderstate . projectionmatrix ) ;
qglMatrixMode ( GL_MODELVIEW ) ;
}
2012-11-29 13:37:48 +00:00
shaderstate . depthrange = nd ;
2018-01-22 19:18:04 +00:00
// if (qglDepthRange)
// qglDepthRange (gldepthmin, gldepthmin + shaderstate.depthrange*(gldepthmax-gldepthmin));
// else if (qglDepthRangef)
// qglDepthRangef (gldepthmin, gldepthmin + shaderstate.depthrange*(gldepthmax-gldepthmin));
2012-04-24 07:59:11 +00:00
}
2012-01-21 07:53:49 +00:00
shaderstate . lastuniform = 0 ;
2010-08-28 17:14:38 +00:00
}
2018-01-22 19:18:04 +00:00
2017-11-30 17:59:11 +00:00
# if 1
2012-09-30 05:52:03 +00:00
static void BE_SelectFog ( vec3_t colour , float alpha , float density )
2011-02-25 04:22:14 +00:00
{
2011-03-31 02:32:32 +00:00
float zscale ;
2017-11-30 17:59:11 +00:00
GL_DeSelectProgram ( ) ;
2011-03-31 02:32:32 +00:00
zscale = 2048 ; /*this value is meant to be the distance at which fog the value becomes as good as fully fogged, just hack it to 2048...*/
GenerateFogTexture ( & shaderstate . fogtexture , density , zscale ) ;
shaderstate . fogfar = 1 / zscale ; /*scaler for z coords*/
2017-11-30 17:59:11 +00:00
VectorCopy ( colour , shaderstate . pendingcolourflat ) ;
shaderstate . pendingcolourflat [ 3 ] = alpha ;
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = NULL ;
2011-02-25 04:22:14 +00:00
}
2013-03-12 22:47:42 +00:00
# endif
2012-12-04 19:37:57 +00:00
# ifdef RTLIGHTS
static qboolean GLBE_RegisterLightShader ( int mode )
{
if ( ! shaderstate . inited_shader_light [ mode ] )
{
2018-01-22 19:18:04 +00:00
char * name = va ( " rtlight%s%s%s%s%s " ,
2013-10-29 17:38:22 +00:00
( mode & LSHADER_SMAP ) ? " #PCF " : " " ,
( mode & LSHADER_SPOT ) ? " #SPOT " : " " ,
2014-08-27 08:41:31 +00:00
( mode & LSHADER_CUBE ) ? " #CUBE " : " " ,
2018-01-22 19:18:04 +00:00
( mode & LSHADER_ORTHO ) ? " #ORTHO " : " " ,
( gl_config . arb_shadow & & ( mode & ( LSHADER_SMAP | LSHADER_SPOT | LSHADER_CUBE | LSHADER_ORTHO ) ) ) ? " #USE_ARB_SHADOW " : " "
2014-08-27 08:41:31 +00:00
) ;
2012-12-04 19:37:57 +00:00
shaderstate . inited_shader_light [ mode ] = true ;
2013-08-21 07:14:39 +00:00
shaderstate . shader_light [ mode ] = R_RegisterCustom ( name , SUF_NONE , Shader_LightPass , NULL ) ;
2013-10-08 14:28:11 +00:00
}
2012-12-04 19:37:57 +00:00
2013-10-08 14:28:11 +00:00
if ( shaderstate . shader_light [ mode ] )
{
2012-12-04 19:37:57 +00:00
//make sure it has a program and forget it if it doesn't, to save a compare.
2013-10-08 14:28:11 +00:00
if ( ! shaderstate . shader_light [ mode ] - > prog )
2012-12-04 19:37:57 +00:00
{
shaderstate . shader_light [ mode ] = NULL ;
2013-10-08 14:28:11 +00:00
return false ;
2012-12-04 19:37:57 +00:00
}
return true ;
2013-10-08 14:28:11 +00:00
}
2012-12-04 19:37:57 +00:00
return false ;
}
# endif
2014-10-05 20:04:11 +00:00
qboolean GLBE_SelectDLight ( dlight_t * dl , vec3_t colour , vec3_t axis [ 3 ] , unsigned int lmode )
2009-11-04 21:16:50 +00:00
{
2016-02-15 06:01:17 +00:00
# ifdef RTLIGHTS
2012-11-27 03:23:19 +00:00
extern cvar_t gl_specular ;
2016-02-15 06:01:17 +00:00
# endif
2013-10-08 14:28:11 +00:00
2013-10-08 16:13:18 +00:00
shaderstate . lastuniform = 0 ;
2013-10-08 14:28:11 +00:00
shaderstate . curdlight = dl ;
2013-10-29 17:38:22 +00:00
shaderstate . lightmode = lmode ;
2011-12-27 08:35:19 +00:00
/*simple info*/
2009-11-04 21:16:50 +00:00
shaderstate . lightradius = dl - > radius ;
VectorCopy ( dl - > origin , shaderstate . lightorg ) ;
2018-07-22 11:49:37 +00:00
VectorCopy ( axis [ 0 ] , shaderstate . lightdir ) ;
2009-11-04 21:16:50 +00:00
VectorCopy ( colour , shaderstate . lightcolours ) ;
2011-12-27 08:35:19 +00:00
# ifdef RTLIGHTS
2013-10-08 14:28:11 +00:00
VectorCopy ( dl - > lightcolourscales , shaderstate . lightcolourscale ) ;
2014-10-05 20:04:11 +00:00
shaderstate . lightcolourscale [ 2 ] * = gl_specular . value ;
2018-01-22 19:18:04 +00:00
if ( lmode & ( LSHADER_SPOT | LSHADER_ORTHO ) )
2013-10-29 17:38:22 +00:00
shaderstate . lightcubemap = r_nulltex ;
else
shaderstate . lightcubemap = dl - > cubetexture ;
2012-01-21 07:53:49 +00:00
2014-10-05 20:04:11 +00:00
if ( TEXLOADED ( shaderstate . lightcubemap ) & & GLBE_RegisterLightShader ( shaderstate . lightmode | LSHADER_CUBE ) )
2013-10-29 17:38:22 +00:00
shaderstate . lightmode | = LSHADER_CUBE ;
2013-10-08 16:13:18 +00:00
if ( ! GLBE_RegisterLightShader ( shaderstate . lightmode ) )
return false ;
2013-10-29 17:38:22 +00:00
/*generate light projection information*/
2018-01-22 19:18:04 +00:00
if ( shaderstate . lightmode & LSHADER_ORTHO )
{
2018-07-22 11:49:37 +00:00
float view [ 16 ] ;
float proj [ 16 ] ;
2018-01-22 19:18:04 +00:00
float xmin = - dl - > radius ;
float ymin = - dl - > radius ;
float znear = - dl - > radius ;
float xmax = dl - > radius ;
float ymax = dl - > radius ;
float zfar = dl - > radius ;
2018-07-22 11:49:37 +00:00
Matrix4x4_CM_Orthographic ( proj , xmin , xmax , ymax , ymin , znear , zfar ) ;
Matrix4x4_CM_ModelViewMatrixFromAxis ( view , axis [ 0 ] , axis [ 2 ] , axis [ 1 ] , dl - > origin ) ;
Matrix4_Multiply ( proj , view , shaderstate . lightprojmatrix ) ;
2018-01-22 19:18:04 +00:00
// Matrix4x4_CM_LightMatrixFromAxis(shaderstate.lightprojmatrix, axis[0], axis[1], axis[2], dl->origin);
}
else if ( shaderstate . lightmode & LSHADER_SPOT )
2013-10-29 17:38:22 +00:00
{
float view [ 16 ] ;
float proj [ 16 ] ;
extern cvar_t r_shadow_shadowmapping_nearclip ;
2017-12-28 16:24:50 +00:00
Matrix4x4_CM_Projection_Far ( proj , dl - > fov , dl - > fov , r_shadow_shadowmapping_nearclip . value , dl - > radius , false ) ;
2014-10-05 20:04:11 +00:00
Matrix4x4_CM_ModelViewMatrixFromAxis ( view , axis [ 0 ] , axis [ 1 ] , axis [ 2 ] , dl - > origin ) ;
2013-10-29 17:38:22 +00:00
Matrix4_Multiply ( proj , view , shaderstate . lightprojmatrix ) ;
}
else if ( shaderstate . lightmode & ( LSHADER_SMAP | LSHADER_CUBE ) )
{
2014-10-05 20:04:11 +00:00
Matrix4x4_CM_LightMatrixFromAxis ( shaderstate . lightprojmatrix , axis [ 0 ] , axis [ 1 ] , axis [ 2 ] , dl - > origin ) ;
2013-10-29 17:38:22 +00:00
/*
vec3_t down ;
vec3_t back ;
vec3_t right ;
2014-10-05 20:04:11 +00:00
VectorScale ( axis [ 2 ] , - 1 , down ) ;
VectorScale ( axis [ 1 ] , 1 , right ) ;
VectorScale ( axis [ 0 ] , 1 , back ) ;
2013-10-29 17:38:22 +00:00
Matrix4x4_CM_ModelViewMatrixFromAxis ( shaderstate . lightprojmatrix , down , back , right , dl - > origin ) ;
*/
}
2013-10-08 16:13:18 +00:00
# endif
2012-10-08 04:36:10 +00:00
2013-10-08 14:28:11 +00:00
return true ;
2011-09-05 01:48:23 +00:00
}
2009-11-04 21:16:50 +00:00
2013-06-23 02:17:02 +00:00
void GLBE_Scissor ( srect_t * rect )
{
if ( rect )
{
qglScissor (
floor ( r_refdef . pxrect . x + rect - > x * r_refdef . pxrect . width ) ,
2014-08-30 09:58:51 +00:00
// floor(r_refdef.pxrect.y + rect->y*r_refdef.pxrect.height),// - r_refdef.pxrect.maxheight),
floor ( rect - > y * r_refdef . pxrect . height + ( r_refdef . pxrect . maxheight - r_refdef . pxrect . y ) - r_refdef . pxrect . height ) ,
2013-06-23 02:17:02 +00:00
ceil ( rect - > width * r_refdef . pxrect . width ) ,
ceil ( rect - > height * r_refdef . pxrect . height ) ) ;
2013-12-08 20:06:55 +00:00
qglEnable ( GL_SCISSOR_TEST ) ;
2013-06-23 02:17:02 +00:00
if ( qglDepthBoundsEXT )
{
qglDepthBoundsEXT ( rect - > dmin , rect - > dmax ) ;
qglEnable ( GL_DEPTH_BOUNDS_TEST_EXT ) ;
}
}
else
{
2013-10-08 14:28:11 +00:00
/* qglScissor(
r_refdef . pxrect . x ,
r_refdef . pxrect . y - r_refdef . pxrect . height ,
r_refdef . pxrect . width ,
r_refdef . pxrect . height ) ;
*/ qglDisable ( GL_SCISSOR_TEST ) ;
2013-06-23 02:17:02 +00:00
if ( qglDepthBoundsEXT )
qglDisable ( GL_DEPTH_BOUNDS_TEST_EXT ) ;
2013-12-29 22:48:28 +00:00
// if (qglDepthBoundsEXT)
// qglDepthBoundsEXT(0, 1);
2013-06-23 02:17:02 +00:00
}
}
2014-08-25 07:35:41 +00:00
# if defined(RTLIGHTS) && !defined(GLSLONLY)
2012-05-10 01:00:41 +00:00
texid_t GenerateNormalisationCubeMap ( void ) ;
static void BE_LegacyLighting ( void )
{
//bigfoot wants rtlight support without glsl, so here goes madness...
//register combiners for bumpmapping using 4 tmus...
float * col ;
float * ldir ;
vec3_t lightdir , rellight ;
float scale ;
int i , m ;
mesh_t * mesh ;
unsigned int attr = ( 1u < < VATTR_LEG_VERTEX ) | ( 1u < < VATTR_LEG_COLOUR ) ;
2012-11-27 03:23:19 +00:00
int tmu = 0 ;
2012-05-10 01:00:41 +00:00
BE_SendPassBlendDepthMask ( SBITS_SRCBLEND_ONE | SBITS_DSTBLEND_ONE ) ;
//rotate this into modelspace
Matrix4x4_CM_Transform3 ( shaderstate . modelmatrixinv , shaderstate . lightorg , rellight ) ;
for ( m = 0 ; m < shaderstate . meshcount ; m + + )
{
mesh = shaderstate . meshes [ m ] ;
2013-10-29 17:38:22 +00:00
//vbo-only mesh.
if ( ! mesh - > xyz_array )
return ;
2014-10-05 20:04:11 +00:00
if ( ! mesh - > normals_array )
return ;
2013-10-29 17:38:22 +00:00
2012-05-10 01:00:41 +00:00
col = coloursarray [ 0 ] + mesh - > vbofirstvert * 4 ;
ldir = texcoordarray [ 0 ] + mesh - > vbofirstvert * 3 ;
for ( i = 0 ; i < mesh - > numvertexes ; i + + , col + = 4 , ldir + = 3 )
{
VectorSubtract ( rellight , mesh - > xyz_array [ i ] , lightdir ) ;
scale = VectorNormalize ( lightdir ) ;
scale = 1 - ( scale / shaderstate . lightradius ) ;
VectorScale ( shaderstate . lightcolours , scale , col ) ;
col [ 3 ] = 1 ;
ldir [ 0 ] = - DotProduct ( lightdir , mesh - > snormals_array [ i ] ) ;
ldir [ 1 ] = DotProduct ( lightdir , mesh - > tnormals_array [ i ] ) ;
ldir [ 2 ] = DotProduct ( lightdir , mesh - > normals_array [ i ] ) ;
}
}
2018-12-29 07:43:02 +00:00
if ( TEXLOADED ( shaderstate . curtexnums - > bump ) & & sh_config . havecubemaps & & gl_config . arb_texture_env_dot3 & & gl_config . arb_texture_env_combine & & be_maxpasses > = 4 )
2012-05-11 01:57:00 +00:00
{ //we could get this down to 2 tmus by arranging for the dot3 result to be written the alpha buffer. But then we'd need to have an alpha buffer too.
2012-05-10 01:00:41 +00:00
2014-10-05 20:04:11 +00:00
if ( ! shaderstate . normalisationcubemap )
2012-05-11 01:57:00 +00:00
shaderstate . normalisationcubemap = GenerateNormalisationCubeMap ( ) ;
2012-05-10 01:00:41 +00:00
//tmu0: normalmap+replace+regular tex coords
2012-11-27 03:23:19 +00:00
GL_LazyBind ( tmu , GL_TEXTURE_2D , shaderstate . curtexnums - > bump ) ;
BE_SetPassBlendMode ( tmu , PBM_REPLACE ) ;
shaderstate . pendingtexcoordparts [ tmu ] = 2 ;
shaderstate . pendingtexcoordvbo [ tmu ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ tmu ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
attr | = ( 1u < < ( VATTR_LEG_TMU0 + tmu ) ) ;
tmu + + ;
2012-05-10 01:00:41 +00:00
//tmu1: normalizationcubemap+dot3+lightdir
2012-11-27 03:23:19 +00:00
GL_LazyBind ( tmu , GL_TEXTURE_CUBE_MAP_ARB , shaderstate . normalisationcubemap ) ;
BE_SetPassBlendMode ( tmu , PBM_DOTPRODUCT ) ;
shaderstate . pendingtexcoordparts [ tmu ] = 3 ;
shaderstate . pendingtexcoordvbo [ tmu ] = 0 ;
shaderstate . pendingtexcoordpointer [ tmu ] = texcoordarray [ 0 ] ;
attr | = ( 1u < < ( VATTR_LEG_TMU0 + tmu ) ) ;
tmu + + ;
2012-05-10 01:00:41 +00:00
//tmu2: $diffuse+multiply+regular tex coords
2012-11-27 03:23:19 +00:00
GL_LazyBind ( tmu , GL_TEXTURE_2D , shaderstate . curtexnums - > base ) ; //texture not used, its just to make sure the code leaves it enabled.
BE_SetPassBlendMode ( tmu , PBM_MODULATE ) ;
shaderstate . pendingtexcoordparts [ tmu ] = 2 ;
shaderstate . pendingtexcoordvbo [ tmu ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ tmu ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
attr | = ( 1u < < ( VATTR_LEG_TMU0 + tmu ) ) ;
tmu + + ;
2012-05-10 01:00:41 +00:00
//tmu3: $any+multiply-by-colour+notc
2017-12-09 21:22:46 +00:00
GL_LazyBind ( tmu , GL_TEXTURE_2D , shaderstate . curtexnums - > base ) ; //texture not used, its just to make sure the code leaves it enabled.
2012-11-27 03:23:19 +00:00
BE_SetPassBlendMode ( tmu , PBM_MODULATE_PREV_COLOUR ) ;
shaderstate . pendingtexcoordparts [ tmu ] = 0 ;
shaderstate . pendingtexcoordvbo [ tmu ] = 0 ;
shaderstate . pendingtexcoordpointer [ tmu ] = NULL ;
tmu + + ;
2012-05-10 01:00:41 +00:00
//note we need 4 combiners in the first because we can't use the colour argument in the first without breaking the normals.
2012-11-27 03:23:19 +00:00
for ( i = tmu ; i < shaderstate . lastpasstmus ; i + + )
2012-05-10 01:00:41 +00:00
{
2012-11-27 03:23:19 +00:00
GL_LazyBind ( i , 0 , r_nulltex ) ;
2012-05-10 01:00:41 +00:00
}
2012-11-27 03:23:19 +00:00
shaderstate . lastpasstmus = tmu ;
2012-05-10 01:00:41 +00:00
}
else
{
attr | = ( 1u < < ( VATTR_LEG_TMU0 ) ) ;
//tmu0: $diffuse+multiply+regular tex coords
//multiplies by vertex colours
GL_LazyBind ( 0 , GL_TEXTURE_2D , shaderstate . curtexnums - > base ) ; //texture not used, its just to make sure the code leaves it enabled.
BE_SetPassBlendMode ( 0 , PBM_MODULATE ) ;
2012-11-27 03:23:19 +00:00
shaderstate . pendingtexcoordvbo [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
2012-05-10 01:00:41 +00:00
for ( i = 1 ; i < shaderstate . lastpasstmus ; i + + )
{
2012-11-27 03:23:19 +00:00
GL_LazyBind ( i , 0 , r_nulltex ) ;
2012-05-10 01:00:41 +00:00
}
shaderstate . lastpasstmus = 1 ;
}
shaderstate . colourarraytype = GL_FLOAT ;
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = coloursarray ;
GL_DeSelectProgram ( ) ;
2012-11-27 03:23:19 +00:00
BE_EnableShaderAttributes ( attr , 0 ) ;
2012-05-10 01:00:41 +00:00
2014-11-05 05:39:24 +00:00
BE_SubmitMeshChain ( false ) ;
2012-05-10 01:00:41 +00:00
2017-12-09 21:22:46 +00:00
// GL_LazyBind(1, 0, r_nulltex);
// GL_LazyBind(2, 0, r_nulltex);
// GL_LazyBind(3, 0, r_nulltex);
2012-05-10 01:00:41 +00:00
}
# endif
2010-07-11 02:22:39 +00:00
static void DrawMeshes ( void )
{
2013-10-29 17:38:22 +00:00
const shader_t * altshader ;
2010-07-11 02:22:39 +00:00
const shaderpass_t * p ;
2010-08-11 09:30:16 +00:00
int passno ;
2013-10-08 14:28:11 +00:00
int flags ;
2010-07-11 02:22:39 +00:00
passno = 0 ;
2004-10-19 16:10:14 +00:00
2011-02-25 04:22:14 +00:00
if ( shaderstate . force2d )
{
RQuantAdd ( RQUANT_2DBATCHES , 1 ) ;
}
else if ( shaderstate . curentity = = & r_worldentity )
{
RQuantAdd ( RQUANT_WORLDBATCHES , 1 ) ;
}
else
{
RQuantAdd ( RQUANT_ENTBATCHES , 1 ) ;
}
2013-10-08 14:28:11 +00:00
flags = shaderstate . curshader - > flags ;
Reworked client support for DPP5+. less code now, its much more graceful.
added waterfog command. waterfog overrides regular fog only when the view is in water.
fixed 64bit printf format specifiers. should work better on winxp64.
fixed some spec angle weirdness.
fixed viewsize 99.99 weirdness with ezhud.
fixed extra offset on the console (exhibited in 64bit builds, but not limited to).
fixed .avi playback, can now actually display frames again.
reimplemented line sparks.
fixed r_editlights_save flipping the light's pitch.
fixed issue with oggs failing to load.
fixed condump to cope with unicode properly.
made sv_bigcoords default except in quake. hexen2 kinda needs it for bsp angle precision.
fixed nq server to not stall weirdly on map changes.
fixed qwprogs svc_cdtrack not bugging out with nq clients on the server.
fixed restart command to load the last map run by the server, instead of start.bsp (when idle)
optimised d3d9 renderer a little. now uses less draw calls, especially with complex scenes. seems to get higher framerates than opengl now.
fixed d3d9 renderer to not bug out quite so much when run fullscreen (shader subsystem is now correctly initialised).
fixed a couple of bugs from font change. also now supports utf-8 in a few more places.
r_editlights_reload no longer generates rtlights inside the void. this resolves a few glitches (but should also help framerates a little).
fixed so corona-only lights won't generate shadowmaps and waste lots of time.
removed lots of #defines from qclib. I should never have made them in the first place, but I was lazy. obviously there's more left that I cba to remove yet.
fixed nested calls with variant-vectors. this fixes csaddon's light editor.
fixed qcc hc calling conventions using redundant stores.
disabled keywords can still be used by using __keyword instead.
fixed ftegccgui grep feature.
fixed motionless-dog qcc bug.
tweaked qcc warnings a little. -Wall is now a viable setting. you should be able to fix all those warnings.
fixed qw svc_intermission + dpp5+ clients bug.
fixed annoying spam about disconnecting in hexen2.
rewrote status command a little to cope with ipv6 addresses more gracefully
fixed significant stall when hibernating/debugging a server with a player sitting on it.
fixed truelightning.
fixed rocketlight overriding pflags.
fixed torches vanishing on vid_restart.
fixed issue with decal scaling.
fixed findentityfield builtin.
fixed fteqcc issue with ptr+1
fixed use of arrays inside class functions.
fixed/implemented fteqcc emulation of pointer opcodes.
added __inout keyword to fteqcc, so that it doesn't feel so horrendous.
fixed sizeof(*foo)
fixed *struct = struct;
fixed recursive structs.
fixed fteqcc warning report.
fixed sdl2 controller support, hopefully.
attempted to implement xinput, including per-player audio playback.
slightly fixed relaxed attitude to mouse focus when running fullscreen.
fixed weird warnings/errors with 'ent.arrayhead' terms. now generates sane errors.
implemented bindmaps (for csqc).
fixed crashing bug with eprint builtin.
implemented subset of music_playlist_* functionality. significant changes to music playback.
fixed some more dpcsqc compat.
fixed binds menu. now displays and accepts modifiers.
fixed issues with huge lightmaps.
fixed protocol determinism with dp clients connecting to fte servers. the initial getchallenge request now inhibits vanilla nq connection requests.
implemented support for 'dupe' userinfo key, allowing clients to request client->server packet duplication. should probably queue them tbh.
implemented sv_saveentfile command.
fixed resume after breaking inside a stepped-over function.
fixed erroneous footer after debugging.
(I wonder just how many things I broke with these fixes)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4946 fc73d0e0-1445-4013-8a0c-d673dee63da5
2015-07-26 10:56:18 +00:00
GL_CullFace ( flags & ( SHADER_CULL_FRONT | SHADER_CULL_BACK ) ) ;
2010-07-11 02:22:39 +00:00
2013-04-07 07:13:59 +00:00
if ( shaderstate . sourcevbo - > coord2 . gl . addr & & ( shaderstate . curshader - > numdeforms | | ! shaderstate . curshader - > prog ) )
2012-05-09 15:30:53 +00:00
GenerateVertexBlends ( shaderstate . curshader ) ;
else if ( shaderstate . curshader - > numdeforms )
GenerateVertexDeforms ( shaderstate . curshader ) ;
else
{
shaderstate . pendingvertexpointer = shaderstate . sourcevbo - > coord . gl . addr ;
shaderstate . pendingvertexvbo = shaderstate . sourcevbo - > coord . gl . vbo ;
}
2015-06-28 00:42:00 +00:00
# ifdef _DEBUG
if ( ! shaderstate . pendingvertexpointer & & ! shaderstate . pendingvertexvbo )
{
Con_Printf ( CON_ERROR " pendingvertexpointer+vbo are both null! shader is %s \n " , shaderstate . curshader - > name ) ;
return ;
}
# endif
2013-04-04 08:08:49 +00:00
# ifdef FTE_TARGET_WEB
if ( ! shaderstate . pendingvertexvbo )
2015-08-25 03:02:19 +00:00
{
int len = 0 , m ;
mesh_t * meshlist ;
for ( m = 0 ; m < shaderstate . meshcount ; m + + )
{
meshlist = shaderstate . meshes [ m ] ;
if ( len < meshlist - > vbofirstvert + meshlist - > numvertexes )
len = meshlist - > vbofirstvert + meshlist - > numvertexes ;
}
len * = sizeof ( vecV_t ) ;
shaderstate . streamid = ( shaderstate . streamid + 1 ) & ( sizeof ( shaderstate . streamvbo ) / sizeof ( shaderstate . streamvbo [ 0 ] ) - 1 ) ;
GL_SelectVBO ( shaderstate . pendingvertexvbo = shaderstate . streamvbo [ shaderstate . streamid ] ) ;
qglBufferDataARB ( GL_ARRAY_BUFFER_ARB , len , shaderstate . pendingvertexpointer , GL_STREAM_DRAW_ARB ) ;
shaderstate . pendingvertexpointer = NULL ;
}
2013-04-04 08:08:49 +00:00
if ( ! shaderstate . sourcevbo - > indicies . gl . vbo )
return ;
# endif
2017-10-13 17:50:28 +00:00
BE_PolyOffset ( ) ;
2009-11-04 21:16:50 +00:00
switch ( shaderstate . mode )
{
case BEM_STENCIL :
Host_Error ( " Shader system is not meant to accept stencil meshes \n " ) ;
break ;
2010-07-11 02:22:39 +00:00
# ifdef RTLIGHTS
2009-11-04 21:16:50 +00:00
case BEM_LIGHT :
2013-10-29 17:38:22 +00:00
altshader = shaderstate . curshader - > bemoverrides [ shaderstate . lightmode ] ;
if ( ! altshader )
altshader = shaderstate . shader_light [ shaderstate . lightmode ] ;
if ( altshader & & altshader - > prog )
2015-08-28 03:13:45 +00:00
{
shaderstate . pendingcolourvbo = shaderstate . sourcevbo - > colours [ 0 ] . gl . vbo ;
shaderstate . pendingcolourpointer = shaderstate . sourcevbo - > colours [ 0 ] . gl . addr ;
shaderstate . colourarraytype = shaderstate . sourcevbo - > colours_bytes ? GL_UNSIGNED_BYTE : GL_FLOAT ;
shaderstate . pendingtexcoordparts [ 0 ] = 2 ;
shaderstate . pendingtexcoordvbo [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
BE_RenderMeshProgram ( altshader , altshader - > passes , altshader - > prog ) ;
}
2014-08-25 07:35:41 +00:00
# ifndef GLSLONLY
2012-12-04 19:37:57 +00:00
else
2013-10-29 17:38:22 +00:00
BE_LegacyLighting ( ) ;
2014-08-25 07:35:41 +00:00
# endif
2009-11-04 21:16:50 +00:00
break ;
2016-11-20 20:52:41 +00:00
case BEM_GBUFFER :
altshader = shaderstate . curshader - > bemoverrides [ bemoverride_gbuffer ] ;
2017-10-31 22:52:58 +00:00
if ( altshader )
2015-08-28 03:13:45 +00:00
{
2017-10-31 22:52:58 +00:00
if ( altshader - > prog )
{
shaderstate . pendingcolourvbo = shaderstate . sourcevbo - > colours [ 0 ] . gl . vbo ;
shaderstate . pendingcolourpointer = shaderstate . sourcevbo - > colours [ 0 ] . gl . addr ;
shaderstate . colourarraytype = shaderstate . sourcevbo - > colours_bytes ? GL_UNSIGNED_BYTE : GL_FLOAT ;
shaderstate . pendingtexcoordparts [ 0 ] = 2 ;
shaderstate . pendingtexcoordvbo [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
BE_RenderMeshProgram ( altshader , altshader - > passes , altshader - > prog ) ;
}
else if ( altshader - > numpasses & & altshader - > passes [ 0 ] . prog )
{
shaderstate . pendingcolourvbo = shaderstate . sourcevbo - > colours [ 0 ] . gl . vbo ;
shaderstate . pendingcolourpointer = shaderstate . sourcevbo - > colours [ 0 ] . gl . addr ;
shaderstate . colourarraytype = shaderstate . sourcevbo - > colours_bytes ? GL_UNSIGNED_BYTE : GL_FLOAT ;
shaderstate . pendingtexcoordparts [ 0 ] = 2 ;
shaderstate . pendingtexcoordvbo [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
BE_RenderMeshProgram ( altshader , altshader - > passes , altshader - > passes [ 0 ] . prog ) ;
}
2015-08-28 03:13:45 +00:00
}
2017-10-31 22:52:58 +00:00
2011-09-03 03:49:43 +00:00
break ;
2010-07-11 02:22:39 +00:00
# endif
2011-12-05 15:23:40 +00:00
case BEM_CREPUSCULAR :
2013-10-29 17:38:22 +00:00
altshader = shaderstate . curshader - > bemoverrides [ bemoverride_crepuscular ] ;
if ( ! altshader & & ( shaderstate . curshader - > flags & SHADER_SKY ) )
altshader = shaderstate . crepskyshader ;
if ( ! altshader )
altshader = shaderstate . crepopaqueshader ;
if ( altshader & & altshader - > prog )
2015-08-28 03:13:45 +00:00
{
shaderstate . pendingcolourvbo = shaderstate . sourcevbo - > colours [ 0 ] . gl . vbo ;
shaderstate . pendingcolourpointer = shaderstate . sourcevbo - > colours [ 0 ] . gl . addr ;
shaderstate . colourarraytype = shaderstate . sourcevbo - > colours_bytes ? GL_UNSIGNED_BYTE : GL_FLOAT ;
shaderstate . pendingtexcoordparts [ 0 ] = 2 ;
shaderstate . pendingtexcoordvbo [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
BE_RenderMeshProgram ( altshader , altshader - > passes , altshader - > prog ) ;
}
2011-12-05 15:23:40 +00:00
break ;
2009-11-04 21:16:50 +00:00
case BEM_DEPTHONLY :
2013-10-29 17:38:22 +00:00
altshader = shaderstate . curshader - > bemoverrides [ bemoverride_depthonly ] ;
if ( ! altshader )
altshader = shaderstate . depthonlyshader ;
if ( altshader & & altshader - > prog )
2015-08-28 03:13:45 +00:00
{
shaderstate . pendingcolourvbo = shaderstate . sourcevbo - > colours [ 0 ] . gl . vbo ;
shaderstate . pendingcolourpointer = shaderstate . sourcevbo - > colours [ 0 ] . gl . addr ;
shaderstate . colourarraytype = shaderstate . sourcevbo - > colours_bytes ? GL_UNSIGNED_BYTE : GL_FLOAT ;
shaderstate . pendingtexcoordparts [ 0 ] = 2 ;
shaderstate . pendingtexcoordvbo [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
BE_RenderMeshProgram ( altshader , altshader - > passes , altshader - > prog ) ;
}
2013-10-08 14:28:11 +00:00
else
{
GL_DeSelectProgram ( ) ;
2011-10-27 16:16:29 +00:00
# ifdef warningmsg
# pragma warningmsg("fixme: support alpha test")
2011-05-29 04:26:29 +00:00
# endif
2013-10-08 14:28:11 +00:00
BE_EnableShaderAttributes ( ( 1u < < VATTR_LEG_VERTEX ) , 0 ) ;
2014-11-05 05:39:24 +00:00
BE_SubmitMeshChain ( false ) ; //fixme: dangerous
2013-10-08 14:28:11 +00:00
}
2009-11-04 21:16:50 +00:00
break ;
2011-02-25 04:22:14 +00:00
case BEM_FOG :
2014-08-25 07:35:41 +00:00
# ifndef GLSLONLY
2012-10-08 04:36:10 +00:00
GenerateTCFog ( 0 , NULL ) ;
2017-11-30 17:59:11 +00:00
BE_EnableShaderAttributes ( ( 1u < < VATTR_LEG_VERTEX ) | ( 1u < < VATTR_LEG_COLOUR ) | ( 1u < < VATTR_LEG_TMU0 ) , 0 ) ;
2014-11-05 05:39:24 +00:00
BE_SubmitMeshChain ( false ) ;
2014-08-25 07:35:41 +00:00
# endif
2011-02-25 04:22:14 +00:00
break ;
2012-08-04 01:35:52 +00:00
case BEM_WIREFRAME :
2017-03-06 14:06:12 +00:00
if ( shaderstate . wireframeshader & & shaderstate . wireframeshader - > prog )
{
shaderstate . pendingcolourvbo = shaderstate . sourcevbo - > colours [ 0 ] . gl . vbo ;
shaderstate . pendingcolourpointer = shaderstate . sourcevbo - > colours [ 0 ] . gl . addr ;
shaderstate . colourarraytype = shaderstate . sourcevbo - > colours_bytes ? GL_UNSIGNED_BYTE : GL_FLOAT ;
shaderstate . pendingtexcoordparts [ 0 ] = 2 ;
shaderstate . pendingtexcoordvbo [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
BE_RenderMeshProgram ( shaderstate . wireframeshader , shaderstate . wireframeshader - > passes , shaderstate . wireframeshader - > prog ) ;
}
2014-08-27 08:41:31 +00:00
# ifndef GLSLONLY
2018-01-22 19:18:04 +00:00
else if ( ! gl_config_nofixedfunc )
2014-08-27 08:41:31 +00:00
{
BE_SetPassBlendMode ( 0 , PBM_REPLACE ) ;
GL_DeSelectProgram ( ) ;
2017-03-06 14:06:12 +00:00
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = NULL ;
Vector4Set ( shaderstate . pendingcolourflat , 1 , 1 , 1 , 1 ) ;
while ( shaderstate . lastpasstmus > 0 )
{
GL_LazyBind ( - - shaderstate . lastpasstmus , 0 , r_nulltex ) ;
}
BE_SendPassBlendDepthMask ( ( shaderstate . curshader - > passes [ 0 ] . shaderbits & ~ SBITS_BLEND_BITS ) | SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | ( ( r_wireframe . ival = = 1 ) ? SBITS_MISC_NODEPTHTEST : 0 ) ) ;
2012-08-04 01:35:52 +00:00
2017-03-06 14:06:12 +00:00
BE_EnableShaderAttributes ( ( 1u < < VATTR_LEG_VERTEX ) | ( 1u < < VATTR_LEG_COLOUR ) , 0 ) ;
BE_SubmitMeshChain ( false ) ;
}
# endif
2012-08-04 01:35:52 +00:00
break ;
2009-11-04 21:16:50 +00:00
case BEM_DEPTHDARK :
2018-12-28 00:04:36 +00:00
if ( ( shaderstate . curshader - > flags & ( SHADER_HASLIGHTMAP | SHADER_NODLIGHT ) ) = = SHADER_HASLIGHTMAP & & ! TEXVALID ( shaderstate . curtexnums - > fullbright ) )
2009-11-04 21:16:50 +00:00
{
2012-11-27 03:23:19 +00:00
if ( gl_config . arb_shader_objects )
2009-11-04 21:16:50 +00:00
{
2014-11-05 05:39:24 +00:00
if ( ! shaderstate . allblackshader . glsl . handle )
2013-10-08 14:28:11 +00:00
{
2014-03-31 17:06:41 +00:00
const char * defs [ ] = { NULL } ;
2017-11-14 14:37:04 +00:00
shaderstate . allblackshader = GLSlang_CreateProgram ( NULL , " allblackprogram " , sh_config . minver , defs , " #include \" sys/skeletal.h \" \n void main(){gl_Position = skeletaltransform();} " , NULL , NULL , NULL , " void main(){gl_FragColor=vec4(0.0,0.0,0.0,1.0);} " , false , NULL ) ;
2014-11-05 05:39:24 +00:00
shaderstate . allblack_mvp = qglGetUniformLocationARB ( shaderstate . allblackshader . glsl . handle , " m_modelviewprojection " ) ;
2013-10-08 14:28:11 +00:00
}
2012-11-27 03:23:19 +00:00
2014-11-05 05:39:24 +00:00
GL_SelectProgram ( shaderstate . allblackshader . glsl . handle ) ;
2012-11-27 03:23:19 +00:00
BE_SendPassBlendDepthMask ( shaderstate . curshader - > passes [ 0 ] . shaderbits ) ;
2014-08-27 08:41:31 +00:00
BE_EnableShaderAttributes ( gl_config_nofixedfunc ? ( 1u < < VATTR_VERTEX1 ) : ( 1u < < VATTR_LEG_VERTEX ) , 0 ) ;
2014-11-05 05:39:24 +00:00
if ( shaderstate . allblackshader . glsl . handle ! = shaderstate . lastuniform & & shaderstate . allblack_mvp ! = - 1 )
2012-11-27 03:23:19 +00:00
{
float m16 [ 16 ] ;
2017-12-15 06:56:40 +00:00
Matrix4_Multiply ( shaderstate . projectionmatrix , shaderstate . modelviewmatrix , m16 ) ;
2013-10-08 14:28:11 +00:00
qglUniformMatrix4fvARB ( shaderstate . allblack_mvp , 1 , false , m16 ) ;
2012-11-27 03:23:19 +00:00
}
2014-11-05 05:39:24 +00:00
BE_SubmitMeshChain ( shaderstate . allblackshader . glsl . usetesselation ) ;
2012-11-27 03:23:19 +00:00
2014-11-05 05:39:24 +00:00
shaderstate . lastuniform = shaderstate . allblackshader . glsl . handle ;
2014-08-27 08:41:31 +00:00
break ;
2009-11-04 21:16:50 +00:00
}
2014-08-27 08:41:31 +00:00
# ifndef GLSLONLY
else if ( ! gl_config_nofixedfunc )
2012-11-27 03:23:19 +00:00
{
GL_DeSelectProgram ( ) ;
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = NULL ;
Vector4Set ( shaderstate . pendingcolourflat , 0 , 0 , 0 , 1 ) ;
while ( shaderstate . lastpasstmus > 0 )
{
GL_LazyBind ( - - shaderstate . lastpasstmus , 0 , r_nulltex ) ;
}
2009-11-04 21:16:50 +00:00
2012-11-27 03:23:19 +00:00
BE_SetPassBlendMode ( 0 , PBM_REPLACE ) ;
BE_SendPassBlendDepthMask ( shaderstate . curshader - > passes [ 0 ] . shaderbits ) ;
BE_EnableShaderAttributes ( ( 1u < < VATTR_LEG_VERTEX ) | ( 1u < < VATTR_LEG_COLOUR ) , 0 ) ;
2014-11-05 05:39:24 +00:00
BE_SubmitMeshChain ( false ) ;
2014-08-27 08:41:31 +00:00
break ;
2012-11-27 03:23:19 +00:00
}
2014-08-27 08:41:31 +00:00
# endif
2009-11-04 21:16:50 +00:00
}
//fallthrough
case BEM_STANDARD :
default :
2011-02-25 04:22:14 +00:00
if ( shaderstate . curshader - > prog )
2011-01-23 03:44:49 +00:00
{
2015-08-28 03:13:45 +00:00
shaderstate . pendingcolourvbo = shaderstate . sourcevbo - > colours [ 0 ] . gl . vbo ;
shaderstate . pendingcolourpointer = shaderstate . sourcevbo - > colours [ 0 ] . gl . addr ;
shaderstate . colourarraytype = shaderstate . sourcevbo - > colours_bytes ? GL_UNSIGNED_BYTE : GL_FLOAT ;
shaderstate . pendingtexcoordparts [ 0 ] = 2 ;
shaderstate . pendingtexcoordvbo [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
BE_RenderMeshProgram ( shaderstate . curshader , shaderstate . curshader - > passes , shaderstate . curshader - > prog ) ;
2011-01-23 03:44:49 +00:00
}
2014-08-25 07:35:41 +00:00
else if ( gl_config_nofixedfunc )
2015-08-28 03:13:45 +00:00
{
# ifdef FTE_TARGET_WEB
int maxverts = 0 , m ;
mesh_t * meshlist ;
for ( m = 0 ; m < shaderstate . meshcount ; m + + )
{
meshlist = shaderstate . meshes [ m ] ;
if ( maxverts < meshlist - > vbofirstvert + meshlist - > numvertexes )
maxverts = meshlist - > vbofirstvert + meshlist - > numvertexes ;
}
# endif
while ( passno < shaderstate . curshader - > numpasses )
{
int emumode ;
p = & shaderstate . curshader - > passes [ passno ] ;
passno + = p - > numMergedPasses ;
emumode = 0 ;
emumode = ( p - > shaderbits & SBITS_ATEST_BITS ) > > SBITS_ATEST_SHIFT ;
GenerateColourMods ( p ) ;
if ( ! shaderstate . colourarraytype )
{
emumode | = 4 ;
shaderstate . lastuniform = 0 ; //FIXME: s_colour uniform might be wrong.
}
# ifdef FTE_TARGET_WEB
else if ( ! shaderstate . pendingcolourvbo & & shaderstate . pendingcolourpointer )
{
shaderstate . streamid = ( shaderstate . streamid + 1 ) & ( sizeof ( shaderstate . streamvbo ) / sizeof ( shaderstate . streamvbo [ 0 ] ) - 1 ) ;
GL_SelectVBO ( shaderstate . pendingcolourvbo = shaderstate . streamvbo [ shaderstate . streamid ] ) ;
switch ( shaderstate . colourarraytype )
{
case GL_FLOAT :
qglBufferDataARB ( GL_ARRAY_BUFFER_ARB , maxverts * sizeof ( vec4_t ) , shaderstate . pendingcolourpointer , GL_STREAM_DRAW_ARB ) ;
break ;
case GL_UNSIGNED_BYTE :
qglBufferDataARB ( GL_ARRAY_BUFFER_ARB , maxverts * sizeof ( byte_vec4_t ) , shaderstate . pendingcolourpointer , GL_STREAM_DRAW_ARB ) ;
break ;
}
shaderstate . pendingcolourpointer = NULL ;
}
# endif
BE_GeneratePassTC ( p , 0 ) ;
# ifdef FTE_TARGET_WEB
if ( ! shaderstate . pendingtexcoordvbo [ 0 ] & & shaderstate . pendingtexcoordpointer [ 0 ] )
{
shaderstate . streamid = ( shaderstate . streamid + 1 ) & ( sizeof ( shaderstate . streamvbo ) / sizeof ( shaderstate . streamvbo [ 0 ] ) - 1 ) ;
GL_SelectVBO ( shaderstate . pendingtexcoordvbo [ 0 ] = shaderstate . streamvbo [ shaderstate . streamid ] ) ;
qglBufferDataARB ( GL_ARRAY_BUFFER_ARB , maxverts * sizeof ( float ) * shaderstate . pendingtexcoordparts [ 0 ] , shaderstate . pendingtexcoordpointer [ 0 ] , GL_STREAM_DRAW_ARB ) ;
shaderstate . pendingtexcoordpointer [ 0 ] = NULL ;
}
# endif
if ( ! shaderstate . programfixedemu [ emumode ] )
{
char * modes [ ] = {
" " , " #ALPHATEST=>0.0 " , " #ALPHATEST=<0.5 " , " #ALPHATEST=>=0.5 " ,
" #UC " , " #ALPHATEST=>0.0#UC " , " #ALPHATEST=<0.5#UC " , " #ALPHATEST=>=0.5#UC "
} ;
shaderstate . programfixedemu [ emumode ] = Shader_FindGeneric ( va ( " fixedemu%s " , modes [ emumode ] ) , QR_OPENGL ) ;
if ( ! shaderstate . programfixedemu [ emumode ] )
break ;
}
BE_RenderMeshProgram ( shaderstate . curshader , p , shaderstate . programfixedemu [ emumode ] ) ;
}
2011-01-23 03:44:49 +00:00
break ;
2015-08-28 03:13:45 +00:00
}
# ifndef GLSLONLY
2009-11-04 21:16:50 +00:00
else
{
while ( passno < shaderstate . curshader - > numpasses )
{
p = & shaderstate . curshader - > passes [ passno ] ;
passno + = p - > numMergedPasses ;
// if (p->flags & SHADER_PASS_DETAIL)
// continue;
2016-11-20 20:52:41 +00:00
if ( p - > prog )
{
shaderstate . pendingcolourvbo = shaderstate . sourcevbo - > colours [ 0 ] . gl . vbo ;
shaderstate . pendingcolourpointer = shaderstate . sourcevbo - > colours [ 0 ] . gl . addr ;
shaderstate . colourarraytype = shaderstate . sourcevbo - > colours_bytes ? GL_UNSIGNED_BYTE : GL_FLOAT ;
shaderstate . pendingtexcoordparts [ 0 ] = 2 ;
shaderstate . pendingtexcoordvbo [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . vbo ;
shaderstate . pendingtexcoordpointer [ 0 ] = shaderstate . sourcevbo - > texcoord . gl . addr ;
BE_RenderMeshProgram ( shaderstate . curshader , p , p - > prog ) ;
}
else
{
GL_DeSelectProgram ( ) ;
DrawPass ( p ) ;
}
2009-11-04 21:16:50 +00:00
}
}
2013-07-31 18:00:11 +00:00
if ( shaderstate . curbatch - > fog & & shaderstate . curbatch - > fog - > shader )
2012-10-08 04:36:10 +00:00
{
2017-11-30 17:59:11 +00:00
//FIXME: if glsl, do this fog volume crap properly!
2012-10-08 04:36:10 +00:00
GL_DeSelectProgram ( ) ;
GenerateFogTexture ( & shaderstate . fogtexture , shaderstate . curbatch - > fog - > shader - > fog_dist , 2048 ) ;
shaderstate . fogfar = 1.0f / 2048 ; /*scaler for z coords*/
2014-10-05 20:04:11 +00:00
while ( shaderstate . lastpasstmus > 1 )
2012-10-08 04:36:10 +00:00
{
GL_LazyBind ( - - shaderstate . lastpasstmus , 0 , r_nulltex ) ;
}
GL_LazyBind ( 0 , GL_TEXTURE_2D , shaderstate . fogtexture ) ;
shaderstate . lastpasstmus = 1 ;
Vector4Scale ( shaderstate . curbatch - > fog - > shader - > fog_color , ( 1 / 255.0 ) , shaderstate . pendingcolourflat ) ;
shaderstate . pendingcolourvbo = 0 ;
shaderstate . pendingcolourpointer = NULL ;
BE_SetPassBlendMode ( 0 , PBM_MODULATE ) ;
2018-04-27 16:40:50 +00:00
BE_SendPassBlendDepthMask ( SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA | ( shaderstate . curshader - > numpasses ? SBITS_DEPTHFUNC_EQUAL : 0 ) ) ;
2012-10-08 04:36:10 +00:00
GenerateTCFog ( 0 , shaderstate . curbatch - > fog ) ;
2012-11-27 03:23:19 +00:00
BE_EnableShaderAttributes ( ( 1u < < VATTR_LEG_VERTEX ) | ( 1u < < VATTR_LEG_COLOUR ) | ( 1u < < VATTR_LEG_TMU0 ) , 0 ) ;
2014-11-05 05:39:24 +00:00
BE_SubmitMeshChain ( false ) ;
2012-10-08 04:36:10 +00:00
}
2009-11-04 21:16:50 +00:00
break ;
2014-08-25 07:35:41 +00:00
# endif
2009-11-04 21:16:50 +00:00
}
}
2013-04-04 16:24:43 +00:00
static qboolean BE_GenTempMeshVBO ( vbo_t * * vbo , mesh_t * m )
{
* vbo = & shaderstate . dummyvbo ;
//this code is shit shit shit.
2013-04-06 08:38:40 +00:00
if ( shaderstate . streamvbo [ 0 ] )
2013-04-04 16:24:43 +00:00
{
2013-04-06 08:38:40 +00:00
//use a local. can't use a static, that crashes the compiler due to memory use, so lets eat the malloc or stack or whatever because we really don't have a choice.
2013-05-03 04:28:08 +00:00
static char * buffer ;
2013-05-10 15:20:47 +00:00
size_t len = 0 ;
2013-05-03 04:28:08 +00:00
if ( ! buffer )
buffer = malloc ( 65536 * 33 * sizeof ( float ) ) ;
2013-04-06 08:38:40 +00:00
//we're not doing vao... but just in case someone added that as an extension...
2013-04-04 16:24:43 +00:00
GL_DeselectVAO ( ) ;
2013-04-06 08:38:40 +00:00
//cycle the vbo. this reduces the likelyhood that we'll have to wait for the vbo to no longer be in use.
//remember, we can't do nice things like orphan in webgl. we have to create a new buffer every single time.
//we can't stream with BufferSubData, because browsers are pure shite, and probably mmap and read back huge blocks of code as they translate the calls to direct3d nonsense.
//we can't use client memory and let the driver do the right thing, because lets face it, our driver is technically a browser. its safer to run everything in a scripted language than to fight the nonsense.
//how many buffers do we need? no idea. all this memory allocation is going to be shit for performance.
//but we really do not have a choice. This is the only way to 'stream' without dropping down to <1fps.
//although arguably we should build our entire hud+2d stuff into a single vbo each frame... meh. At least this keeps the memory use in the driver's 64bit memory space instead of the browser's 32bit one...
shaderstate . streamid = ( shaderstate . streamid + 1 ) & ( sizeof ( shaderstate . streamvbo ) / sizeof ( shaderstate . streamvbo [ 0 ] ) - 1 ) ;
2013-05-03 04:28:08 +00:00
shaderstate . dummyvbo . vao = shaderstate . streamvao [ shaderstate . streamid ] ;
shaderstate . dummyvbo . vaodynamic = ~ 0 ;
shaderstate . dummyvbo . vaoenabled = 0 ;
if ( shaderstate . dummyvbo . vao )
{
qglBindVertexArray ( shaderstate . dummyvbo . vao ) ;
shaderstate . currentvao = shaderstate . dummyvbo . vao ;
}
2013-04-06 08:38:40 +00:00
GL_SelectVBO ( shaderstate . streamvbo [ shaderstate . streamid ] ) ;
GL_SelectEBO ( shaderstate . streamebo [ shaderstate . streamid ] ) ;
memcpy ( buffer + len , m - > xyz_array , sizeof ( * m - > xyz_array ) * m - > numvertexes ) ;
shaderstate . dummyvbo . coord . gl . addr = ( void * ) len ;
shaderstate . dummyvbo . coord . gl . vbo = shaderstate . streamvbo [ shaderstate . streamid ] ;
len + = sizeof ( * m - > xyz_array ) * m - > numvertexes ;
2013-04-04 16:24:43 +00:00
if ( m - > xyz2_array )
{
2013-04-06 08:38:40 +00:00
memcpy ( buffer + len , m - > xyz2_array , sizeof ( * m - > xyz2_array ) * m - > numvertexes ) ;
shaderstate . dummyvbo . coord2 . gl . addr = ( void * ) len ;
shaderstate . dummyvbo . coord2 . gl . vbo = shaderstate . streamvbo [ shaderstate . streamid ] ;
len + = sizeof ( * m - > xyz2_array ) * m - > numvertexes ;
2013-04-04 16:24:43 +00:00
}
else
{
shaderstate . dummyvbo . coord2 . gl . addr = NULL ;
shaderstate . dummyvbo . coord2 . gl . vbo = 0 ;
}
2013-04-06 08:38:40 +00:00
memcpy ( buffer + len , m - > st_array , sizeof ( * m - > st_array ) * m - > numvertexes ) ;
shaderstate . dummyvbo . texcoord . gl . addr = ( void * ) len ;
shaderstate . dummyvbo . texcoord . gl . vbo = shaderstate . streamvbo [ shaderstate . streamid ] ;
len + = sizeof ( * m - > st_array ) * m - > numvertexes ;
//FIXME: lightmaps
2013-08-27 13:18:09 +00:00
if ( m - > colors4f_array [ 0 ] )
2013-04-04 16:24:43 +00:00
{
2013-08-27 13:18:09 +00:00
memcpy ( buffer + len , m - > colors4f_array [ 0 ] , sizeof ( * m - > colors4f_array [ 0 ] ) * m - > numvertexes ) ;
shaderstate . dummyvbo . colours [ 0 ] . gl . addr = ( void * ) len ;
shaderstate . dummyvbo . colours [ 0 ] . gl . vbo = shaderstate . streamvbo [ shaderstate . streamid ] ;
len + = sizeof ( * m - > colors4f_array [ 0 ] ) * m - > numvertexes ;
2015-08-28 03:13:45 +00:00
shaderstate . dummyvbo . colours_bytes = false ;
2013-04-04 16:24:43 +00:00
}
else if ( m - > colors4b_array )
{
2013-04-06 08:38:40 +00:00
memcpy ( buffer + len , m - > colors4b_array , sizeof ( * m - > colors4b_array ) * m - > numvertexes ) ;
2013-08-27 13:18:09 +00:00
shaderstate . dummyvbo . colours [ 0 ] . gl . addr = ( void * ) len ;
shaderstate . dummyvbo . colours [ 0 ] . gl . vbo = shaderstate . streamvbo [ shaderstate . streamid ] ;
2013-04-06 08:38:40 +00:00
len + = sizeof ( * m - > colors4b_array ) * m - > numvertexes ;
2015-08-28 03:13:45 +00:00
shaderstate . dummyvbo . colours_bytes = true ;
2013-04-04 16:24:43 +00:00
}
else
{
2013-08-27 13:18:09 +00:00
shaderstate . dummyvbo . colours [ 0 ] . gl . addr = NULL ;
shaderstate . dummyvbo . colours [ 0 ] . gl . vbo = 0 ;
2015-08-28 03:13:45 +00:00
shaderstate . dummyvbo . colours_bytes = false ;
2013-04-04 16:24:43 +00:00
}
2013-04-06 08:38:40 +00:00
2015-04-21 20:08:55 +00:00
if ( m - > normals_array )
{
memcpy ( buffer + len , m - > normals_array , sizeof ( * m - > normals_array ) * m - > numvertexes ) ;
shaderstate . dummyvbo . normals . gl . addr = ( void * ) len ;
shaderstate . dummyvbo . normals . gl . vbo = shaderstate . streamvbo [ shaderstate . streamid ] ;
len + = sizeof ( * m - > normals_array ) * m - > numvertexes ;
}
else
{
shaderstate . dummyvbo . normals . gl . addr = NULL ;
shaderstate . dummyvbo . normals . gl . vbo = 0 ;
}
2015-09-01 04:45:15 +00:00
if ( m - > snormals_array )
{
memcpy ( buffer + len , m - > snormals_array , sizeof ( * m - > snormals_array ) * m - > numvertexes ) ;
shaderstate . dummyvbo . svector . gl . addr = ( void * ) len ;
shaderstate . dummyvbo . svector . gl . vbo = shaderstate . streamvbo [ shaderstate . streamid ] ;
len + = sizeof ( * m - > snormals_array ) * m - > numvertexes ;
}
else
{
shaderstate . dummyvbo . svector . gl . addr = NULL ;
shaderstate . dummyvbo . svector . gl . vbo = 0 ;
}
if ( m - > tnormals_array )
{
memcpy ( buffer + len , m - > tnormals_array , sizeof ( * m - > tnormals_array ) * m - > numvertexes ) ;
shaderstate . dummyvbo . tvector . gl . addr = ( void * ) len ;
shaderstate . dummyvbo . tvector . gl . vbo = shaderstate . streamvbo [ shaderstate . streamid ] ;
len + = sizeof ( * m - > tnormals_array ) * m - > numvertexes ;
}
else
{
shaderstate . dummyvbo . tvector . gl . addr = NULL ;
shaderstate . dummyvbo . tvector . gl . vbo = 0 ;
}
2015-04-21 20:08:55 +00:00
if ( m - > bonenums )
{
memcpy ( buffer + len , m - > bonenums , sizeof ( * m - > bonenums ) * m - > numvertexes ) ;
shaderstate . dummyvbo . bonenums . gl . addr = ( void * ) len ;
shaderstate . dummyvbo . bonenums . gl . vbo = shaderstate . streamvbo [ shaderstate . streamid ] ;
len + = sizeof ( * m - > bonenums ) * m - > numvertexes ;
}
else
{
shaderstate . dummyvbo . bonenums . gl . addr = NULL ;
shaderstate . dummyvbo . bonenums . gl . vbo = 0 ;
}
if ( m - > boneweights )
{
memcpy ( buffer + len , m - > boneweights , sizeof ( * m - > boneweights ) * m - > numvertexes ) ;
shaderstate . dummyvbo . boneweights . gl . addr = ( void * ) len ;
shaderstate . dummyvbo . boneweights . gl . vbo = shaderstate . streamvbo [ shaderstate . streamid ] ;
len + = sizeof ( * m - > boneweights ) * m - > numvertexes ;
}
else
{
shaderstate . dummyvbo . boneweights . gl . addr = NULL ;
shaderstate . dummyvbo . boneweights . gl . vbo = 0 ;
}
2013-04-06 08:38:40 +00:00
//FIXME: normals, svector, tvector, bone nums, bone weights
//now we've got a single buffer in a single place, update the buffer
qglBufferDataARB ( GL_ARRAY_BUFFER_ARB , len , buffer , GL_STREAM_DRAW_ARB ) ;
2013-04-04 16:24:43 +00:00
//and finally the elements array, which is a much simpler affair
2013-04-06 03:36:00 +00:00
qglBufferDataARB ( GL_ELEMENT_ARRAY_BUFFER_ARB , sizeof ( * m - > indexes ) * m - > numindexes , m - > indexes , GL_STREAM_DRAW_ARB ) ;
shaderstate . dummyvbo . indicies . gl . addr = ( void * ) NULL ;
2013-04-06 08:38:40 +00:00
shaderstate . dummyvbo . indicies . gl . vbo = shaderstate . streamebo [ shaderstate . streamid ] ;
2013-04-04 16:24:43 +00:00
}
else
{
2013-04-06 08:38:40 +00:00
//client memory. may be slower. will probably be faster.
2013-04-04 16:24:43 +00:00
shaderstate . dummyvbo . coord . gl . addr = m - > xyz_array ;
shaderstate . dummyvbo . coord2 . gl . addr = m - > xyz2_array ;
shaderstate . dummyvbo . texcoord . gl . addr = m - > st_array ;
shaderstate . dummyvbo . indicies . gl . addr = m - > indexes ;
shaderstate . dummyvbo . normals . gl . addr = m - > normals_array ;
shaderstate . dummyvbo . svector . gl . addr = m - > snormals_array ;
shaderstate . dummyvbo . tvector . gl . addr = m - > tnormals_array ;
2013-08-27 13:18:09 +00:00
if ( m - > colors4f_array [ 0 ] )
2013-04-04 16:24:43 +00:00
{
2015-08-28 03:13:45 +00:00
shaderstate . dummyvbo . colours_bytes = false ;
2013-08-27 13:18:09 +00:00
shaderstate . dummyvbo . colours [ 0 ] . gl . addr = m - > colors4f_array [ 0 ] ;
2013-04-04 16:24:43 +00:00
}
else
{
2015-08-28 03:13:45 +00:00
shaderstate . dummyvbo . colours_bytes = true ;
2013-08-27 13:18:09 +00:00
shaderstate . dummyvbo . colours [ 0 ] . gl . addr = m - > colors4b_array ;
2013-04-04 16:24:43 +00:00
}
shaderstate . dummyvbo . bonenums . gl . addr = m - > bonenums ;
shaderstate . dummyvbo . boneweights . gl . addr = m - > boneweights ;
}
shaderstate . dummyvbo . bones = m - > bones ;
shaderstate . dummyvbo . numbones = m - > numbones ;
shaderstate . meshcount = 1 ;
shaderstate . meshes = & m ;
return true ;
}
2011-04-20 23:34:13 +00:00
void GLBE_DrawMesh_List ( shader_t * shader , int nummeshes , mesh_t * * meshlist , vbo_t * vbo , texnums_t * texnums , unsigned int beflags )
2009-11-04 21:16:50 +00:00
{
2012-07-05 19:42:36 +00:00
shaderstate . curbatch = & shaderstate . dummybatch ;
2014-02-13 23:54:57 +00:00
shaderstate . curshader = shader - > remapto ;
2015-05-03 19:57:46 +00:00
2009-11-04 21:16:50 +00:00
if ( ! vbo )
{
mesh_t * m ;
2011-04-20 23:34:13 +00:00
shaderstate . flags = beflags ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " GLBE_DrawMesh_List: shader %s \n " , shader - > name ) ) ;
2010-08-28 17:14:38 +00:00
if ( shaderstate . curentity ! = & r_worldentity )
2012-11-27 03:23:19 +00:00
GLBE_SelectEntity ( & r_worldentity ) ;
2014-02-13 23:54:57 +00:00
shaderstate . curtime = shaderstate . updatetime - ( shaderstate . curentity - > shaderTime + shader - > remaptime ) ;
2015-05-03 19:57:46 +00:00
if ( texnums )
shaderstate . curtexnums = texnums ;
else if ( shader - > numdefaulttextures )
shaderstate . curtexnums = shader - > defaulttextures + ( ( int ) ( shader - > defaulttextures_fps * shaderstate . curtime ) % shader - > numdefaulttextures ) ;
else
shaderstate . curtexnums = shader - > defaulttextures ;
2009-11-04 21:16:50 +00:00
2010-07-11 02:22:39 +00:00
while ( nummeshes - - )
2009-11-04 21:16:50 +00:00
{
2010-07-11 02:22:39 +00:00
m = * meshlist + + ;
2009-11-04 21:16:50 +00:00
2013-04-04 16:24:43 +00:00
if ( ! BE_GenTempMeshVBO ( & shaderstate . sourcevbo , m ) )
continue ;
2009-11-04 21:16:50 +00:00
2010-07-11 02:22:39 +00:00
shaderstate . meshcount = 1 ;
shaderstate . meshes = & m ;
DrawMeshes ( ) ;
2009-11-04 21:16:50 +00:00
}
}
else
{
shaderstate . sourcevbo = vbo ;
2011-04-20 23:34:13 +00:00
shaderstate . flags = beflags ;
2010-08-28 17:14:38 +00:00
if ( shaderstate . curentity ! = & r_worldentity )
2012-11-27 03:23:19 +00:00
GLBE_SelectEntity ( & r_worldentity ) ;
2014-02-13 23:54:57 +00:00
shaderstate . curtime = shaderstate . updatetime - ( shaderstate . curentity - > shaderTime + shader - > remaptime ) ;
2015-05-03 19:57:46 +00:00
if ( texnums )
shaderstate . curtexnums = texnums ;
else if ( shader - > numdefaulttextures )
shaderstate . curtexnums = shader - > defaulttextures + ( ( int ) ( shader - > defaulttextures_fps * shaderstate . curtime ) % shader - > numdefaulttextures ) ;
else
shaderstate . curtexnums = shader - > defaulttextures ;
2009-11-04 21:16:50 +00:00
2010-07-11 02:22:39 +00:00
shaderstate . meshcount = nummeshes ;
shaderstate . meshes = meshlist ;
DrawMeshes ( ) ;
2009-11-04 21:16:50 +00:00
}
}
2015-05-03 19:57:46 +00:00
void GLBE_DrawMesh_Single ( shader_t * shader , mesh_t * mesh , vbo_t * vbo , unsigned int beflags )
2009-11-04 21:16:50 +00:00
{
2010-07-11 02:22:39 +00:00
shader - > next = NULL ;
added r_meshpitch cvar that allows for fixing the unfixable mesh pitch bug from vanilla... needs a better name... do note that this will break pretty much any mod, so this is really only for TCs designed to use it. Its likely that I missed places.
nqsv: added support for spectators with nq clients. the angles are a bit rough, but hey. need to do something about frags so nq clients know who's a spectator. use 'cmd observe' to get an nq client to spectate on an fte server (then attack/jump behave the same as in qw clients).
nqsv: rewrote EF_MUZZLEFLASH handling, so svc_muzzleflash is now translated properly to EF_MUZZLEFLASH, and vice versa. No more missing muzzleflashes!
added screenshot_cubemap, so you can actually pre-generate cubemaps with fte (which can be used for reflections or whatever).
misc fixes (server crash, a couple of other less important ones).
external files based on a model's name will now obey r_replacemodels properly, instead of needing to use foo.mdl_0.skin for foo.md3.
identify <playernum> should now use the correct masked ip, instead of abrubtly failing (reported by kt)
vid_toggle console command should now obey vid_width and vid_height when switching to fullscreen, but only if vid_fullscreen is actually set, which should make it seem better behaved (reported by kt).
qcc: cleaned up sym->symboldata[sym->ofs] to be more consistent at all stages.
qcc: typedef float vec4[4]; now works to define a float array with 4 elements (however, it will be passed by-value rather than by-reference).
qcc: cleaned up optional vs __out ordering issues.
qccgui: shift+f3 searches backwards
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5064 fc73d0e0-1445-4013-8a0c-d673dee63da5
2017-02-27 09:34:35 +00:00
GLBE_DrawMesh_List ( shader , 1 , & mesh , NULL , NULL , beflags ) ;
2009-11-04 21:16:50 +00:00
}
2011-01-04 02:56:16 +00:00
void GLBE_SubmitBatch ( batch_t * batch )
2010-07-11 02:22:39 +00:00
{
2015-05-03 19:57:46 +00:00
shader_t * sh ;
2012-07-05 19:42:36 +00:00
shaderstate . curbatch = batch ;
2012-04-09 19:12:12 +00:00
if ( batch - > vbo )
2010-08-28 17:14:38 +00:00
{
2012-04-09 19:12:12 +00:00
shaderstate . sourcevbo = batch - > vbo ;
2015-08-04 15:16:24 +00:00
if ( ! batch - > vbo - > vao )
batch - > vbo - > vao = shaderstate . streamvao [ 0 ] ;
batch - > vbo - > vaodynamic = ~ 0 ;
batch - > vbo - > vaoenabled = 0 ;
2010-08-28 17:14:38 +00:00
}
else
{
2013-04-04 16:24:43 +00:00
//we're only allowed one mesh per batch if there's no vbo info.
if ( ! BE_GenTempMeshVBO ( & shaderstate . sourcevbo , batch - > mesh [ 0 ] ) )
return ;
2010-08-28 17:14:38 +00:00
}
2015-05-03 19:57:46 +00:00
sh = batch - > shader ;
shaderstate . curshader = sh - > remapto ;
2011-04-20 23:34:13 +00:00
shaderstate . flags = batch - > flags ;
2010-08-28 17:14:38 +00:00
if ( shaderstate . curentity ! = batch - > ent )
2012-11-27 03:23:19 +00:00
GLBE_SelectEntity ( batch - > ent ) ;
2015-05-03 19:57:46 +00:00
shaderstate . curtime = shaderstate . updatetime - ( shaderstate . curentity - > shaderTime + sh - > remaptime ) ;
2010-08-28 17:14:38 +00:00
if ( batch - > skin )
shaderstate . curtexnums = batch - > skin ;
2015-05-03 19:57:46 +00:00
else if ( sh - > numdefaulttextures )
shaderstate . curtexnums = sh - > defaulttextures + ( ( int ) ( sh - > defaulttextures_fps * shaderstate . curtime ) % sh - > numdefaulttextures ) ;
2010-08-28 17:14:38 +00:00
else
2015-05-03 19:57:46 +00:00
shaderstate . curtexnums = sh - > defaulttextures ;
2005-09-08 22:52:46 +00:00
2010-07-11 02:22:39 +00:00
if ( 0 )
{
int i ;
for ( i = batch - > firstmesh ; i < batch - > meshes ; i + + )
2009-05-21 09:36:18 +00:00
{
2010-07-11 02:22:39 +00:00
shaderstate . meshcount = 1 ;
shaderstate . meshes = & batch - > mesh [ i ] ;
DrawMeshes ( ) ;
2005-09-08 22:52:46 +00:00
}
}
2010-07-11 02:22:39 +00:00
else
{
shaderstate . meshcount = batch - > meshes - batch - > firstmesh ;
shaderstate . meshes = batch - > mesh + batch - > firstmesh ;
DrawMeshes ( ) ;
2009-11-04 21:16:50 +00:00
}
}
2012-05-09 15:30:53 +00:00
static void GLBE_SubmitMeshesPortals ( batch_t * * worldlist , batch_t * dynamiclist )
2009-11-04 21:16:50 +00:00
{
2013-12-29 22:48:28 +00:00
batch_t * batch , * masklists [ 2 ] ;
2010-08-28 17:14:38 +00:00
int i ;
2017-08-29 02:29:06 +00:00
float il ;
2016-12-07 18:45:25 +00:00
if ( ! dynamiclist & & ! worldlist [ SHADER_SORT_PORTAL ] )
return ; //no portals to draw
2010-08-28 17:14:38 +00:00
/*attempt to draw portal shaders*/
if ( shaderstate . mode = = BEM_STANDARD )
2009-11-04 21:16:50 +00:00
{
2010-08-28 17:14:38 +00:00
for ( i = 0 ; i < 2 ; i + + )
2010-07-11 02:22:39 +00:00
{
2010-08-29 13:49:43 +00:00
for ( batch = i ? dynamiclist : worldlist [ SHADER_SORT_PORTAL ] ; batch ; batch = batch - > next )
2010-07-11 02:22:39 +00:00
{
if ( batch - > meshes = = batch - > firstmesh )
continue ;
2004-10-19 16:10:14 +00:00
2010-08-29 13:49:43 +00:00
if ( batch - > buildmeshes )
batch - > buildmeshes ( batch ) ;
2017-08-29 02:29:06 +00:00
il = shaderstate . identitylighting ;
2013-12-29 22:48:28 +00:00
masklists [ 0 ] = worldlist [ SHADER_SORT_PORTAL ] ;
masklists [ 1 ] = dynamiclist ;
GLR_DrawPortal ( batch , worldlist , masklists , 0 ) ;
2017-08-29 02:29:06 +00:00
shaderstate . identitylighting = il ;
2004-10-19 16:10:14 +00:00
2010-07-11 02:22:39 +00:00
/*clear depth again*/
GL_ForceDepthWritable ( ) ;
qglClear ( GL_DEPTH_BUFFER_BIT ) ;
}
2004-10-19 16:10:14 +00:00
}
2013-12-29 22:48:28 +00:00
//make sure the current scene doesn't draw over the portal where its not meant to. clamp depth so the near clip plane doesn't cause problems.
if ( gl_config . arb_depth_clamp )
qglEnable ( GL_DEPTH_CLAMP_ARB ) ;
2016-12-07 18:45:25 +00:00
/*draw depth only, to mask it off*/
GLBE_SelectMode ( BEM_DEPTHONLY ) ;
2013-12-29 22:48:28 +00:00
for ( i = 0 ; i < 2 ; i + + )
{
for ( batch = i ? dynamiclist : worldlist [ SHADER_SORT_PORTAL ] ; batch ; batch = batch - > next )
{
2016-12-07 18:45:25 +00:00
// if (batch->meshes == batch->firstmesh)
// continue;
2013-12-29 22:48:28 +00:00
GLBE_SubmitBatch ( batch ) ;
}
}
2016-12-07 18:45:25 +00:00
GLBE_SelectMode ( BEM_STANDARD ) ;
2013-12-29 22:48:28 +00:00
if ( gl_config . arb_depth_clamp )
qglDisable ( GL_DEPTH_CLAMP_ARB ) ;
2004-10-19 16:10:14 +00:00
}
2010-08-28 17:14:38 +00:00
}
2004-10-19 16:10:14 +00:00
2018-07-22 11:49:37 +00:00
static qboolean GLBE_GenerateBatchTextures ( batch_t * batch , shader_t * bs )
{
int oldfbo ;
float oldil ;
int oldbem ;
if ( r_refdef . recurse = = r_portalrecursion . ival | | r_refdef . recurse = = R_MAX_RECURSE )
return false ;
//these flags require rendering some view as an fbo
//(BEM_DEPTHDARK is used when lightmap scale is 0, but still shows any emissive stuff)
if ( shaderstate . mode ! = BEM_STANDARD & & shaderstate . mode ! = BEM_DEPTHDARK )
return false ;
oldbem = shaderstate . mode ;
oldil = shaderstate . identitylighting ;
if ( ( bs - > flags & SHADER_HASREFLECT ) & & gl_config . ext_framebuffer_objects )
{
float renderscale = bs - > portalfboscale ;
vrect_t orect = r_refdef . vrect ;
pxrect_t oprect = r_refdef . pxrect ;
if ( ! shaderstate . tex_reflection [ r_refdef . recurse ] )
{
shaderstate . tex_reflection [ r_refdef . recurse ] = Image_CreateTexture ( " ***tex_reflection*** " , NULL , 0 ) ;
if ( ! shaderstate . tex_reflection [ r_refdef . recurse ] - > num )
qglGenTextures ( 1 , & shaderstate . tex_reflection [ r_refdef . recurse ] - > num ) ;
}
r_refdef . vrect . x = 0 ;
r_refdef . vrect . y = 0 ;
r_refdef . vrect . width = max ( 1 , vid . fbvwidth * renderscale ) ;
r_refdef . vrect . height = max ( 1 , vid . fbvheight * renderscale ) ;
r_refdef . pxrect . x = 0 ;
r_refdef . pxrect . y = 0 ;
r_refdef . pxrect . width = max ( 1 , vid . fbpwidth * renderscale ) ;
r_refdef . pxrect . height = max ( 1 , vid . fbpheight * renderscale ) ;
if ( shaderstate . tex_reflection [ r_refdef . recurse ] - > width ! = r_refdef . pxrect . width | | shaderstate . tex_reflection [ r_refdef . recurse ] - > height ! = r_refdef . pxrect . height )
{
shaderstate . tex_reflection [ r_refdef . recurse ] - > width = r_refdef . pxrect . width ;
shaderstate . tex_reflection [ r_refdef . recurse ] - > height = r_refdef . pxrect . height ;
GL_MTBind ( 0 , GL_TEXTURE_2D , shaderstate . tex_reflection [ r_refdef . recurse ] ) ;
if ( ( vid . flags & VID_FP16 ) & & sh_config . texfmt [ PTI_RGBA16F ] )
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA16F_ARB , shaderstate . tex_reflection [ r_refdef . recurse ] - > width , shaderstate . tex_reflection [ r_refdef . recurse ] - > height , 0 , GL_RGBA , GL_UNSIGNED_BYTE , NULL ) ;
else if ( ( vid . flags & ( VID_SRGBAWARE | VID_FP16 ) ) & & sh_config . texfmt [ PTI_RGBA8_SRGB ] )
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_SRGB8_ALPHA8_EXT , shaderstate . tex_reflection [ r_refdef . recurse ] - > width , shaderstate . tex_reflection [ r_refdef . recurse ] - > height , 0 , GL_RGBA , GL_UNSIGNED_BYTE , NULL ) ;
else
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , shaderstate . tex_reflection [ r_refdef . recurse ] - > width , shaderstate . tex_reflection [ r_refdef . recurse ] - > height , 0 , GL_RGBA , GL_UNSIGNED_BYTE , NULL ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
}
oldfbo = GLBE_FBO_Update ( & shaderstate . fbo_reflectrefrac [ r_refdef . recurse ] , FBO_RB_DEPTH , & shaderstate . tex_reflection [ r_refdef . recurse ] , 1 , r_nulltex , shaderstate . tex_reflection [ r_refdef . recurse ] - > width , shaderstate . tex_reflection [ r_refdef . recurse ] - > height , 0 ) ;
r_refdef . pxrect . maxheight = shaderstate . fbo_reflectrefrac [ r_refdef . recurse ] . rb_size [ 1 ] ;
GL_ViewportUpdate ( ) ;
GL_ForceDepthWritable ( ) ;
qglClearColor ( 0 , 0 , 0 , 1 ) ;
qglClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
GLR_DrawPortal ( batch , cl . worldmodel - > batches , NULL , 1 ) ;
GLBE_FBO_Pop ( oldfbo ) ;
r_refdef . vrect = orect ;
r_refdef . pxrect = oprect ;
GL_ViewportUpdate ( ) ;
}
if ( bs - > flags & ( SHADER_HASREFRACT | SHADER_HASREFRACTDEPTH ) )
{
if ( r_refract_fboival | | ( bs - > flags & SHADER_HASPORTAL ) )
{
float renderscale = min ( 1 , bs - > portalfboscale ) ;
vrect_t ovrect = r_refdef . vrect ;
pxrect_t oprect = r_refdef . pxrect ;
r_refdef . vrect . x = 0 ;
r_refdef . vrect . y = 0 ;
r_refdef . vrect . width = max ( 1 , vid . fbvwidth * renderscale ) ;
r_refdef . vrect . height = max ( 1 , vid . fbvheight * renderscale ) ;
r_refdef . pxrect . x = 0 ;
r_refdef . pxrect . y = 0 ;
r_refdef . pxrect . width = max ( 1 , vid . fbpwidth * renderscale ) ;
r_refdef . pxrect . height = max ( 1 , vid . fbpheight * renderscale ) ;
if ( ! shaderstate . tex_refraction [ r_refdef . recurse ] )
{
shaderstate . tex_refraction [ r_refdef . recurse ] = Image_CreateTexture ( " ***tex_refraction*** " , NULL , 0 ) ;
if ( ! shaderstate . tex_refraction [ r_refdef . recurse ] - > num )
qglGenTextures ( 1 , & shaderstate . tex_refraction [ r_refdef . recurse ] - > num ) ;
}
if ( shaderstate . tex_refraction [ r_refdef . recurse ] - > width ! = r_refdef . pxrect . width | | shaderstate . tex_refraction [ r_refdef . recurse ] - > height ! = r_refdef . pxrect . height )
{
shaderstate . tex_refraction [ r_refdef . recurse ] - > width = r_refdef . pxrect . width ;
shaderstate . tex_refraction [ r_refdef . recurse ] - > height = r_refdef . pxrect . height ;
GL_MTBind ( 0 , GL_TEXTURE_2D , shaderstate . tex_refraction [ r_refdef . recurse ] ) ;
if ( ( vid . flags & VID_FP16 ) & & sh_config . texfmt [ PTI_RGBA16F ] )
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA16F_ARB , r_refdef . pxrect . width , r_refdef . pxrect . height , 0 , GL_RGBA , GL_UNSIGNED_BYTE , NULL ) ;
else if ( ( vid . flags & ( VID_SRGBAWARE | VID_FP16 ) ) & & sh_config . texfmt [ PTI_RGBA16F ] )
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_SRGB8_ALPHA8_EXT , r_refdef . pxrect . width , r_refdef . pxrect . height , 0 , GL_RGBA , GL_UNSIGNED_BYTE , NULL ) ;
else
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , r_refdef . pxrect . width , r_refdef . pxrect . height , 0 , GL_RGBA , GL_UNSIGNED_BYTE , NULL ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
}
if ( bs - > flags & SHADER_HASREFRACTDEPTH )
{
if ( ! shaderstate . tex_refractiondepth [ r_refdef . recurse ] )
{
shaderstate . tex_refractiondepth [ r_refdef . recurse ] = Image_CreateTexture ( " ***tex_refractiondepth*** " , NULL , 0 ) ;
if ( ! shaderstate . tex_refractiondepth [ r_refdef . recurse ] - > num )
qglGenTextures ( 1 , & shaderstate . tex_refractiondepth [ r_refdef . recurse ] - > num ) ;
}
if ( shaderstate . tex_refractiondepth [ r_refdef . recurse ] - > width ! = r_refdef . pxrect . width | | shaderstate . tex_refractiondepth [ r_refdef . recurse ] - > height ! = r_refdef . pxrect . height )
{
shaderstate . tex_refractiondepth [ r_refdef . recurse ] - > width = r_refdef . pxrect . width ;
shaderstate . tex_refractiondepth [ r_refdef . recurse ] - > height = r_refdef . pxrect . height ;
GL_MTBind ( 0 , GL_TEXTURE_2D , shaderstate . tex_refractiondepth [ r_refdef . recurse ] ) ;
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_DEPTH_COMPONENT24_ARB , r_refdef . pxrect . width , r_refdef . pxrect . height , 0 , GL_DEPTH_COMPONENT , GL_UNSIGNED_BYTE , NULL ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
}
oldfbo = GLBE_FBO_Update ( & shaderstate . fbo_reflectrefrac [ r_refdef . recurse ] , FBO_TEX_DEPTH , & shaderstate . tex_refraction [ r_refdef . recurse ] , 1 , shaderstate . tex_refractiondepth [ r_refdef . recurse ] , r_refdef . pxrect . width , r_refdef . pxrect . height , 0 ) ;
}
else
{
oldfbo = GLBE_FBO_Update ( & shaderstate . fbo_reflectrefrac [ r_refdef . recurse ] , FBO_RB_DEPTH , & shaderstate . tex_refraction [ r_refdef . recurse ] , 1 , r_nulltex , r_refdef . pxrect . width , r_refdef . pxrect . height , 0 ) ;
}
r_refdef . pxrect . maxheight = shaderstate . fbo_reflectrefrac [ r_refdef . recurse ] . rb_size [ 1 ] ;
GL_ViewportUpdate ( ) ;
GL_ForceDepthWritable ( ) ;
qglClearColor ( 0 , 0 , 0 , 1 ) ;
qglClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
if ( bs - > flags & SHADER_HASPORTAL )
GLR_DrawPortal ( batch , cl . worldmodel - > batches , NULL , 0 ) ;
else
GLR_DrawPortal ( batch , cl . worldmodel - > batches , NULL , ( ( bs - > flags & SHADER_HASREFRACTDEPTH ) ? 3 : 2 ) ) ; //fixme
GLBE_FBO_Pop ( oldfbo ) ;
r_refdef . vrect = ovrect ;
r_refdef . pxrect = oprect ;
GL_ViewportUpdate ( ) ;
}
else
GLR_DrawPortal ( batch , cl . worldmodel - > batches , NULL , 3 ) ;
}
if ( ( bs - > flags & SHADER_HASRIPPLEMAP ) & & gl_config . ext_framebuffer_objects )
{
float renderscale = bs - > portalfboscale ;
vrect_t orect = r_refdef . vrect ;
pxrect_t oprect = r_refdef . pxrect ;
r_refdef . vrect . x = 0 ;
r_refdef . vrect . y = 0 ;
r_refdef . vrect . width = max ( 1 , vid . fbvwidth * renderscale ) ;
r_refdef . vrect . height = max ( 1 , vid . fbvheight * renderscale ) ;
r_refdef . pxrect . x = 0 ;
r_refdef . pxrect . y = 0 ;
r_refdef . pxrect . width = max ( 1 , vid . fbpwidth * renderscale ) ;
r_refdef . pxrect . height = max ( 1 , vid . fbpheight * renderscale ) ;
if ( ! shaderstate . tex_ripplemap [ r_refdef . recurse ] )
{
//FIXME: can we use RGB8 instead?
shaderstate . tex_ripplemap [ r_refdef . recurse ] = Image_CreateTexture ( " ***tex_ripplemap*** " , NULL , 0 ) ;
if ( ! shaderstate . tex_ripplemap [ r_refdef . recurse ] - > num )
qglGenTextures ( 1 , & shaderstate . tex_ripplemap [ r_refdef . recurse ] - > num ) ;
}
if ( shaderstate . tex_ripplemap [ r_refdef . recurse ] - > width ! = r_refdef . pxrect . width | | shaderstate . tex_ripplemap [ r_refdef . recurse ] - > height ! = r_refdef . pxrect . height )
{
shaderstate . tex_ripplemap [ r_refdef . recurse ] - > width = r_refdef . pxrect . width ;
shaderstate . tex_ripplemap [ r_refdef . recurse ] - > height = r_refdef . pxrect . height ;
GL_MTBind ( 0 , GL_TEXTURE_2D , shaderstate . tex_ripplemap [ r_refdef . recurse ] ) ;
qglTexImage2D ( GL_TEXTURE_2D , 0 , /*(gl_config.glversion>3.1)?GL_RGBA8_SNORM:*/ GL_RGBA16F_ARB , r_refdef . pxrect . width , r_refdef . pxrect . height , 0 , GL_RGBA , GL_HALF_FLOAT , NULL ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP_TO_EDGE ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP_TO_EDGE ) ;
}
oldfbo = GLBE_FBO_Update ( & shaderstate . fbo_reflectrefrac [ r_refdef . recurse ] , 0 , & shaderstate . tex_ripplemap [ r_refdef . recurse ] , 1 , r_nulltex , r_refdef . pxrect . width , r_refdef . pxrect . height , 0 ) ;
r_refdef . pxrect . maxheight = shaderstate . fbo_reflectrefrac [ r_refdef . recurse ] . rb_size [ 1 ] ;
GL_ViewportUpdate ( ) ;
qglClearColor ( 0 , 0 , 0 , 1 ) ;
qglClear ( GL_COLOR_BUFFER_BIT ) ;
2018-09-29 17:31:58 +00:00
// r_refdef.waterheight = DotProduct(batch->mesh[0]->xyz_array[0], batch->mesh[0]->normals_array[0]);
2018-07-22 11:49:37 +00:00
r_refdef . recurse + = 1 ; //paranoid, should stop potential infinite loops
GLBE_SubmitMeshes ( cl . worldmodel - > batches , SHADER_SORT_RIPPLE , SHADER_SORT_RIPPLE ) ;
r_refdef . recurse - = 1 ;
GLBE_FBO_Pop ( oldfbo ) ;
r_refdef . vrect = orect ;
r_refdef . pxrect = oprect ;
GL_ViewportUpdate ( ) ;
}
BE_SelectMode ( oldbem ) ;
shaderstate . identitylighting = oldil ;
return true ;
}
2012-05-09 15:30:53 +00:00
static void GLBE_SubmitMeshesSortList ( batch_t * sortlist )
2010-08-28 17:14:38 +00:00
{
batch_t * batch ;
2015-06-22 11:49:15 +00:00
shader_t * bs ;
2010-08-28 17:14:38 +00:00
for ( batch = sortlist ; batch ; batch = batch - > next )
2010-07-11 02:22:39 +00:00
{
if ( batch - > meshes = = batch - > firstmesh )
2009-11-04 21:16:50 +00:00
continue ;
2011-04-23 20:37:20 +00:00
if ( batch - > flags & BEF_NODLIGHT )
2013-10-08 14:28:11 +00:00
if ( shaderstate . mode = = BEM_LIGHT )
2011-04-23 20:37:20 +00:00
continue ;
if ( batch - > flags & BEF_NOSHADOWS )
------------------------------------------------------------------------
r4169 | acceptthis | 2013-01-17 08:55:12 +0000 (Thu, 17 Jan 2013) | 31 lines
removed MAX_VISEDICTS limit.
PEXT2_REPLACEMENTDELTAS tweaked, now has 4 million entity limit. still not enabled by default.
TE_BEAM now maps to a separate TEQW_BEAM to avoid conflicts with QW.
added android multitouch emulation for windows/rawinput (in_simulatemultitouch).
split topcolor/bottomcolor from scoreboard, for dp's colormap|1024 feature.
now using utf-8 for windows consoles.
qcc warnings/errors now give clickable console links for quick+easy editing.
disabled menutint when the currently active item changes contrast or gamma (for OneManClan).
Added support for drawfont/drawfontscale.
tweaked the qcvm a little to reduce the number of pointers.
.doll file loading. still experimental and will likely crash. requires csqc active, even if its a dummy progs. this will be fixed in time. Still other things that need cleaning up.
windows: gl_font "?" shows the standard windows font-selection dialog, and can be used to select windows fonts. not all work. and you probably don't want to use windings.
fixed splitscreen support when playing mvds. added mini-scoreboards to splitscreen.
editor/debugger now shows asm if there's no linenumber info. also, pressing f1 for help shows the shortcuts.
Added support for .framegroups files for psk(psa) and iqm formats.
True support for ezquake's colour codes. Mutually exclusive with background colours.
path command output slightly more readable.
added support for digest_hex (MD4, SHA1, CRC16).
skingroups now colourmap correctly.
Fix terrain colour hints, and litdata from the wrong bsp.
fix ftp dual-homed issue. support epsv command, and enable ipv6 (eprt still not supported).
remove d3d11 compilation from the makefile. the required headers are not provided by mingw, and are not available to the build bot, so don't bother.
fix v *= v.x and similar opcodes.
fteqcc: fixed support for áéÃóú type chars in names. utf-8 files now properly supported (even with the utf-8 bom/identifier). utf-16 also supported.
fteqcc: fixed '#if 1 == 3 && 4' parsing.
fteqcc: -Werror acts on the warning, rather than as a separate error. Line numbers are thus more readable.
fteqcc: copyright message now includes compile date instead.
fteqccgui: the treeview control is now coloured depending on whether there were warnings/errors in the last compile.
fteqccgui: the output window is now focused and scrolls down as compilation progresses.
pr_dumpplatform command dumps out some pragmas to convert more serious warnings to errors. This is to avoid the infamous 'fteqcc sucks cos my code sucks' issue.
rewrote prespawn/modelist/soundlist code. server tracks progress now.
------------------------------------------------------------------------
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4167 fc73d0e0-1445-4013-8a0c-d673dee63da5
2013-03-12 22:29:40 +00:00
if ( shaderstate . mode = = BEM_STENCIL | | shaderstate . mode = = BEM_DEPTHONLY ) //fixme: depthonly is not just shadows.
2011-04-23 20:37:20 +00:00
continue ;
2013-12-02 14:30:30 +00:00
//buildmeshes updates shaders and generates pose information for sufaces that need it.
//the shader flags checked *after* this call may be a performance issue if it generated lots of new mesh data.
//FIXME: should we assume that the batch's shader will have the same flags?
2010-08-28 17:14:38 +00:00
if ( batch - > buildmeshes )
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
{
TRACE ( ( " GLBE_SubmitMeshesSortList: build \n " ) ) ;
2010-08-28 17:14:38 +00:00
batch - > buildmeshes ( batch ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
}
2004-10-19 16:10:14 +00:00
2015-06-22 11:49:15 +00:00
bs = batch - > shader ;
TRACE ( ( " GLBE_SubmitMeshesSortList: shader %s \n " , bs - > name ) ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
2013-12-29 22:48:28 +00:00
//FIXME:!!
2015-06-22 11:49:15 +00:00
if ( ! bs )
2013-12-29 22:48:28 +00:00
{
Con_Printf ( " Shader not set... \n " ) ;
if ( batch - > texture )
2015-06-22 11:49:15 +00:00
bs = R_TextureAnimation ( 0 , batch - > texture ) - > shader ;
2013-12-29 22:48:28 +00:00
else
continue ;
}
2015-06-28 00:42:00 +00:00
if ( ( bs - > flags & SHADER_NODRAW ) | | ! batch - > meshes )
2011-02-25 04:22:14 +00:00
continue ;
2015-06-22 11:49:15 +00:00
if ( bs - > flags & SHADER_NODLIGHT )
2013-10-08 14:28:11 +00:00
if ( shaderstate . mode = = BEM_LIGHT )
2009-11-04 21:16:50 +00:00
continue ;
2015-06-22 11:49:15 +00:00
if ( bs - > flags & SHADER_NOSHADOWS )
2014-10-05 20:04:11 +00:00
if ( shaderstate . mode = = BEM_STENCIL | | shaderstate . mode = = BEM_DEPTHONLY ) //fixme: depthonly is not just shadows.
2013-11-21 23:02:28 +00:00
continue ;
2015-06-22 11:49:15 +00:00
if ( bs - > flags & SHADER_SKY )
2009-11-04 21:16:50 +00:00
{
2014-05-10 13:42:13 +00:00
if ( shaderstate . mode = = BEM_STANDARD | | shaderstate . mode = = BEM_DEPTHDARK ) // || shaderstate.mode == BEM_WIREFRAME)
2011-03-31 02:32:32 +00:00
{
2016-01-18 05:22:07 +00:00
if ( R_DrawSkyChain ( batch ) )
2011-03-31 02:32:32 +00:00
continue ;
}
2018-04-27 16:40:50 +00:00
else if ( /*shaderstate.mode != BEM_FOG &&*/ shaderstate . mode ! = BEM_CREPUSCULAR & & shaderstate . mode ! = BEM_WIREFRAME )
2011-02-25 04:22:14 +00:00
continue ;
2009-11-04 21:16:50 +00:00
}
2010-07-11 02:22:39 +00:00
2015-06-22 11:49:15 +00:00
if ( ( bs - > flags & ( SHADER_HASREFLECT | SHADER_HASREFRACT | SHADER_HASRIPPLEMAP ) ) & & shaderstate . mode ! = BEM_WIREFRAME )
2018-09-29 17:31:58 +00:00
{
2018-07-22 11:49:37 +00:00
if ( ! GLBE_GenerateBatchTextures ( batch , bs ) )
2012-08-04 01:35:52 +00:00
continue ;
2018-09-29 17:31:58 +00:00
if ( ( bs - > flags & SHADER_HASPORTAL ) & & shaderstate . mode ! = BEM_DEPTHONLY & & gl_config . arb_depth_clamp )
{ //this little bit of code is meant to prevent issues when the near clip plane intersects the portal surface, allowing us to be that little bit closer to the portal.
2018-09-30 03:38:26 +00:00
qglEnable ( GL_DEPTH_CLAMP_ARB ) ;
2018-09-29 17:31:58 +00:00
GLBE_SubmitBatch ( batch ) ;
2018-09-30 03:38:26 +00:00
qglDisable ( GL_DEPTH_CLAMP_ARB ) ;
2018-09-29 17:31:58 +00:00
continue ;
}
}
2012-05-09 15:30:53 +00:00
GLBE_SubmitBatch ( batch ) ;
2009-11-04 21:16:50 +00:00
}
2010-08-28 17:14:38 +00:00
}
2009-11-04 21:16:50 +00:00
2015-10-11 11:34:58 +00:00
void GLBE_SubmitMeshes ( batch_t * * worldbatches , int start , int stop )
2010-08-28 17:14:38 +00:00
{
int i ;
2013-12-29 22:48:28 +00:00
int portaldepth = r_portalrecursion . ival ;
2010-08-28 17:14:38 +00:00
2011-09-03 03:49:43 +00:00
for ( i = start ; i < = stop ; i + + )
2010-08-28 17:14:38 +00:00
{
2015-10-11 11:34:58 +00:00
if ( worldbatches )
2010-08-28 17:14:38 +00:00
{
2013-12-29 22:48:28 +00:00
if ( i = = SHADER_SORT_PORTAL & & r_refdef . recurse < portaldepth )
2014-02-14 09:59:32 +00:00
{
2015-10-11 11:34:58 +00:00
GLBE_SubmitMeshesPortals ( worldbatches , shaderstate . mbatches [ i ] ) ;
2010-08-28 17:14:38 +00:00
2014-02-14 09:59:32 +00:00
if ( ! r_refdef . recurse & & r_portalonly . ival )
return ;
}
2015-10-11 11:34:58 +00:00
GLBE_SubmitMeshesSortList ( worldbatches [ i ] ) ;
2010-08-28 17:14:38 +00:00
}
2012-05-14 01:41:08 +00:00
GLBE_SubmitMeshesSortList ( shaderstate . mbatches [ i ] ) ;
2010-08-28 17:14:38 +00:00
}
2009-11-04 21:16:50 +00:00
}
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
static void BE_UpdateLightmaps ( void )
{
2012-07-05 19:42:36 +00:00
lightmapinfo_t * lm ;
int lmidx ;
2015-04-14 23:12:17 +00:00
2012-07-05 19:42:36 +00:00
for ( lmidx = 0 ; lmidx < numlightmaps ; lmidx + + )
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
{
2012-07-05 19:42:36 +00:00
lm = lightmap [ lmidx ] ;
2012-07-07 05:17:43 +00:00
if ( ! lm )
continue ;
2012-07-05 19:42:36 +00:00
if ( lm - > modified )
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
{
2015-10-11 11:34:58 +00:00
int t = lm - > rectchange . t ; //pull them out now, in the hopes that it'll be more robust with respect to r_dynamic -1
int b = lm - > rectchange . b ;
2015-10-27 15:20:15 +00:00
# ifdef _DEBUG
if ( t > = b )
Con_Printf ( " Dodgy lightmaps \n " ) ;
else
# endif
2012-09-30 05:52:03 +00:00
if ( ! TEXVALID ( lm - > lightmap_texture ) )
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
{
2018-03-04 14:41:16 +00:00
extern cvar_t r_lightmap_nearest ;
TEXASSIGN ( lm - > lightmap_texture , Image_CreateTexture ( va ( " ***lightmap %i*** " , lmidx ) , NULL , ( r_lightmap_nearest . ival ? IF_NEAREST : IF_LINEAR ) | IF_NOMIPMAP ) ) ;
2014-10-05 20:04:11 +00:00
qglGenTextures ( 1 , & lm - > lightmap_texture - > num ) ;
2012-09-30 05:52:03 +00:00
GL_MTBind ( 0 , GL_TEXTURE_2D , lm - > lightmap_texture ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
2018-10-27 04:32:18 +00:00
qglTexImage2D ( GL_TEXTURE_2D , 0 , gl_config . formatinfo [ lm - > fmt ] . internalformat , lm - > width , lm - > height , 0 , gl_config . formatinfo [ lm - > fmt ] . format , gl_config . formatinfo [ lm - > fmt ] . type , lm - > lightmaps ) ;
2018-03-04 14:41:16 +00:00
if ( gl_config . glversion > = ( gl_config . gles ? 3.0 : 3.3 ) )
{
2018-10-27 04:32:18 +00:00
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_SWIZZLE_R , gl_config . formatinfo [ lm - > fmt ] . swizzle_r ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_SWIZZLE_G , gl_config . formatinfo [ lm - > fmt ] . swizzle_g ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_SWIZZLE_B , gl_config . formatinfo [ lm - > fmt ] . swizzle_b ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_SWIZZLE_A , gl_config . formatinfo [ lm - > fmt ] . swizzle_a ) ;
2018-03-04 14:41:16 +00:00
}
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
}
2012-09-30 05:52:03 +00:00
else
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
{
2012-09-30 05:52:03 +00:00
GL_MTBind ( 0 , GL_TEXTURE_2D , lm - > lightmap_texture ) ;
2018-10-27 04:32:18 +00:00
qglTexSubImage2D ( GL_TEXTURE_2D , 0 , 0 , t , lm - > width , b - t , gl_config . formatinfo [ lm - > fmt ] . format , gl_config . formatinfo [ lm - > fmt ] . type , lm - > lightmaps + t * lm - > width * lm - > pixbytes ) ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
}
2015-10-27 15:20:15 +00:00
lm - > modified = false ;
2015-03-03 00:14:43 +00:00
lm - > rectchange . l = lm - > width ;
lm - > rectchange . t = lm - > height ;
2015-10-11 11:34:58 +00:00
lm - > rectchange . r = 0 ;
lm - > rectchange . b = 0 ;
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
}
}
}
2011-01-04 02:56:16 +00:00
batch_t * GLBE_GetTempBatch ( void )
2010-08-28 17:14:38 +00:00
{
2012-10-08 04:36:10 +00:00
batch_t * b ;
2010-08-28 17:14:38 +00:00
if ( shaderstate . wbatch > = shaderstate . maxwbatches )
{
shaderstate . wbatch + + ;
return NULL ;
}
2012-10-08 04:36:10 +00:00
b = & shaderstate . wbatches [ shaderstate . wbatch + + ] ;
b - > fog = NULL ;
return b ;
2010-08-28 17:14:38 +00:00
}
/*called from shadowmapping code*/
# ifdef RTLIGHTS
2012-01-01 11:22:24 +00:00
void GLBE_BaseEntTextures ( void )
2010-08-28 17:14:38 +00:00
{
batch_t * batches [ SHADER_SORT_COUNT ] ;
2012-05-14 01:41:08 +00:00
batch_t * * ob = shaderstate . mbatches ;
shaderstate . mbatches = batches ;
2013-10-08 14:28:11 +00:00
BE_GenModelBatches ( batches , shaderstate . curdlight , shaderstate . mode ) ;
2015-10-11 11:34:58 +00:00
GLBE_SubmitMeshes ( NULL , SHADER_SORT_PORTAL , SHADER_SORT_SEETHROUGH + 1 ) ;
2012-11-27 03:23:19 +00:00
GLBE_SelectEntity ( & r_worldentity ) ;
2012-05-14 01:41:08 +00:00
shaderstate . mbatches = ob ;
2010-08-28 17:14:38 +00:00
}
# endif
2014-02-07 08:38:40 +00:00
void GLBE_RenderToTextureUpdate2d ( qboolean destchanged )
{
2014-05-30 03:57:30 +00:00
unsigned int width = 0 , height = 0 ;
2014-02-07 08:38:40 +00:00
if ( destchanged )
{
2014-08-03 14:47:47 +00:00
if ( * r_refdef . rt_destcolour [ 0 ] . texname )
2014-02-07 08:38:40 +00:00
{
2014-08-03 14:47:47 +00:00
texid_t tex = R2D_RT_GetTexture ( r_refdef . rt_destcolour [ 0 ] . texname , & width , & height ) ;
2015-07-06 14:47:46 +00:00
GLBE_FBO_Update ( & shaderstate . fbo_2dfbo , 0 , & tex , 1 , r_nulltex , width , height , 0 ) ;
2014-02-07 08:38:40 +00:00
}
else
GLBE_FBO_Push ( NULL ) ;
2014-05-30 03:57:30 +00:00
2016-12-07 18:45:25 +00:00
GL_Set2D ( false ) ;
2014-02-07 08:38:40 +00:00
}
else
{
2014-08-03 14:47:47 +00:00
shaderstate . tex_sourcecol = R2D_RT_GetTexture ( r_refdef . rt_sourcecolour . texname , & width , & height ) ;
shaderstate . tex_sourcedepth = R2D_RT_GetTexture ( r_refdef . rt_depth . texname , & width , & height ) ;
2016-07-12 00:40:13 +00:00
if ( * r_refdef . nearenvmap . texname )
shaderstate . tex_reflectcube = Image_GetTexture ( r_refdef . nearenvmap . texname , NULL , IF_CUBEMAP , NULL , NULL , 0 , 0 , TF_INVALID ) ;
else
shaderstate . tex_reflectcube = r_nulltex ;
2014-02-07 08:38:40 +00:00
}
}
void GLBE_FBO_Sources ( texid_t sourcecolour , texid_t sourcedepth )
{
shaderstate . tex_sourcecol = sourcecolour ;
shaderstate . tex_sourcedepth = sourcedepth ;
}
int GLBE_FBO_Push ( fbostate_t * state )
{
int newfbo ;
int oldfbo = shaderstate . fbo_current ;
if ( state )
newfbo = state - > fbo ;
else
newfbo = 0 ;
if ( shaderstate . fbo_current = = newfbo ) //don't bother if its not changed (also avoids crashes when fbos are not supported)
return oldfbo ;
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shaderstate . fbo_current = newfbo ) ;
return oldfbo ;
}
void GLBE_FBO_Pop ( int oldfbo )
{
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , oldfbo ) ;
shaderstate . fbo_current = oldfbo ;
}
void GLBE_FBO_Destroy ( fbostate_t * state )
{
if ( state - > fbo = = shaderstate . fbo_current )
GLBE_FBO_Push ( NULL ) ;
//wasn't initialised anyway.
if ( ! state - > fbo )
return ;
qglDeleteFramebuffersEXT ( 1 , & state - > fbo ) ;
state - > fbo = 0 ;
if ( state - > rb_depth )
qglDeleteRenderbuffersEXT ( 1 , & state - > rb_depth ) ;
state - > rb_depth = 0 ;
if ( state - > rb_stencil )
qglDeleteRenderbuffersEXT ( 1 , & state - > rb_stencil ) ;
state - > rb_stencil = 0 ;
if ( state - > rb_depthstencil )
qglDeleteRenderbuffersEXT ( 1 , & state - > rb_depthstencil ) ;
state - > rb_depthstencil = 0 ;
state - > enables = 0 ;
}
2018-01-22 19:18:04 +00:00
# ifdef RTLIGHTS
# ifdef SHADOWDBG_COLOURNOTDEPTH
void GLBE_BeginRenderBuffer_DepthOnly ( texid_t depthtexture )
{
if ( gl_config . ext_framebuffer_objects )
{
if ( ! shadow_fbo_id )
{
int drb ;
qglGenFramebuffersEXT ( 1 , & shadow_fbo_id ) ;
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shadow_fbo_id ) ;
//create an unnamed depth buffer
// qglGenRenderbuffersEXT(1, &drb);
// qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, drb);
// qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, SHADOWMAP_SIZE*3, SHADOWMAP_SIZE*2);
// qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, drb);
if ( qglDrawBuffer )
qglDrawBuffer ( GL_COLOR_ATTACHMENT0_EXT ) ;
if ( qglReadBuffer )
qglReadBuffer ( GL_NONE ) ;
}
else
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shadow_fbo_id ) ;
if ( TEXVALID ( depthtexture ) )
qglFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT , GL_TEXTURE_2D , depthtexture - > num , 0 ) ;
}
}
# else
int GLBE_BeginRenderBuffer_DepthOnly ( texid_t depthtexture )
{
int old = shaderstate . fbo_current ;
if ( gl_config . ext_framebuffer_objects )
{
if ( ! shadow_fbo_id )
{
qglGenFramebuffersEXT ( 1 , & shadow_fbo_id ) ;
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shadow_fbo_id ) ;
if ( qglDrawBuffers )
qglDrawBuffers ( 0 , NULL ) ;
else if ( qglDrawBuffer )
qglDrawBuffer ( GL_NONE ) ;
if ( qglReadBuffer )
qglReadBuffer ( GL_NONE ) ;
}
else
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shadow_fbo_id ) ;
shaderstate . fbo_current = shadow_fbo_id ;
if ( shadow_fbo_depth_num ! = depthtexture - > num )
{
shadow_fbo_depth_num = depthtexture - > num ;
if ( TEXVALID ( depthtexture ) )
qglFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_TEXTURE_2D , depthtexture - > num , 0 ) ;
}
}
return old ;
}
# endif
# endif
2014-02-07 08:38:40 +00:00
//state->colour is created if usedepth is set and it doesn't previously exist
2015-07-06 14:47:46 +00:00
int GLBE_FBO_Update ( fbostate_t * state , unsigned int enables , texid_t * destcol , int mrt , texid_t destdepth , int width , int height , int layer )
2014-02-07 08:38:40 +00:00
{
2014-08-27 08:41:31 +00:00
GLenum allcolourattachments [ ] = { GL_COLOR_ATTACHMENT0_EXT , GL_COLOR_ATTACHMENT1_EXT , GL_COLOR_ATTACHMENT2_EXT , GL_COLOR_ATTACHMENT3_EXT ,
GL_COLOR_ATTACHMENT4_EXT , GL_COLOR_ATTACHMENT5_EXT , GL_COLOR_ATTACHMENT6_EXT , GL_COLOR_ATTACHMENT7_EXT } ;
2014-08-15 02:20:41 +00:00
int i ;
2014-02-07 08:38:40 +00:00
int old ;
if ( TEXVALID ( destdepth ) )
{
enables | = FBO_TEX_DEPTH ;
enables & = ~ FBO_RB_DEPTH ;
}
2014-08-15 02:20:41 +00:00
enables | = ( mrt < < 16 ) ;
2014-02-07 08:38:40 +00:00
if ( ( state - > enables ^ enables ) & ~ FBO_RESET )
{
GLBE_FBO_Destroy ( state ) ;
state - > enables = enables & ~ FBO_RESET ;
enables | = FBO_RESET ;
}
if ( ! state - > fbo )
{
qglGenFramebuffersEXT ( 1 , & state - > fbo ) ;
old = GLBE_FBO_Push ( state ) ;
enables | = FBO_RESET ;
}
else
old = GLBE_FBO_Push ( state ) ;
if ( state - > rb_size [ 0 ] ! = width | | state - > rb_size [ 1 ] ! = height | | ( enables & FBO_RESET ) )
{
if ( state - > rb_depth & & ! ( enables & FBO_RB_DEPTH ) )
{
qglDeleteRenderbuffersEXT ( 1 , & state - > rb_depth ) ;
state - > rb_depth = 0 ;
}
if ( state - > rb_stencil & & ! ( enables & FBO_RB_STENCIL ) )
{
qglDeleteRenderbuffersEXT ( 1 , & state - > rb_stencil ) ;
state - > rb_stencil = 0 ;
}
state - > rb_size [ 0 ] = width ;
state - > rb_size [ 1 ] = height ;
enables | = FBO_RESET ;
2014-08-15 02:20:41 +00:00
if ( mrt )
2014-08-27 08:41:31 +00:00
{ //be careful here, gles2 doesn't support glDrawBuffer. hopefully it'll make things up, but this is worrying.
if ( qglDrawBuffers )
qglDrawBuffers ( mrt , allcolourattachments ) ;
else if ( qglDrawBuffer )
qglDrawBuffer ( GL_COLOR_ATTACHMENT0_EXT ) ;
if ( qglReadBuffer )
qglReadBuffer ( GL_COLOR_ATTACHMENT0_EXT ) ;
2014-02-07 08:38:40 +00:00
}
else
{
2014-08-27 08:41:31 +00:00
if ( qglDrawBuffers )
qglDrawBuffers ( 0 , NULL ) ;
else if ( qglDrawBuffer )
qglDrawBuffer ( GL_NONE ) ;
if ( qglReadBuffer )
qglReadBuffer ( GL_NONE ) ;
2014-02-07 08:38:40 +00:00
}
}
if ( enables & FBO_TEX_DEPTH )
{
2014-10-05 20:04:11 +00:00
qglFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_TEXTURE_2D , destdepth - > num , 0 ) ;
2014-02-07 08:38:40 +00:00
//fixme: no stencil
}
else if ( enables & FBO_RB_DEPTH )
{
if ( ! state - > rb_depth )
{
//create an unnamed depth buffer
qglGenRenderbuffersEXT ( 1 , & state - > rb_depth ) ;
2014-08-27 08:41:31 +00:00
// if (!gl_config.ext_packed_depth_stencil)
// qglGenRenderbuffersEXT(1, &state->rb_stencil);
2014-02-07 08:38:40 +00:00
enables | = FBO_RESET ; //make sure it gets instanciated
}
if ( enables & FBO_RESET )
{
qglBindRenderbufferEXT ( GL_RENDERBUFFER_EXT , state - > rb_depth ) ;
if ( gl_config . ext_packed_depth_stencil )
qglRenderbufferStorageEXT ( GL_RENDERBUFFER_EXT , GL_DEPTH24_STENCIL8_EXT , state - > rb_size [ 0 ] , state - > rb_size [ 1 ] ) ;
else
{
2014-08-27 08:41:31 +00:00
qglRenderbufferStorageEXT ( GL_RENDERBUFFER_EXT , GL_DEPTH_COMPONENT16_ARB , state - > rb_size [ 0 ] , state - > rb_size [ 1 ] ) ;
// qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, state->rb_stencil);
// qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, state->rb_size[0], state->rb_size[1]);
2014-02-07 08:38:40 +00:00
}
qglFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , state - > rb_depth ) ;
if ( gl_config . ext_packed_depth_stencil )
qglFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_STENCIL_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , state - > rb_depth ) ;
else
qglFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_STENCIL_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , state - > rb_stencil ) ;
}
}
2014-08-15 02:20:41 +00:00
for ( i = 0 ; i < mrt ; i + + )
2015-07-06 14:47:46 +00:00
{
if ( ( destcol [ i ] - > flags & IF_TEXTYPE ) = = IF_CUBEMAP )
{
//fixme: we should probably support whole-cubemap rendering for shadowmaps or something.
qglFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT + i , GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + layer , destcol [ i ] - > num , 0 ) ;
}
else
{ //layer does not make sense here
qglFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT + i , GL_TEXTURE_2D , destcol [ i ] - > num , 0 ) ;
}
}
2014-08-27 08:41:31 +00:00
i = qglCheckFramebufferStatusEXT ( GL_FRAMEBUFFER_EXT ) ;
if ( GL_FRAMEBUFFER_COMPLETE_EXT ! = i )
{
switch ( i )
{
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT :
Con_Printf ( " glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT \n " ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT :
Con_Printf ( " glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT \n " ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT :
Con_Printf ( " glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS \n " ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT :
Con_Printf ( " glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_FORMATS \n " ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT :
Con_Printf ( " glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER \n " ) ;
break ;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT :
Con_Printf ( " glCheckFramebufferStatus reported GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER \n " ) ;
break ;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT :
Con_Printf ( " glCheckFramebufferStatus reported GL_FRAMEBUFFER_UNSUPPORTED \n " ) ;
break ;
default :
Con_Printf ( " glCheckFramebufferStatus returned %#x \n " , i ) ;
break ;
}
}
2014-02-07 08:38:40 +00:00
return old ;
}
/*
2013-03-12 23:13:39 +00:00
void GLBE_RenderToTexture ( texid_t sourcecol , texid_t sourcedepth , texid_t destcol , texid_t destdepth , qboolean usedepth )
2012-01-17 07:57:46 +00:00
{
shaderstate . tex_sourcecol = sourcecol ;
shaderstate . tex_sourcedepth = sourcedepth ;
if ( ! destcol . num )
2013-10-29 17:38:22 +00:00
{
shaderstate . fbo_current = 0 ;
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shaderstate . fbo_current ) ;
}
2012-01-17 07:57:46 +00:00
else
{
2012-05-09 15:30:53 +00:00
if ( usedepth )
2012-01-17 07:57:46 +00:00
{
2012-05-09 15:30:53 +00:00
if ( ! shaderstate . fbo_diffuse )
{
qglGenFramebuffersEXT ( 1 , & shaderstate . fbo_diffuse ) ;
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shaderstate . fbo_diffuse ) ;
2012-01-17 07:57:46 +00:00
2012-05-09 15:30:53 +00:00
//create an unnamed depth buffer
2012-11-29 13:37:48 +00:00
qglGenRenderbuffersEXT ( 1 , & shaderstate . rb_depth ) ;
qglBindRenderbufferEXT ( GL_RENDERBUFFER_EXT , shaderstate . rb_depth ) ;
if ( gl_config . ext_packed_depth_stencil )
{
qglFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_STENCIL_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , shaderstate . rb_depth ) ;
}
else
{
qglGenRenderbuffersEXT ( 1 , & shaderstate . rb_stencil ) ;
2013-03-12 23:13:39 +00:00
qglBindRenderbufferEXT ( GL_RENDERBUFFER_EXT , shaderstate . rb_stencil ) ;
2012-11-29 13:37:48 +00:00
qglFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_STENCIL_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , shaderstate . rb_stencil ) ;
}
qglFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , shaderstate . rb_depth ) ;
2012-05-09 15:30:53 +00:00
qglDrawBuffer ( GL_COLOR_ATTACHMENT0_EXT ) ;
qglReadBuffer ( GL_NONE ) ;
}
else
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shaderstate . fbo_diffuse ) ;
2013-10-29 17:38:22 +00:00
shaderstate . fbo_current = shaderstate . fbo_diffuse ;
2013-03-12 23:13:39 +00:00
if ( destdepth . num )
2014-02-07 08:38:40 +00:00
{
2013-03-12 23:13:39 +00:00
qglFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_TEXTURE_2D , destdepth . num , 0 ) ;
2014-02-07 08:38:40 +00:00
qglFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_STENCIL_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , 0 ) ;
}
2013-03-12 23:13:39 +00:00
else
2014-02-07 08:38:40 +00:00
{
//resize the depth renderbuffer if its the wrong size now
if ( shaderstate . rb_depth_size [ 0 ] ! = r_refdef . fbo_width | | shaderstate . rb_depth_size [ 1 ] ! = r_refdef . fbo_height )
{
shaderstate . rb_depth_size [ 0 ] = r_refdef . fbo_width ;
shaderstate . rb_depth_size [ 1 ] = r_refdef . fbo_height ;
qglBindRenderbufferEXT ( GL_RENDERBUFFER_EXT , shaderstate . rb_depth ) ;
if ( gl_config . ext_packed_depth_stencil )
{
qglRenderbufferStorageEXT ( GL_RENDERBUFFER_EXT , GL_DEPTH24_STENCIL8_EXT , r_refdef . fbo_width , r_refdef . fbo_height ) ;
qglFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_STENCIL_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , shaderstate . rb_depth ) ;
}
else
{
qglRenderbufferStorageEXT ( GL_RENDERBUFFER_EXT , GL_DEPTH_COMPONENT24_ARB , r_refdef . fbo_width , r_refdef . fbo_height ) ;
qglBindRenderbufferEXT ( GL_RENDERBUFFER_EXT , shaderstate . rb_stencil ) ;
qglRenderbufferStorageEXT ( GL_RENDERBUFFER_EXT , GL_STENCIL_INDEX8_EXT , r_refdef . fbo_width , r_refdef . fbo_height ) ;
}
}
2013-03-12 23:13:39 +00:00
qglFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_DEPTH_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , shaderstate . rb_depth ) ;
2014-02-07 08:38:40 +00:00
if ( gl_config . ext_packed_depth_stencil )
qglFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_STENCIL_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , shaderstate . rb_depth ) ;
else
qglFramebufferRenderbufferEXT ( GL_FRAMEBUFFER_EXT , GL_STENCIL_ATTACHMENT_EXT , GL_RENDERBUFFER_EXT , shaderstate . rb_stencil ) ;
}
2012-01-17 07:57:46 +00:00
}
else
2012-05-09 15:30:53 +00:00
{
if ( ! shaderstate . fbo_depthless )
{
qglGenFramebuffersEXT ( 1 , & shaderstate . fbo_depthless ) ;
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shaderstate . fbo_depthless ) ;
qglDrawBuffer ( GL_COLOR_ATTACHMENT0_EXT ) ;
qglReadBuffer ( GL_NONE ) ;
}
else
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shaderstate . fbo_depthless ) ;
2013-10-29 17:38:22 +00:00
shaderstate . fbo_current = shaderstate . fbo_depthless ;
2012-05-09 15:30:53 +00:00
}
2012-01-17 07:57:46 +00:00
qglFramebufferTexture2DEXT ( GL_FRAMEBUFFER_EXT , GL_COLOR_ATTACHMENT0_EXT , GL_TEXTURE_2D , destcol . num , 0 ) ;
}
}
2014-02-07 08:38:40 +00:00
*/
2012-01-17 07:57:46 +00:00
2016-11-20 20:52:41 +00:00
void GLBE_DrawLightPrePass ( void )
2011-09-03 03:49:43 +00:00
{
2017-10-31 22:52:58 +00:00
cvar_t * var ;
2017-10-13 17:50:28 +00:00
unsigned int i ;
2016-11-20 20:52:41 +00:00
qboolean redefine = false ;
2017-10-31 22:52:58 +00:00
texid_t depth , targets [ countof ( shaderstate . tex_gbuf ) ] ;
const char * s ;
int w = r_refdef . pxrect . width , h = r_refdef . pxrect . height ;
2014-02-07 08:38:40 +00:00
/*
walls ( bumps ) - > normalbuffer
lights + normalbuffer - > lightlevelbuffer
walls ( diffuse ) + lightlevelbuffer - > screen
normalbuffer contains depth in the alpha channel . an actual depthbuffer is also generated at this time , which is used for depth test stuff but not as a shader input .
*/
int oldfbo ;
2017-10-31 22:52:58 +00:00
2017-11-05 13:15:08 +00:00
if ( r_refdef . recurse )
return ; //fixme: messy stuff...
2011-09-03 03:49:43 +00:00
/*do portals*/
BE_SelectMode ( BEM_STANDARD ) ;
2015-10-11 11:34:58 +00:00
GLBE_SubmitMeshes ( cl . worldmodel - > batches , SHADER_SORT_PORTAL , SHADER_SORT_PORTAL ) ;
2011-09-03 03:49:43 +00:00
2016-11-20 20:52:41 +00:00
BE_SelectMode ( BEM_GBUFFER ) ;
2017-10-13 17:50:28 +00:00
for ( i = 0 ; i < countof ( shaderstate . tex_gbuf ) ; i + + )
2011-09-03 03:49:43 +00:00
{
2017-10-31 22:52:58 +00:00
if ( ! TEXVALID ( shaderstate . tex_gbuf [ i ] ) | | w ! = shaderstate . tex_gbuf [ i ] - > width | | h ! = shaderstate . tex_gbuf [ i ] - > height )
2016-11-20 20:52:41 +00:00
{
2017-10-13 17:50:28 +00:00
if ( ! shaderstate . tex_gbuf [ i ] )
{
2017-10-31 22:52:58 +00:00
shaderstate . tex_gbuf [ i ] = Image_CreateTexture ( va ( " ***gbuffer %u*** " , i ) , NULL , IF_CLAMP | IF_NEAREST | IF_NOMIPMAP | IF_RENDERTARGET ) ;
2017-10-13 17:50:28 +00:00
qglGenTextures ( 1 , & shaderstate . tex_gbuf [ i ] - > num ) ;
}
2017-10-31 22:52:58 +00:00
shaderstate . tex_gbuf [ i ] - > width = w ;
shaderstate . tex_gbuf [ i ] - > height = h ;
2017-10-13 17:50:28 +00:00
redefine = true ;
2016-11-20 20:52:41 +00:00
}
2011-09-03 03:49:43 +00:00
}
2016-11-20 20:52:41 +00:00
//something changed, redefine the textures.
if ( redefine )
2011-09-03 03:49:43 +00:00
{
2017-10-31 22:52:58 +00:00
static const char * defualtfmts [ countof ( shaderstate . tex_gbuf ) ] =
//depth, normals, difflight, speclight
{ " depth " , " rgba16f " , " rgba16f " , " rgba8 " , " " , " " , " " , " " } ;
2017-11-05 13:15:08 +00:00
checkglerror ( ) ;
2017-10-31 22:52:58 +00:00
for ( i = 0 ; i < countof ( shaderstate . tex_gbuf ) ; i + + )
{
GLint ifmt = 0 ;
GLenum dfmt = GL_RGBA ;
2017-11-05 13:15:08 +00:00
GLenum dtype = GL_UNSIGNED_BYTE ;
2017-10-31 22:52:58 +00:00
var = Cvar_Get ( va ( " gl_deferred_gbuffmt_%i " , i ) , defualtfmts [ i ] ? defualtfmts [ i ] : " " , 0 , " Deferred Rendering " ) ;
if ( ! var )
continue ;
if ( ! strcmp ( var - > string , " rgba32f " ) )
2017-11-05 13:15:08 +00:00
{
if ( gl_config_gles )
{ //gles3
ifmt = GL_RGBA32F_ARB ;
dfmt = GL_RGBA ;
dtype = GL_FLOAT ;
}
else
ifmt = GL_RGBA32F_ARB ;
}
2017-10-31 22:52:58 +00:00
else if ( ! strcmp ( var - > string , " rgba16f " ) )
2017-11-05 13:15:08 +00:00
{
if ( gl_config_gles )
{ //gles3
ifmt = GL_RGBA16F_ARB ;
dfmt = GL_RGBA ;
2018-03-04 14:41:16 +00:00
dtype = GL_HALF_FLOAT ;
2017-11-05 13:15:08 +00:00
}
else
ifmt = GL_RGBA16F_ARB ;
}
2017-10-31 22:52:58 +00:00
// else if (!strcmp(var->string, "rgba8s"))
// ifmt = GL_RGBA8_SNORM;
else if ( ! strcmp ( var - > string , " depth " ) )
{
2017-11-05 13:15:08 +00:00
dtype = GL_UNSIGNED_INT ;
2017-10-31 22:52:58 +00:00
ifmt = GL_DEPTH_COMPONENT ;
dfmt = GL_DEPTH_COMPONENT ;
}
else if ( ! strcmp ( var - > string , " depth16 " ) )
{
2017-11-05 13:15:08 +00:00
if ( gl_config_gles )
{
dtype = GL_UNSIGNED_SHORT ;
ifmt = GL_DEPTH_COMPONENT ;
}
else
ifmt = GL_DEPTH_COMPONENT16_ARB ;
2017-10-31 22:52:58 +00:00
dfmt = GL_DEPTH_COMPONENT ;
}
else if ( ! strcmp ( var - > string , " depth24 " ) )
{
2017-11-05 13:15:08 +00:00
if ( gl_config_gles )
{
dtype = GL_UNSIGNED_INT ;
ifmt = GL_DEPTH_COMPONENT ;
}
else
ifmt = GL_DEPTH_COMPONENT24_ARB ;
2017-10-31 22:52:58 +00:00
dfmt = GL_DEPTH_COMPONENT ;
}
else if ( ! strcmp ( var - > string , " depth32 " ) )
{
2017-11-05 13:15:08 +00:00
if ( gl_config_gles )
{
dtype = GL_FLOAT ;
ifmt = GL_DEPTH_COMPONENT ;
}
else
ifmt = GL_DEPTH_COMPONENT32_ARB ;
2017-10-31 22:52:58 +00:00
dfmt = GL_DEPTH_COMPONENT ;
}
2017-11-05 13:15:08 +00:00
else if ( ! strcmp ( var - > string , " rgb565 " ) )
{
dtype = GL_UNSIGNED_SHORT_5_6_5 ;
ifmt = GL_RGB ;
dfmt = GL_RGB ;
}
else if ( ! strcmp ( var - > string , " rgba4 " ) )
{
dtype = GL_UNSIGNED_SHORT_4_4_4_4 ;
ifmt = GL_RGBA ;
dfmt = GL_RGBA ;
}
else if ( ! strcmp ( var - > string , " rgba5551 " ) )
{
dtype = GL_UNSIGNED_SHORT_5_5_5_1 ;
ifmt = GL_RGBA ;
dfmt = GL_RGBA ;
}
2017-10-31 22:52:58 +00:00
else if ( ! strcmp ( var - > string , " rgba8 " ) | | * var - > string )
2017-11-05 13:15:08 +00:00
{
# ifndef GLESONLY
if ( ! gl_config_gles )
ifmt = GL_RGBA8 ;
else
# endif
ifmt = GL_RGBA ;
dfmt = GL_RGBA ;
}
2017-10-31 22:52:58 +00:00
else
continue ;
2011-09-03 03:49:43 +00:00
2017-10-31 22:52:58 +00:00
shaderstate . tex_gbuf [ i ] - > status = TEX_LOADED ;
GL_MTBind ( 0 , GL_TEXTURE_2D , shaderstate . tex_gbuf [ i ] ) ;
2017-11-05 13:15:08 +00:00
qglTexImage2D ( GL_TEXTURE_2D , 0 , ifmt , w , h , 0 , dfmt , dtype , NULL ) ;
2017-10-31 22:52:58 +00:00
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_NEAREST ) ;
2017-11-05 13:15:08 +00:00
if ( qglGetError ( ) )
Con_Printf ( " unable to configure gbuffer image as '%s' \n " , var - > string ) ;
2017-10-31 22:52:58 +00:00
}
2011-09-03 03:49:43 +00:00
}
/*set the FB up to draw surface info*/
2017-10-31 22:52:58 +00:00
var = Cvar_Get2 ( " gl_deferred_pre_depth " , " 0 " , 0 , " gbuffer index used for depth. negative means to use an annonamous renderbuffer " , " Deferred Rendering " ) ;
if ( var - > ival < 0 | | var - > ival > = countof ( shaderstate . tex_gbuf ) )
depth = r_nulltex ;
else
depth = shaderstate . tex_gbuf [ var - > ival ] ;
var = Cvar_Get2 ( " gl_deferred_pre_targets " , " 1 " , 0 , " space-separated list of gbuffer indexes to use for deferred surface information " , " Deferred Rendering " ) ;
for ( i = 0 , s = var - > string ; * s & & i < countof ( targets ) ; )
{
char token [ 32 ] ;
int b ;
s = COM_ParseOut ( s , token , sizeof ( token ) ) ;
if ( ! * token )
continue ;
b = atoi ( token ) ;
if ( b > = 0 & & b < countof ( shaderstate . tex_gbuf ) )
targets [ i + + ] = shaderstate . tex_gbuf [ b ] ;
}
2011-09-03 03:49:43 +00:00
2017-10-31 22:52:58 +00:00
oldfbo = GLBE_FBO_Update ( & shaderstate . fbo_lprepass , depth ? FBO_TEX_DEPTH : FBO_RB_DEPTH , targets , i , depth , w , h , 0 ) ;
2011-09-03 03:49:43 +00:00
if ( GL_FRAMEBUFFER_COMPLETE_EXT ! = qglCheckFramebufferStatusEXT ( GL_FRAMEBUFFER_EXT ) )
{
Con_Printf ( " Bad framebuffer \n " ) ;
return ;
}
2017-10-31 22:52:58 +00:00
GL_ForceDepthWritable ( ) ;
//FIXME: should probably clear colour buffer too.
qglClear ( GL_DEPTH_BUFFER_BIT ) ;
2011-09-03 03:49:43 +00:00
/*draw surfaces that can be drawn this way*/
2015-10-11 11:34:58 +00:00
GLBE_SubmitMeshes ( cl . worldmodel - > batches , SHADER_SORT_OPAQUE , SHADER_SORT_OPAQUE ) ;
2011-09-03 03:49:43 +00:00
/*reconfigure - now drawing diffuse light info using the previous fb image as a source image*/
2017-10-31 22:52:58 +00:00
var = Cvar_Get2 ( " gl_deferred_light_targets " , " 2 3 " , 0 , " space-separated list of gbuffer indexes for lighting to write to " , " Deferred Rendering " ) ;
for ( i = 0 , s = var - > string ; * s & & i < countof ( targets ) ; )
{
char token [ 32 ] ;
int b ;
s = COM_ParseOut ( s , token , sizeof ( token ) ) ;
if ( ! * token )
continue ;
b = atoi ( token ) ;
if ( b > = 0 & & b < countof ( shaderstate . tex_gbuf ) )
targets [ i + + ] = shaderstate . tex_gbuf [ b ] ;
}
GLBE_FBO_Update ( & shaderstate . fbo_lprepass , depth ? FBO_TEX_DEPTH : FBO_RB_DEPTH , targets , i , depth , w , h , 0 ) ;
2011-09-03 03:49:43 +00:00
BE_SelectMode ( BEM_STANDARD ) ;
2017-10-31 22:52:58 +00:00
qglClearColor ( 0 , 0 , 0 , 0 ) ;
2011-09-03 03:49:43 +00:00
qglClear ( GL_COLOR_BUFFER_BIT ) ;
2012-11-27 03:23:19 +00:00
GLBE_SelectEntity ( & r_worldentity ) ;
2011-09-03 03:49:43 +00:00
/*now draw the prelights*/
2017-10-31 22:52:58 +00:00
GLBE_SubmitMeshes ( cl . worldmodel - > batches , SHADER_SORT_DEFERREDLIGHT , SHADER_SORT_DEFERREDLIGHT ) ;
2011-09-03 03:49:43 +00:00
/*final reconfigure - now drawing final surface data onto true framebuffer*/
2014-02-07 08:38:40 +00:00
GLBE_FBO_Pop ( oldfbo ) ;
2017-11-05 13:15:08 +00:00
if ( ! oldfbo & & qglDrawBuffer )
2016-11-20 20:52:41 +00:00
qglDrawBuffer ( GL_BACK ) ;
2011-09-03 03:49:43 +00:00
/*now draw the postlight passes (this includes blended stuff which will NOT be lit)*/
2012-11-27 03:23:19 +00:00
GLBE_SelectEntity ( & r_worldentity ) ;
2015-10-11 11:34:58 +00:00
GLBE_SubmitMeshes ( cl . worldmodel - > batches , SHADER_SORT_SKY , SHADER_SORT_NEAREST ) ;
2011-09-03 03:49:43 +00:00
2011-09-05 01:48:23 +00:00
# ifdef RTLIGHTS
2011-09-03 03:49:43 +00:00
/*regular lighting now*/
2012-11-27 03:23:19 +00:00
GLBE_SelectEntity ( & r_worldentity ) ;
2016-11-20 20:52:41 +00:00
Sh_DrawLights ( r_refdef . scenevis ) ;
2011-09-05 01:48:23 +00:00
# endif
2011-09-03 03:49:43 +00:00
qglClearColor ( 1 , 0 , 0 , 1 ) ;
}
2016-11-20 20:52:41 +00:00
void GLBE_DrawWorld ( batch_t * * worldbatches )
2009-11-04 21:16:50 +00:00
{
2016-02-15 06:01:17 +00:00
# ifdef RTLIGHTS
2009-11-04 21:16:50 +00:00
extern cvar_t r_shadow_realtime_world , r_shadow_realtime_world_lightmaps ;
2016-02-15 06:01:17 +00:00
# endif
2010-08-28 17:14:38 +00:00
batch_t * batches [ SHADER_SORT_COUNT ] ;
2012-05-14 01:41:08 +00:00
batch_t * * ob = shaderstate . mbatches ;
2009-11-04 21:16:50 +00:00
RSpeedLocals ( ) ;
2012-05-14 01:41:08 +00:00
shaderstate . mbatches = batches ;
2011-02-25 04:22:14 +00:00
2012-11-29 13:37:48 +00:00
shaderstate . depthrange = 0 ;
2017-11-30 17:59:11 +00:00
TRACE ( ( " GLBE_DrawWorld: %p \n " , worldbatches ) ) ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
2014-10-05 20:04:11 +00:00
//reset batches if we needed more mem, to avoid allocations mid-frame.
2010-08-29 13:49:43 +00:00
if ( ! r_refdef . recurse )
2010-08-28 17:14:38 +00:00
{
2011-09-03 03:49:43 +00:00
if ( shaderstate . wbatch + 50 > shaderstate . maxwbatches )
2010-08-29 13:49:43 +00:00
{
2011-09-03 03:49:43 +00:00
int newm = shaderstate . wbatch + 100 ;
2010-08-29 13:49:43 +00:00
shaderstate . wbatches = BZ_Realloc ( shaderstate . wbatches , newm * sizeof ( * shaderstate . wbatches ) ) ;
memset ( shaderstate . wbatches + shaderstate . maxwbatches , 0 , ( newm - shaderstate . maxwbatches ) * sizeof ( * shaderstate . wbatches ) ) ;
shaderstate . maxwbatches = newm ;
}
2010-08-28 17:14:38 +00:00
2010-08-29 13:49:43 +00:00
shaderstate . wbatch = 0 ;
}
2014-10-05 20:04:11 +00:00
//if the video mode changed, update any fbos (hopefully this won't happen on mirrors)
2012-05-11 01:57:00 +00:00
if ( shaderstate . oldwidth ! = vid . pixelwidth | | shaderstate . oldheight ! = vid . pixelheight )
{
2014-05-30 03:57:30 +00:00
GLBE_DestroyFBOs ( ) ; //will be recreated on demand
2012-05-11 01:57:00 +00:00
shaderstate . oldwidth = vid . pixelwidth ;
shaderstate . oldheight = vid . pixelheight ;
while ( shaderstate . lastpasstmus > 0 )
{
GL_LazyBind ( - - shaderstate . lastpasstmus , 0 , r_nulltex ) ;
}
# ifdef RTLIGHTS
2012-09-30 05:52:03 +00:00
Sh_Reset ( ) ;
2012-05-11 01:57:00 +00:00
# endif
}
2013-10-08 14:28:11 +00:00
//memset(batches, 0, sizeof(batches));
BE_GenModelBatches ( batches , shaderstate . curdlight , BEM_STANDARD ) ;
2011-09-03 03:49:43 +00:00
R_GenDlightBatches ( batches ) ;
2011-02-25 04:22:14 +00:00
shaderstate . curentity = & r_worldentity ;
2014-01-13 02:42:25 +00:00
// if (cl.paused || cls.state < ca_active)
2012-07-05 19:42:36 +00:00
shaderstate . updatetime = r_refdef . time ;
2014-01-13 02:42:25 +00:00
// else
// shaderstate.updatetime = cl.servertime;
2010-08-28 17:14:38 +00:00
2012-11-27 03:23:19 +00:00
GLBE_SelectEntity ( & r_worldentity ) ;
2011-05-20 04:10:46 +00:00
2012-04-09 19:12:12 +00:00
BE_UpdateLightmaps ( ) ;
2015-10-11 11:34:58 +00:00
if ( worldbatches )
2011-04-30 17:21:10 +00:00
{
2011-09-03 03:49:43 +00:00
if ( gl_overbright . modified )
{
int i ;
gl_overbright . modified = false ;
if ( gl_overbright . ival > 2 )
gl_overbright . ival = 2 ;
2012-11-27 03:23:19 +00:00
for ( i = 0 ; i < SHADER_TMU_MAX ; i + + )
2011-09-03 03:49:43 +00:00
shaderstate . blendmode [ i ] = - 1 ;
}
2011-04-30 17:21:10 +00:00
2010-07-11 02:22:39 +00:00
# ifdef RTLIGHTS
2015-10-11 11:34:58 +00:00
if ( worldbatches & & r_shadow_realtime_world . ival )
2011-09-03 03:49:43 +00:00
shaderstate . identitylighting = r_shadow_realtime_world_lightmaps . value ;
else
2004-10-19 16:10:14 +00:00
# endif
2017-08-29 02:29:06 +00:00
shaderstate . identitylighting = r_lightmap_scale . value ;
2015-04-27 12:51:42 +00:00
shaderstate . identitylighting * = r_refdef . hdr_value ;
2016-07-12 00:40:13 +00:00
shaderstate . identitylightmap = shaderstate . identitylighting ;
// shaderstate.identitylightmap *= 1<<gl_overbright.ival;
2009-11-04 21:16:50 +00:00
2017-08-29 02:29:06 +00:00
// if (cl.worldmodel && cl.worldmodel->fromgame == fg_quake3)
// shaderstate.identitylighting *= 2;
2011-09-03 03:49:43 +00:00
# ifdef RTLIGHTS
2016-11-20 20:52:41 +00:00
if ( r_lightprepass )
2011-09-03 03:49:43 +00:00
{
2016-11-20 20:52:41 +00:00
GLBE_DrawLightPrePass ( ) ;
2011-09-03 03:49:43 +00:00
}
else
# endif
{
if ( shaderstate . identitylighting = = 0 )
BE_SelectMode ( BEM_DEPTHDARK ) ;
else
BE_SelectMode ( BEM_STANDARD ) ;
2011-05-26 16:46:43 +00:00
2011-09-03 03:49:43 +00:00
RSpeedRemark ( ) ;
2017-02-21 20:22:07 +00:00
GLBE_SubmitMeshes ( worldbatches , SHADER_SORT_PORTAL , SHADER_SORT_SEETHROUGH + 1 ) ;
2017-08-29 02:29:06 +00:00
RSpeedEnd ( RSPEED_OPAQUE ) ;
2011-05-26 16:46:43 +00:00
2009-11-04 21:16:50 +00:00
# ifdef RTLIGHTS
2015-10-11 11:34:58 +00:00
if ( worldbatches )
2015-06-22 11:49:15 +00:00
{
RSpeedRemark ( ) ;
TRACE ( ( " GLBE_DrawWorld: drawing lights \n " ) ) ;
GLBE_SelectEntity ( & r_worldentity ) ;
2016-11-20 20:52:41 +00:00
Sh_DrawLights ( r_refdef . scenevis ) ;
2017-08-29 02:29:06 +00:00
RSpeedEnd ( RSPEED_RTLIGHTS ) ;
2015-06-22 11:49:15 +00:00
TRACE ( ( " GLBE_DrawWorld: lights drawn \n " ) ) ;
}
2009-11-04 21:16:50 +00:00
# endif
2015-06-22 11:49:15 +00:00
}
2011-05-26 16:46:43 +00:00
2011-10-27 16:16:29 +00:00
shaderstate . identitylighting = 1 ;
2017-08-29 02:29:06 +00:00
RSpeedRemark ( ) ;
2017-02-21 20:22:07 +00:00
GLBE_SubmitMeshes ( worldbatches , SHADER_SORT_SEETHROUGH + 1 , SHADER_SORT_NEAREST ) ;
2017-08-29 02:29:06 +00:00
RSpeedEnd ( RSPEED_TRANSPARENTS ) ;
2011-10-27 16:16:29 +00:00
2017-11-30 17:59:11 +00:00
# ifndef GLSLONLY
2018-03-04 14:41:16 +00:00
if ( r_refdef . globalfog . density & & ( ! gl_config . arb_shader_objects | | ! r_fog_permutation . ival ) )
2017-11-30 17:59:11 +00:00
{ //fixed function-only. with global fog. that means we need to hack something in.
//FIXME: should really be doing this on a per-shader basis, for custom shaders that don't use glsl
2011-09-03 03:49:43 +00:00
BE_SelectMode ( BEM_FOG ) ;
2017-11-30 17:59:11 +00:00
BE_SelectFog ( r_refdef . globalfog . colour , r_refdef . globalfog . alpha , r_refdef . globalfog . density ) ;
GLBE_SubmitMeshes ( worldbatches , SHADER_SORT_PORTAL , SHADER_SORT_NEAREST ) ;
2011-09-03 03:49:43 +00:00
}
2017-11-30 17:59:11 +00:00
# endif
2012-08-04 01:35:52 +00:00
2012-08-04 12:27:24 +00:00
# ifdef GL_LINE //no gles
if ( r_wireframe . ival & & qglPolygonMode )
2012-08-04 01:35:52 +00:00
{
BE_SelectMode ( BEM_WIREFRAME ) ;
qglPolygonMode ( GL_FRONT_AND_BACK , GL_LINE ) ;
2015-10-11 11:34:58 +00:00
GLBE_SubmitMeshes ( worldbatches , SHADER_SORT_PORTAL , SHADER_SORT_NEAREST ) ;
2012-08-04 01:35:52 +00:00
BE_SelectMode ( BEM_STANDARD ) ;
qglPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ) ;
}
2012-08-04 12:27:24 +00:00
# endif
2013-10-08 14:28:11 +00:00
shaderstate . curdlight = NULL ;
2011-02-25 04:22:14 +00:00
}
2011-09-03 03:49:43 +00:00
else
2010-08-28 17:14:38 +00:00
{
2015-10-11 11:34:58 +00:00
GLBE_SubmitMeshes ( NULL , SHADER_SORT_PORTAL , SHADER_SORT_NEAREST ) ;
2012-08-04 01:35:52 +00:00
2012-08-04 12:27:24 +00:00
# ifdef GL_LINE //no gles
if ( r_wireframe . ival & & qglPolygonMode )
2012-08-04 01:35:52 +00:00
{
BE_SelectMode ( BEM_WIREFRAME ) ;
qglPolygonMode ( GL_FRONT_AND_BACK , GL_LINE ) ;
2015-10-11 11:34:58 +00:00
GLBE_SubmitMeshes ( NULL , SHADER_SORT_PORTAL , SHADER_SORT_NEAREST ) ;
2012-08-04 01:35:52 +00:00
BE_SelectMode ( BEM_STANDARD ) ;
qglPolygonMode ( GL_FRONT_AND_BACK , GL_FILL ) ;
}
2012-08-04 12:27:24 +00:00
# endif
2010-08-28 17:14:38 +00:00
}
2012-11-27 03:23:19 +00:00
GLBE_SelectEntity ( & r_worldentity ) ;
2014-01-13 02:42:25 +00:00
// shaderstate.curtime = shaderstate.updatetime = realtime;
2018-01-06 18:29:36 +00:00
shaderstate . depthrange = 0 ;
2011-02-25 04:22:14 +00:00
2011-10-27 16:16:29 +00:00
shaderstate . identitylighting = 1 ;
2012-05-14 01:41:08 +00:00
shaderstate . mbatches = ob ;
Android: fat presses, vibrator, onscreen keyboard, keep-screen-on, console scaling, touch-based console scrolling, additional bindables.
Some memory leaks fixed.
latency with the nq protocol over loopback is much reduced.
Terrain: now mostly a property of a (q1 for now) bsp map, file format changed, glsl now built in, terrain editor builtin improved/changed, holes supported.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4067 fc73d0e0-1445-4013-8a0c-d673dee63da5
2012-07-14 16:25:18 +00:00
TRACE ( ( " GLBE_DrawWorld: drawn everything \n " ) ) ;
2005-09-08 22:52:46 +00:00
}
2013-04-06 03:36:00 +00:00
2015-03-03 00:14:43 +00:00
void GLBE_VBO_Begin ( vbobctx_t * ctx , size_t maxsize )
2013-04-06 03:36:00 +00:00
{
2018-04-08 14:24:50 +00:00
COM_AssertMainThread ( " GLBE_VBO_Begin " ) ; //actually, we should probably just build this in memory and throw it to the main thread as needed, but we still need some buffers indexes. I guess we could build a list of varrays. the other option is to just create a large persistant-mapped buffer, and then just append+reuse from any thread, but that makes destruction messy.
2014-10-05 20:04:11 +00:00
2013-04-06 03:36:00 +00:00
ctx - > maxsize = maxsize ;
ctx - > pos = 0 ;
2013-05-10 15:20:47 +00:00
ctx - > fallback = NULL ;
2018-04-08 14:24:50 +00:00
if ( qglBufferStorage )
2013-05-10 15:20:47 +00:00
{
2018-04-08 14:24:50 +00:00
ctx - > vboid [ 0 ] = ctx - > vboid [ 1 ] = 0 ;
qglGenBuffersARB ( 2 , ctx - > vboid ) ;
ctx - > fallback = BZ_Malloc ( maxsize ) ;
}
else if ( qglBufferDataARB )
{
ctx - > vboid [ 0 ] = ctx - > vboid [ 1 ] = 0 ;
2013-05-10 15:20:47 +00:00
qglGenBuffersARB ( 2 , ctx - > vboid ) ;
GL_SelectVBO ( ctx - > vboid [ 0 ] ) ;
//WARNING: in emscripten/webgl, we should probably not pass null.
qglBufferDataARB ( GL_ARRAY_BUFFER_ARB , ctx - > maxsize , NULL , GL_STATIC_DRAW_ARB ) ;
}
else
ctx - > fallback = BZ_Malloc ( maxsize ) ;
2013-04-06 03:36:00 +00:00
}
2015-03-03 00:14:43 +00:00
void GLBE_VBO_Data ( vbobctx_t * ctx , void * data , size_t size , vboarray_t * varray )
2013-04-06 03:36:00 +00:00
{
2018-04-08 14:24:50 +00:00
if ( qglBufferStorage )
{
memcpy ( ( char * ) ctx - > fallback + ctx - > pos , data , size ) ;
varray - > gl . vbo = ctx - > vboid [ 0 ] ;
varray - > gl . addr = ( void * ) ctx - > pos ;
}
else if ( ctx - > fallback )
2013-05-10 15:20:47 +00:00
{
2013-05-11 14:02:55 +00:00
memcpy ( ( char * ) ctx - > fallback + ctx - > pos , data , size ) ;
2013-05-10 15:20:47 +00:00
varray - > gl . vbo = 0 ;
2013-05-11 14:02:55 +00:00
varray - > gl . addr = ( char * ) ctx - > fallback + ctx - > pos ;
2013-05-10 15:20:47 +00:00
}
else
{
qglBufferSubDataARB ( GL_ARRAY_BUFFER_ARB , ctx - > pos , size , data ) ;
varray - > gl . vbo = ctx - > vboid [ 0 ] ;
varray - > gl . addr = ( void * ) ctx - > pos ;
}
2013-04-06 03:36:00 +00:00
ctx - > pos + = size ;
}
2016-07-12 00:40:13 +00:00
void GLBE_VBO_Finish ( vbobctx_t * ctx , void * edata , size_t esize , vboarray_t * earray , void * * vbomem , void * * ebomem )
2013-04-06 03:36:00 +00:00
{
if ( ctx - > pos > ctx - > maxsize )
Sys_Error ( " BE_VBO_Finish: too much data given \n " ) ;
2018-04-08 14:24:50 +00:00
if ( qglBufferStorage )
{
GL_SelectVBO ( ctx - > vboid [ 0 ] ) ;
qglBufferStorage ( GL_ARRAY_BUFFER_ARB , ctx - > pos , ctx - > fallback , 0 ) ;
BZ_Free ( ctx - > fallback ) ;
ctx - > fallback = NULL ;
GL_SelectEBO ( ctx - > vboid [ 1 ] ) ;
qglBufferStorage ( GL_ELEMENT_ARRAY_BUFFER_ARB , esize , edata , 0 ) ;
earray - > gl . vbo = ctx - > vboid [ 1 ] ;
earray - > gl . addr = NULL ;
}
else if ( ctx - > fallback )
2013-05-10 15:20:47 +00:00
{
void * d = BZ_Malloc ( esize ) ;
memcpy ( d , edata , esize ) ;
earray - > gl . vbo = 0 ;
earray - > gl . addr = d ;
}
else
{
GL_SelectEBO ( ctx - > vboid [ 1 ] ) ;
qglBufferDataARB ( GL_ELEMENT_ARRAY_BUFFER_ARB , esize , edata , GL_STATIC_DRAW_ARB ) ;
earray - > gl . vbo = ctx - > vboid [ 1 ] ;
earray - > gl . addr = NULL ;
}
2013-04-06 03:36:00 +00:00
}
2016-07-12 00:40:13 +00:00
void GLBE_VBO_Destroy ( vboarray_t * vearray , void * vbomem )
2013-04-06 03:36:00 +00:00
{
2013-05-10 15:20:47 +00:00
if ( vearray - > gl . vbo )
2015-03-03 00:14:43 +00:00
{
2013-05-10 15:20:47 +00:00
qglDeleteBuffersARB ( 1 , & vearray - > gl . vbo ) ;
2015-03-03 00:14:43 +00:00
vearray - > gl . vbo = 0 ;
}
2013-05-10 15:20:47 +00:00
else
BZ_Free ( vearray - > gl . addr ) ;
2015-03-03 00:14:43 +00:00
vearray - > gl . addr = NULL ;
2013-04-06 03:36:00 +00:00
}
2009-11-04 21:16:50 +00:00
# endif