2009-11-04 21:16:50 +00:00
# include "quakedef.h"
2012-07-05 19:42:36 +00:00
/*
room for improvement :
There is no screen - space culling of lit surfaces .
model meshes are interpolated multiple times per frame
*/
2012-08-04 01:35:52 +00:00
//#define DBG_COLOURNOTDEPTH
2009-11-04 21:16:50 +00:00
# ifdef RTLIGHTS
# include "glquake.h"
# include "shader.h"
2012-09-30 05:52:03 +00:00
# ifdef D3D9QUAKE
2012-01-01 02:26:42 +00:00
# include "shader.h"
# if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500)
# define HMONITOR_DECLARED
DECLARE_HANDLE ( HMONITOR ) ;
# endif
# include <d3d9.h>
extern LPDIRECT3DDEVICE9 pD3DDev9 ;
2012-09-30 05:52:03 +00:00
void D3D9BE_Cull ( unsigned int sflags ) ;
void D3D9BE_RenderShadowBuffer ( unsigned int numverts , IDirect3DVertexBuffer9 * vbuf , unsigned int numindicies , IDirect3DIndexBuffer9 * ibuf ) ;
2012-01-01 02:26:42 +00:00
# endif
2013-11-21 23:02:28 +00:00
# ifdef D3D11QUAKE
void D3D11BE_GenerateShadowBuffer ( void * * vbuf , vecV_t * verts , int numverts , void * * ibuf , index_t * indicies , int numindicies ) ;
void D3D11BE_RenderShadowBuffer ( unsigned int numverts , void * vbuf , unsigned int numindicies , void * ibuf ) ;
void D3D11_DestroyShadowBuffer ( void * vbuf , void * ibuf ) ;
void D3D11BE_DoneShadows ( void ) ;
# endif
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-08-04 01:35:52 +00:00
static void SHM_Shutdown ( void ) ;
2010-07-11 02:22:39 +00:00
# define SHADOWMAP_SIZE 512
2011-12-05 15:23:40 +00:00
# define PROJECTION_DISTANCE (float)(dl->radius*2) //0x7fffffff
2012-08-04 01:35:52 +00:00
static texid_t shadowmap [ 2 ] ;
2009-11-04 21:16:50 +00:00
2010-07-11 02:22:39 +00:00
static int shadow_fbo_id ;
2013-10-08 14:28:11 +00:00
static int shadow_fbo_depth_num ;
2011-12-05 15:23:40 +00:00
static int crepuscular_fbo_id ;
texid_t crepuscular_texture_id ;
shader_t * crepuscular_shader ;
2010-07-11 02:22:39 +00:00
2013-10-08 14:28:11 +00:00
cvar_t r_shadow_shadowmapping_nearclip = CVAR ( " r_shadow_shadowmapping_nearclip " , " 1 " ) ;
cvar_t r_shadow_shadowmapping_bias = CVAR ( " r_shadow_shadowmapping_bias " , " 0.03 " ) ;
cvar_t r_shadow_scissor = CVAR ( " r_shadow_scissor " , " 1 " ) ;
2009-11-04 21:16:50 +00:00
2013-10-08 14:28:11 +00:00
cvar_t r_shadow_realtime_world = SCVARF ( " r_shadow_realtime_world " , " 0 " , CVAR_ARCHIVE ) ;
cvar_t r_shadow_realtime_world_shadows = SCVARF ( " r_shadow_realtime_world_shadows " , " 1 " , CVAR_ARCHIVE ) ;
cvar_t r_shadow_realtime_world_lightmaps = SCVARF ( " r_shadow_realtime_world_lightmaps " , " 0 " , 0 ) ;
# ifdef FTE_TARGET_WEB
cvar_t r_shadow_realtime_dlight = SCVARF ( " r_shadow_realtime_dlight " , " 0 " , CVAR_ARCHIVE ) ;
# else
cvar_t r_shadow_realtime_dlight = SCVARF ( " r_shadow_realtime_dlight " , " 1 " , CVAR_ARCHIVE ) ;
# endif
cvar_t r_shadow_realtime_dlight_shadows = SCVARF ( " r_shadow_realtime_dlight_shadows " , " 1 " , CVAR_ARCHIVE ) ;
cvar_t r_shadow_realtime_dlight_ambient = SCVAR ( " r_shadow_realtime_dlight_ambient " , " 0 " ) ;
cvar_t r_shadow_realtime_dlight_diffuse = SCVAR ( " r_shadow_realtime_dlight_diffuse " , " 1 " ) ;
cvar_t r_shadow_realtime_dlight_specular = SCVAR ( " r_shadow_realtime_dlight_specular " , " 4 " ) ; //excessive, but noticable. its called stylized, okay? shiesh, some people
cvar_t r_editlights_import_radius = SCVAR ( " r_editlights_import_radius " , " 1 " ) ;
cvar_t r_editlights_import_ambient = SCVAR ( " r_editlights_import_ambient " , " 0 " ) ;
cvar_t r_editlights_import_diffuse = SCVAR ( " r_editlights_import_diffuse " , " 1 " ) ;
cvar_t r_editlights_import_specular = SCVAR ( " r_editlights_import_specular " , " 1 " ) ; //excessive, but noticable. its called stylized, okay? shiesh, some people
2013-10-29 17:38:22 +00:00
cvar_t r_shadow_shadowmapping = SCVARF ( " r_shadow_shadowmapping " , " 1 " , 0 ) ;
2013-10-08 14:28:11 +00:00
cvar_t r_shadow_shadowmapping_precision = CVARD ( " r_shadow_shadowmapping_precision " , " 1 " , " Scales the shadowmap detail level up or down. " ) ;
extern cvar_t r_shadow_shadowmapping_nearclip ;
extern cvar_t r_shadow_shadowmapping_bias ;
cvar_t r_sun_dir = CVARD ( " r_sun_dir " , " 0.2 0.5 0.8 " , " Specifies the direction that crepusular rays appear along " ) ;
cvar_t r_sun_colour = CVARFD ( " r_sun_colour " , " 0 0 0 " , CVAR_ARCHIVE , " Specifies the colour of sunlight that appears in the form of crepuscular rays. " ) ;
2009-11-04 21:16:50 +00:00
2013-10-08 14:28:11 +00:00
static void Sh_DrawEntLighting ( dlight_t * light , vec3_t colour ) ;
2009-11-04 21:16:50 +00:00
2013-10-29 17:38:22 +00:00
static qbyte lvisb [ ( MAX_MAP_LEAFS + 7 ) > > 3 ] ;
2009-11-04 21:16:50 +00:00
2012-09-30 05:52:03 +00:00
/*
called on framebuffer resize .
flushes textures so they can be regenerated at the real size
*/
void Sh_Reset ( void )
2012-01-01 02:26:42 +00:00
{
# ifdef GLQUAKE
if ( shadow_fbo_id )
{
qglDeleteRenderbuffersEXT ( 1 , & shadow_fbo_id ) ;
shadow_fbo_id = 0 ;
2013-10-08 14:28:11 +00:00
shadow_fbo_depth_num = 0 ;
2012-01-01 02:26:42 +00:00
}
2012-08-04 01:35:52 +00:00
if ( shadowmap [ 0 ] . num )
{
R_DestroyTexture ( shadowmap [ 0 ] ) ;
shadowmap [ 0 ] = r_nulltex ;
}
if ( shadowmap [ 1 ] . num )
{
R_DestroyTexture ( shadowmap [ 1 ] ) ;
shadowmap [ 1 ] = r_nulltex ;
}
2012-05-11 01:57:00 +00:00
if ( crepuscular_texture_id . num )
{
R_DestroyTexture ( crepuscular_texture_id ) ;
crepuscular_texture_id = r_nulltex ;
}
2012-01-01 02:26:42 +00:00
if ( crepuscular_fbo_id )
{
qglDeleteRenderbuffersEXT ( 1 , & crepuscular_fbo_id ) ;
crepuscular_fbo_id = 0 ;
}
# endif
2012-09-30 05:52:03 +00:00
}
void Sh_Shutdown ( void )
{
Sh_Reset ( ) ;
2012-08-04 01:35:52 +00:00
SHM_Shutdown ( ) ;
2012-01-01 02:26:42 +00:00
}
2009-11-04 21:16:50 +00:00
typedef struct {
unsigned int count ;
unsigned int max ;
2012-05-09 15:30:53 +00:00
texture_t * tex ;
vbo_t * vbo ;
2010-07-11 02:22:39 +00:00
mesh_t * * s ;
2012-05-09 15:30:53 +00:00
} shadowmeshbatch_t ;
2013-06-23 02:17:02 +00:00
typedef struct shadowmesh_s
{
enum
{
2013-10-08 14:28:11 +00:00
SMT_STENCILVOLUME , //build edges mesh (and surface list)
SMT_SHADOWMAP , //build front faces mesh (and surface list)
SMT_SHADOWLESS //build surface list only
2013-06-23 02:17:02 +00:00
} type ;
2009-11-04 21:16:50 +00:00
unsigned int numindicies ;
unsigned int maxindicies ;
index_t * indicies ;
unsigned int numverts ;
unsigned int maxverts ;
vecV_t * verts ;
//we also have a list of all the surfaces that this light lights.
2012-05-09 15:30:53 +00:00
unsigned int numbatches ;
shadowmeshbatch_t * batches ;
2009-11-04 21:16:50 +00:00
unsigned int leafbytes ;
unsigned char * litleaves ;
2011-12-05 15:23:40 +00:00
2012-01-01 02:26:42 +00:00
# ifdef GLQUAKE
2011-12-05 15:23:40 +00:00
GLuint vebo [ 2 ] ;
2012-01-01 02:26:42 +00:00
# endif
2012-09-30 05:52:03 +00:00
# ifdef D3D9QUAKE
2013-11-21 23:02:28 +00:00
IDirect3DVertexBuffer9 * d3d9_vbuffer ;
IDirect3DIndexBuffer9 * d3d9_ibuffer ;
# endif
# ifdef D3D11QUAKE
void * d3d11_vbuffer ;
void * d3d11_ibuffer ;
2012-01-01 02:26:42 +00:00
# endif
2009-11-04 21:16:50 +00:00
} shadowmesh_t ;
/*state of the current shadow mesh*/
# define inc 128
int sh_shadowframe ;
static int sh_firstindex ;
static int sh_vertnum ; //vertex number (set to 0 at SH_Begin)
static shadowmesh_t * sh_shmesh , sh_tempshmesh ;
/* functions to add geometry to the shadow mesh */
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 SHM_BeginQuads ( void )
2009-11-04 21:16:50 +00:00
{
sh_firstindex = sh_shmesh - > numverts ;
}
static void SHM_End ( void )
{
int i ;
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
i = ( sh_shmesh - > numindicies + ( sh_vertnum / 4 ) * 6 + inc + 5 ) & ~ ( inc - 1 ) ; //and a bit of padding
if ( sh_shmesh - > maxindicies ! = i )
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
sh_shmesh - > maxindicies = i ;
2011-05-15 13:23:13 +00:00
sh_shmesh - > indicies = BZ_Realloc ( sh_shmesh - > indicies , i * sizeof ( * sh_shmesh - > indicies ) ) ;
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
}
//add the extra triangles
for ( i = 0 ; i < sh_vertnum ; i + = 4 )
{
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = sh_firstindex + i + 0 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = sh_firstindex + i + 1 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = sh_firstindex + i + 2 ;
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
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = sh_firstindex + i + 0 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = sh_firstindex + i + 2 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = sh_firstindex + i + 3 ;
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
sh_vertnum = 0 ;
2009-11-04 21:16:50 +00:00
}
2012-01-01 02:26:42 +00:00
static void SHM_Vertex3fv ( const float * v )
2009-11-04 21:16:50 +00:00
{
int i ;
//add the verts as we go
i = ( sh_shmesh - > numverts + inc + 5 ) & ~ ( inc - 1 ) ; //and a bit of padding
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
if ( sh_shmesh - > maxverts < i )
2009-11-04 21:16:50 +00:00
{
sh_shmesh - > maxverts = i ;
sh_shmesh - > verts = BZ_Realloc ( sh_shmesh - > verts , i * sizeof ( * sh_shmesh - > verts ) ) ;
}
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
sh_shmesh - > verts [ sh_shmesh - > numverts ] [ 0 ] = v [ 0 ] ;
sh_shmesh - > verts [ sh_shmesh - > numverts ] [ 1 ] = v [ 1 ] ;
sh_shmesh - > verts [ sh_shmesh - > numverts ] [ 2 ] = v [ 2 ] ;
2009-11-04 21:16:50 +00:00
sh_vertnum + + ;
sh_shmesh - > numverts + + ;
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
if ( sh_vertnum = = 4 )
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
SHM_End ( ) ;
sh_firstindex = sh_shmesh - > numverts ;
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
2013-10-08 14:28:11 +00:00
static void SHM_MeshFrontOnly ( int numverts , vecV_t * verts , int numidx , index_t * idx )
{
int first = sh_shmesh - > numverts ;
int v , i ;
vecV_t * outv ;
index_t * outi ;
/*make sure there's space*/
v = ( sh_shmesh - > numverts + numverts + inc ) & ~ ( inc - 1 ) ; //and a bit of padding
if ( sh_shmesh - > maxverts < v )
{
v + = 1024 ;
sh_shmesh - > maxverts = v ;
sh_shmesh - > verts = BZ_Realloc ( sh_shmesh - > verts , v * sizeof ( * sh_shmesh - > verts ) ) ;
}
outv = sh_shmesh - > verts + sh_shmesh - > numverts ;
for ( v = 0 ; v < numverts ; v + + )
{
VectorCopy ( verts [ v ] , outv [ v ] ) ;
}
v = ( sh_shmesh - > numindicies + numidx + inc ) & ~ ( inc - 1 ) ; //and a bit of padding
if ( sh_shmesh - > maxindicies < v )
{
v + = 1024 ;
sh_shmesh - > maxindicies = v ;
sh_shmesh - > indicies = BZ_Realloc ( sh_shmesh - > indicies , v * sizeof ( * sh_shmesh - > indicies ) ) ;
}
outi = sh_shmesh - > indicies + sh_shmesh - > numindicies ;
for ( i = 0 ; i < numidx ; i + + )
{
outi [ i ] = first + idx [ i ] ;
}
sh_shmesh - > numverts + = numverts ;
sh_shmesh - > numindicies + = numidx ;
}
2011-07-30 14:14:56 +00:00
static void SHM_TriangleFan ( int numverts , vecV_t * verts , vec3_t lightorg , float pd )
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
int v , i , idxs ;
float * v1 ;
vec3_t v3 ;
vecV_t * outv ;
index_t * outi ;
/*make sure there's space*/
v = ( sh_shmesh - > numverts + numverts * 2 + inc ) & ~ ( inc - 1 ) ; //and a bit of padding
if ( sh_shmesh - > maxverts < v )
{
2013-03-12 23:09:25 +00:00
v + = 1024 ;
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
sh_shmesh - > maxverts = v ;
sh_shmesh - > verts = BZ_Realloc ( sh_shmesh - > verts , v * sizeof ( * sh_shmesh - > verts ) ) ;
}
outv = sh_shmesh - > verts + sh_shmesh - > numverts ;
for ( v = 0 ; v < numverts ; v + + )
{
v1 = verts [ v ] ;
VectorCopy ( v1 , outv [ v ] ) ;
v3 [ 0 ] = ( v1 [ 0 ] - lightorg [ 0 ] ) * pd ;
v3 [ 1 ] = ( v1 [ 1 ] - lightorg [ 1 ] ) * pd ;
v3 [ 2 ] = ( v1 [ 2 ] - lightorg [ 2 ] ) * pd ;
outv [ v + numverts ] [ 0 ] = v1 [ 0 ] + v3 [ 0 ] ;
outv [ v + numverts ] [ 1 ] = v1 [ 1 ] + v3 [ 1 ] ;
outv [ v + numverts ] [ 2 ] = v1 [ 2 ] + v3 [ 2 ] ;
}
idxs = ( numverts - 2 ) * 3 ;
/*now add the verts in a fan*/
v = ( sh_shmesh - > numindicies + idxs * 2 + inc ) & ~ ( inc - 1 ) ; //and a bit of padding
if ( sh_shmesh - > maxindicies < v )
{
2013-03-12 23:09:25 +00:00
v + = 1024 ;
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
sh_shmesh - > maxindicies = v ;
sh_shmesh - > indicies = BZ_Realloc ( sh_shmesh - > indicies , v * sizeof ( * sh_shmesh - > indicies ) ) ;
}
outi = sh_shmesh - > indicies + sh_shmesh - > numindicies ;
for ( v = 2 , i = 0 ; v < numverts ; v + + , i + = 3 )
{
outi [ i + 0 ] = sh_shmesh - > numverts ;
outi [ i + 1 ] = sh_shmesh - > numverts + v - 1 ;
outi [ i + 2 ] = sh_shmesh - > numverts + v ;
outi [ i + 0 + idxs ] = sh_shmesh - > numverts + numverts + v ;
outi [ i + 1 + idxs ] = sh_shmesh - > numverts + numverts + v - 1 ;
outi [ i + 2 + idxs ] = sh_shmesh - > numverts + numverts ;
}
/*we added this many*/
sh_shmesh - > numverts + = numverts * 2 ;
sh_shmesh - > numindicies + = i * 2 ;
2009-11-04 21:16:50 +00:00
}
static void SHM_Shadow_Cache_Surface ( msurface_t * surf )
{
int i ;
2012-05-09 15:30:53 +00:00
i = surf - > sbatch - > shadowbatch ;
2010-07-11 02:22:39 +00:00
if ( i < 0 )
return ;
2012-05-09 15:30:53 +00:00
if ( sh_shmesh - > batches [ i ] . count = = sh_shmesh - > batches [ i ] . max )
2009-11-04 21:16:50 +00:00
{
2012-05-09 15:30:53 +00:00
sh_shmesh - > batches [ i ] . max + = 64 ;
sh_shmesh - > batches [ i ] . s = BZ_Realloc ( sh_shmesh - > batches [ i ] . s , sizeof ( void * ) * ( sh_shmesh - > batches [ i ] . max ) ) ;
2009-11-04 21:16:50 +00:00
}
2012-05-09 15:30:53 +00:00
sh_shmesh - > batches [ i ] . s [ sh_shmesh - > batches [ i ] . count ] = surf - > mesh ;
sh_shmesh - > batches [ i ] . count + + ;
2009-11-04 21:16:50 +00:00
}
static void SHM_Shadow_Cache_Leaf ( mleaf_t * leaf )
{
int i ;
i = leaf - cl . worldmodel - > leafs ;
sh_shmesh - > litleaves [ i > > 3 ] | = 1 < < ( i & 7 ) ;
}
2012-09-30 05:52:03 +00:00
static void SH_FreeShadowMesh_ ( shadowmesh_t * sm )
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
{
unsigned int i ;
2012-05-09 15:30:53 +00:00
for ( i = 0 ; i < sm - > numbatches ; i + + )
Z_Free ( sm - > batches [ i ] . s ) ;
2012-09-30 05:52:03 +00:00
sm - > numbatches = 0 ;
2012-05-09 15:30:53 +00:00
Z_Free ( sm - > batches ) ;
2012-09-30 05:52:03 +00:00
sm - > batches = NULL ;
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
Z_Free ( sm - > indicies ) ;
2012-09-30 05:52:03 +00:00
sm - > indicies = NULL ;
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
Z_Free ( sm - > verts ) ;
2012-09-30 05:52:03 +00:00
sm - > verts = NULL ;
2013-10-08 14:28:11 +00:00
sm - > numindicies = 0 ;
sm - > numverts = 0 ;
2011-12-05 15:23:40 +00:00
2012-01-01 02:26:42 +00:00
switch ( qrenderer )
{
2013-03-12 22:47:42 +00:00
case QR_NONE :
case QR_SOFTWARE :
default :
break ;
# ifdef GLQUAKE
2013-11-21 23:02:28 +00:00
case QR_OPENGL :
2012-10-18 10:10:11 +00:00
if ( qglDeleteBuffersARB )
qglDeleteBuffersARB ( 2 , sm - > vebo ) ;
2012-01-01 02:26:42 +00:00
sm - > vebo [ 0 ] = 0 ;
sm - > vebo [ 1 ] = 0 ;
2013-03-12 22:47:42 +00:00
break ;
2013-11-21 23:02:28 +00:00
# endif
2013-03-12 22:47:42 +00:00
# ifdef D3D9QUAKE
2013-11-21 23:02:28 +00:00
case QR_DIRECT3D9 :
if ( sm - > d3d9_ibuffer )
IDirect3DIndexBuffer9_Release ( sm - > d3d9_ibuffer ) ;
sm - > d3d9_ibuffer = NULL ;
if ( sm - > d3d9_vbuffer )
IDirect3DVertexBuffer9_Release ( sm - > d3d9_vbuffer ) ;
sm - > d3d9_vbuffer = NULL ;
break ;
2012-01-01 02:26:42 +00:00
# endif
2013-11-21 23:02:28 +00:00
# ifdef D3D11QUAKE
case QR_DIRECT3D11 :
D3D11_DestroyShadowBuffer ( sm - > d3d11_vbuffer , sm - > d3d11_ibuffer ) ;
sm - > d3d11_vbuffer = NULL ;
sm - > d3d11_ibuffer = NULL ;
2013-03-12 22:47:42 +00:00
break ;
2013-11-21 23:02:28 +00:00
# endif
2012-01-01 02:26:42 +00:00
}
2012-09-30 05:52:03 +00:00
}
void SH_FreeShadowMesh ( shadowmesh_t * sm )
{
SH_FreeShadowMesh_ ( sm ) ;
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
Z_Free ( sm ) ;
}
2012-05-09 15:30:53 +00:00
static void SH_CalcShadowBatches ( model_t * mod )
{
int s ;
batch_t * b ;
batch_t * l = NULL ;
int sb ;
l = NULL ;
for ( s = 0 ; s < SHADER_SORT_COUNT ; s + + )
{
for ( b = mod - > batches [ s ] ; b ; b = b - > next )
{
if ( ! l | | l - > vbo ! = b - > vbo | | l - > texture ! = b - > texture )
{
b - > shadowbatch = mod - > numshadowbatches + + ;
l = b ;
}
else
b - > shadowbatch = l - > shadowbatch ;
}
}
l = NULL ;
sb = 0 ;
mod - > shadowbatches = BZ_Malloc ( sizeof ( * mod - > shadowbatches ) * mod - > numshadowbatches ) ;
for ( s = 0 ; s < SHADER_SORT_COUNT ; s + + )
{
for ( b = mod - > batches [ s ] ; b ; b = b - > next )
{
if ( ! l | | l - > vbo ! = b - > vbo | | l - > texture ! = b - > texture )
{
mod - > shadowbatches [ sb ] . tex = b - > texture ;
mod - > shadowbatches [ sb ] . vbo = b - > vbo ;
sb + + ;
l = b ;
}
}
}
}
2013-06-23 02:17:02 +00:00
static void SHM_BeginShadowMesh ( dlight_t * dl , int type )
2009-11-04 21:16:50 +00:00
{
unsigned int i ;
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
unsigned int lb ;
2009-11-04 21:16:50 +00:00
sh_vertnum = 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
lb = ( cl . worldmodel - > numleafs + 7 ) / 8 ;
if ( ! dl - > die | | ! dl - > key )
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
sh_shmesh = dl - > worldshadowmesh ;
if ( ! sh_shmesh | | sh_shmesh - > leafbytes ! = lb )
{
/*this shouldn't happen too often*/
if ( sh_shmesh )
2013-10-08 14:28:11 +00:00
{ //FIXME: if the light is the same light, reuse the memory allocations where possible...
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
SH_FreeShadowMesh ( sh_shmesh ) ;
}
/*Create a new shadowmesh for this light*/
sh_shmesh = Z_Malloc ( sizeof ( * sh_shmesh ) + lb ) ;
sh_shmesh - > leafbytes = lb ;
sh_shmesh - > litleaves = ( unsigned char * ) ( sh_shmesh + 1 ) ;
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
dl - > worldshadowmesh = sh_shmesh ;
}
2013-03-12 23:11:08 +00:00
memset ( sh_shmesh - > litleaves , 0 , sh_shmesh - > leafbytes ) ;
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
dl - > rebuildcache = false ;
2009-11-04 21:16:50 +00:00
}
else
{
sh_shmesh = & sh_tempshmesh ;
if ( sh_shmesh - > leafbytes ! = lb )
{
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
/*this happens on map changes*/
2009-11-04 21:16:50 +00:00
sh_shmesh - > leafbytes = lb ;
Z_Free ( sh_shmesh - > litleaves ) ;
sh_shmesh - > litleaves = Z_Malloc ( lb ) ;
}
}
sh_shmesh - > maxverts = 0 ;
sh_shmesh - > numverts = 0 ;
sh_shmesh - > maxindicies = 0 ;
sh_shmesh - > numindicies = 0 ;
2013-06-23 02:17:02 +00:00
sh_shmesh - > type = type ;
2009-11-04 21:16:50 +00:00
2012-05-09 15:30:53 +00:00
if ( ! cl . worldmodel - > numshadowbatches )
2009-11-04 21:16:50 +00:00
{
2012-05-09 15:30:53 +00:00
SH_CalcShadowBatches ( cl . worldmodel ) ;
}
if ( sh_shmesh - > numbatches ! = cl . worldmodel - > numshadowbatches )
{
if ( sh_shmesh - > batches )
2009-11-04 21:16:50 +00:00
{
2012-05-09 15:30:53 +00:00
for ( i = 0 ; i < sh_shmesh - > numbatches ; i + + )
Z_Free ( sh_shmesh - > batches [ i ] . s ) ;
Z_Free ( sh_shmesh - > batches ) ;
2009-11-04 21:16:50 +00:00
}
2012-05-09 15:30:53 +00:00
sh_shmesh - > batches = Z_Malloc ( sizeof ( shadowmeshbatch_t ) * cl . worldmodel - > numshadowbatches ) ;
sh_shmesh - > numbatches = cl . worldmodel - > numshadowbatches ;
2009-11-04 21:16:50 +00:00
}
2012-05-09 15:30:53 +00:00
for ( i = 0 ; i < sh_shmesh - > numbatches ; i + + )
2009-11-04 21:16:50 +00:00
{
2012-05-09 15:30:53 +00:00
sh_shmesh - > batches [ i ] . count = 0 ;
2009-11-04 21:16:50 +00:00
}
}
static struct shadowmesh_s * SHM_FinishShadowMesh ( dlight_t * dl )
{
2011-12-05 15:23:40 +00:00
if ( sh_shmesh ! = & sh_tempshmesh )
{
2012-01-01 02:26:42 +00:00
switch ( qrenderer )
{
2013-03-12 22:47:42 +00:00
case QR_NONE :
case QR_SOFTWARE :
default :
break ;
2012-01-01 02:26:42 +00:00
case QR_OPENGL :
2013-03-12 22:47:42 +00:00
# ifdef GLQUAKE
2013-11-21 23:02:28 +00:00
if ( ! qglGenBuffersARB )
return sh_shmesh ;
2012-01-01 02:26:42 +00:00
qglGenBuffersARB ( 2 , sh_shmesh - > vebo ) ;
2012-11-27 03:23:19 +00:00
GL_DeselectVAO ( ) ;
2012-01-01 02:26:42 +00:00
GL_SelectVBO ( sh_shmesh - > vebo [ 0 ] ) ;
qglBufferDataARB ( GL_ARRAY_BUFFER_ARB , sizeof ( * sh_shmesh - > verts ) * sh_shmesh - > numverts , sh_shmesh - > verts , GL_STATIC_DRAW_ARB ) ;
GL_SelectEBO ( sh_shmesh - > vebo [ 1 ] ) ;
qglBufferDataARB ( GL_ELEMENT_ARRAY_BUFFER_ARB , sizeof ( * sh_shmesh - > indicies ) * sh_shmesh - > numindicies , sh_shmesh - > indicies , GL_STATIC_DRAW_ARB ) ;
# endif
2013-03-12 22:47:42 +00:00
break ;
2012-09-30 05:52:03 +00:00
case QR_DIRECT3D9 :
2013-03-12 22:47:42 +00:00
# ifdef D3D9QUAKE
2012-01-01 02:26:42 +00:00
if ( sh_shmesh - > numindicies & & sh_shmesh - > numverts )
{
void * map ;
2013-11-21 23:02:28 +00:00
IDirect3DDevice9_CreateIndexBuffer ( pD3DDev9 , sizeof ( index_t ) * sh_shmesh - > numindicies , 0 , D3DFMT_QINDEX , D3DPOOL_MANAGED , & sh_shmesh - > d3d9_ibuffer , NULL ) ;
IDirect3DIndexBuffer9_Lock ( sh_shmesh - > d3d9_ibuffer , 0 , sizeof ( index_t ) * sh_shmesh - > numindicies , & map , D3DLOCK_DISCARD ) ;
2012-01-01 02:26:42 +00:00
memcpy ( map , sh_shmesh - > indicies , sizeof ( index_t ) * sh_shmesh - > numindicies ) ;
2013-11-21 23:02:28 +00:00
IDirect3DIndexBuffer9_Unlock ( sh_shmesh - > d3d9_ibuffer ) ;
2012-01-01 02:26:42 +00:00
2013-11-21 23:02:28 +00:00
IDirect3DDevice9_CreateVertexBuffer ( pD3DDev9 , sizeof ( vecV_t ) * sh_shmesh - > numverts , D3DUSAGE_WRITEONLY , 0 , D3DPOOL_MANAGED , & sh_shmesh - > d3d9_vbuffer , NULL ) ;
IDirect3DVertexBuffer9_Lock ( sh_shmesh - > d3d9_vbuffer , 0 , sizeof ( vecV_t ) * sh_shmesh - > numverts , & map , D3DLOCK_DISCARD ) ;
2012-01-01 02:26:42 +00:00
memcpy ( map , sh_shmesh - > verts , sizeof ( vecV_t ) * sh_shmesh - > numverts ) ;
2013-11-21 23:02:28 +00:00
IDirect3DVertexBuffer9_Unlock ( sh_shmesh - > d3d9_vbuffer ) ;
2012-01-01 02:26:42 +00:00
}
# endif
2013-03-12 22:47:42 +00:00
break ;
2013-11-21 23:02:28 +00:00
# ifdef D3D11QUAKE
case QR_DIRECT3D11 :
D3D11BE_GenerateShadowBuffer ( & sh_shmesh - > d3d11_vbuffer , sh_shmesh - > verts , sh_shmesh - > numverts , & sh_shmesh - > d3d11_ibuffer , sh_shmesh - > indicies , sh_shmesh - > numindicies ) ;
break ;
# endif
2012-01-01 02:26:42 +00:00
}
2011-12-05 15:23:40 +00:00
Z_Free ( sh_shmesh - > verts ) ;
sh_shmesh - > verts = NULL ;
Z_Free ( sh_shmesh - > indicies ) ;
sh_shmesh - > indicies = NULL ;
}
2009-11-04 21:16:50 +00:00
return sh_shmesh ;
}
/*state of the world that is still to compile*/
static struct {
short count ;
short count2 ;
int next ;
int prev ;
} edge [ MAX_MAP_EDGES ] ;
static int firstedge ;
static void SHM_RecursiveWorldNodeQ1_r ( dlight_t * dl , mnode_t * node )
{
int c , side ;
mplane_t * plane ;
msurface_t * surf , * * mark ;
mleaf_t * pleaf ;
double dot ;
int v ;
float l , maxdist ;
int j , s , t ;
vec3_t impact ;
if ( node - > shadowframe ! = sh_shadowframe )
return ;
if ( node - > contents = = Q1CONTENTS_SOLID )
return ; // solid
//if light areabox is outside node, ignore node + children
for ( c = 0 ; c < 3 ; c + + )
{
if ( dl - > origin [ c ] + dl - > radius < node - > minmaxs [ c ] )
return ;
if ( dl - > origin [ c ] - dl - > radius > node - > minmaxs [ 3 + c ] )
return ;
}
2011-05-15 13:23:13 +00:00
2009-11-04 21:16:50 +00:00
// if a leaf node, draw stuff
if ( node - > contents < 0 )
{
pleaf = ( mleaf_t * ) node ;
SHM_Shadow_Cache_Leaf ( pleaf ) ;
mark = pleaf - > firstmarksurface ;
c = pleaf - > nummarksurfaces ;
if ( c )
{
do
{
( * mark + + ) - > shadowframe = sh_shadowframe ;
} while ( - - c ) ;
}
return ;
}
// node is just a decision point, so go down the apropriate sides
// find which side of the node we are on
plane = node - > plane ;
switch ( plane - > type )
{
case PLANE_X :
dot = dl - > origin [ 0 ] - plane - > dist ;
break ;
case PLANE_Y :
dot = dl - > origin [ 1 ] - plane - > dist ;
break ;
case PLANE_Z :
dot = dl - > origin [ 2 ] - plane - > dist ;
break ;
default :
dot = DotProduct ( dl - > origin , plane - > normal ) - plane - > dist ;
break ;
}
if ( dot > = 0 )
side = 0 ;
else
side = 1 ;
// recurse down the children, front side first
SHM_RecursiveWorldNodeQ1_r ( dl , node - > children [ side ] ) ;
// draw stuff
c = node - > numsurfaces ;
if ( c )
{
surf = cl . worldmodel - > surfaces + node - > firstsurface ;
{
maxdist = dl - > radius * dl - > radius ;
for ( ; c ; c - - , surf + + )
{
if ( surf - > shadowframe ! = sh_shadowframe )
continue ;
// if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))
// continue; // wrong side
// if (surf->flags & SURF_PLANEBACK)
// continue;
if ( surf - > flags & ( SURF_DRAWALPHA | SURF_DRAWTILED ) )
{ // no shadows
continue ;
}
//is the light on the right side?
if ( surf - > flags & SURF_PLANEBACK )
{ //inverted normal.
if ( - DotProduct ( surf - > plane - > normal , dl - > origin ) + surf - > plane - > dist > = dl - > radius )
continue ;
}
else
{
if ( DotProduct ( surf - > plane - > normal , dl - > origin ) - surf - > plane - > dist > = dl - > radius )
continue ;
}
//Yeah, you can blame LordHavoc for this alternate code here.
for ( j = 0 ; j < 3 ; j + + )
impact [ j ] = dl - > origin [ j ] - surf - > plane - > normal [ j ] * dot ;
// clamp center of light to corner and check brightness
l = DotProduct ( impact , surf - > texinfo - > vecs [ 0 ] ) + surf - > texinfo - > vecs [ 0 ] [ 3 ] - surf - > texturemins [ 0 ] ;
s = l + 0.5 ; if ( s < 0 ) s = 0 ; else if ( s > surf - > extents [ 0 ] ) s = surf - > extents [ 0 ] ;
s = l - s ;
l = DotProduct ( impact , surf - > texinfo - > vecs [ 1 ] ) + surf - > texinfo - > vecs [ 1 ] [ 3 ] - surf - > texturemins [ 1 ] ;
t = l + 0.5 ; if ( t < 0 ) t = 0 ; else if ( t > surf - > extents [ 1 ] ) t = surf - > extents [ 1 ] ;
t = l - t ;
// compare to minimum light
if ( ( s * s + t * t + dot * dot ) < maxdist )
{
SHM_Shadow_Cache_Surface ( surf ) ;
2013-10-08 14:28:11 +00:00
if ( sh_shmesh - > type = = SMT_SHADOWMAP )
{
SHM_MeshFrontOnly ( surf - > mesh - > numvertexes , surf - > mesh - > xyz_array , surf - > mesh - > numindexes , surf - > mesh - > indexes ) ;
continue ;
}
2013-06-23 02:17:02 +00:00
if ( sh_shmesh - > type ! = SMT_STENCILVOLUME )
2011-12-05 15:23:40 +00:00
continue ;
2009-11-04 21:16:50 +00:00
//build a list of the edges that are to be drawn.
for ( v = 0 ; v < surf - > numedges ; v + + )
{
int e , delta ;
e = cl . worldmodel - > surfedges [ surf - > firstedge + v ] ;
//negative edge means backwards edge.
if ( e < 0 )
{
e = - e ;
delta = - 1 ;
}
else
{
delta = 1 ;
}
if ( ! edge [ e ] . count )
{
if ( firstedge )
edge [ firstedge ] . prev = e ;
edge [ e ] . next = firstedge ;
edge [ e ] . prev = 0 ;
firstedge = e ;
edge [ e ] . count = delta ;
}
else
{
edge [ e ] . count + = delta ;
if ( ! edge [ e ] . count ) //unlink
{
if ( edge [ e ] . next )
{
edge [ edge [ e ] . next ] . prev = edge [ e ] . prev ;
}
if ( edge [ e ] . prev )
edge [ edge [ e ] . prev ] . next = edge [ e ] . next ;
else
firstedge = edge [ e ] . next ;
}
}
}
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
SHM_TriangleFan ( surf - > mesh - > numvertexes , surf - > mesh - > xyz_array , dl - > origin , PROJECTION_DISTANCE ) ;
2009-11-04 21:16:50 +00:00
}
}
}
}
// recurse down the back side
SHM_RecursiveWorldNodeQ1_r ( dl , node - > children [ ! side ] ) ;
}
static void SHM_RecursiveWorldNodeQ2_r ( dlight_t * dl , mnode_t * node )
{
int c , side ;
mplane_t * plane ;
msurface_t * surf , * * mark ;
mleaf_t * pleaf ;
double dot ;
int v ;
float l , maxdist ;
int j , s , t ;
vec3_t impact ;
if ( node - > shadowframe ! = sh_shadowframe )
return ;
if ( node - > contents = = Q2CONTENTS_SOLID )
return ; // solid
//if light areabox is outside node, ignore node + children
for ( c = 0 ; c < 3 ; c + + )
{
if ( dl - > origin [ c ] + dl - > radius < node - > minmaxs [ c ] )
return ;
if ( dl - > origin [ c ] - dl - > radius > node - > minmaxs [ 3 + c ] )
return ;
}
2011-05-15 13:23:13 +00:00
2009-11-04 21:16:50 +00:00
// if a leaf node, draw stuff
if ( node - > contents ! = - 1 )
{
pleaf = ( mleaf_t * ) node ;
2013-12-01 10:54:16 +00:00
if ( pleaf - > cluster > = 0 )
sh_shmesh - > litleaves [ pleaf - > cluster > > 3 ] | = 1 < < ( pleaf - > cluster & 7 ) ;
2009-11-04 21:16:50 +00:00
mark = pleaf - > firstmarksurface ;
c = pleaf - > nummarksurfaces ;
if ( c )
{
do
{
( * mark + + ) - > shadowframe = sh_shadowframe ;
} while ( - - c ) ;
}
return ;
}
// node is just a decision point, so go down the apropriate sides
// find which side of the node we are on
plane = node - > plane ;
switch ( plane - > type )
{
case PLANE_X :
dot = dl - > origin [ 0 ] - plane - > dist ;
break ;
case PLANE_Y :
dot = dl - > origin [ 1 ] - plane - > dist ;
break ;
case PLANE_Z :
dot = dl - > origin [ 2 ] - plane - > dist ;
break ;
default :
dot = DotProduct ( dl - > origin , plane - > normal ) - plane - > dist ;
break ;
}
if ( dot > = 0 )
side = 0 ;
else
side = 1 ;
// recurse down the children, front side first
SHM_RecursiveWorldNodeQ2_r ( dl , node - > children [ side ] ) ;
// draw stuff
c = node - > numsurfaces ;
if ( c )
{
surf = cl . worldmodel - > surfaces + node - > firstsurface ;
{
maxdist = dl - > radius * dl - > radius ;
for ( ; c ; c - - , surf + + )
{
if ( surf - > shadowframe ! = sh_shadowframe )
continue ;
// if ((dot < 0) ^ !!(surf->flags & SURF_PLANEBACK))
// continue; // wrong side
// if (surf->flags & SURF_PLANEBACK)
// continue;
if ( surf - > flags & ( SURF_DRAWALPHA | SURF_DRAWTILED ) )
{ // no shadows
continue ;
}
//is the light on the right side?
if ( surf - > flags & SURF_PLANEBACK )
{ //inverted normal.
if ( - DotProduct ( surf - > plane - > normal , dl - > origin ) + surf - > plane - > dist > = dl - > radius )
continue ;
}
else
{
if ( DotProduct ( surf - > plane - > normal , dl - > origin ) - surf - > plane - > dist > = dl - > radius )
continue ;
}
//Yeah, you can blame LordHavoc for this alternate code here.
for ( j = 0 ; j < 3 ; j + + )
impact [ j ] = dl - > origin [ j ] - surf - > plane - > normal [ j ] * dot ;
// clamp center of light to corner and check brightness
l = DotProduct ( impact , surf - > texinfo - > vecs [ 0 ] ) + surf - > texinfo - > vecs [ 0 ] [ 3 ] - surf - > texturemins [ 0 ] ;
s = l + 0.5 ; if ( s < 0 ) s = 0 ; else if ( s > surf - > extents [ 0 ] ) s = surf - > extents [ 0 ] ;
s = l - s ;
l = DotProduct ( impact , surf - > texinfo - > vecs [ 1 ] ) + surf - > texinfo - > vecs [ 1 ] [ 3 ] - surf - > texturemins [ 1 ] ;
t = l + 0.5 ; if ( t < 0 ) t = 0 ; else if ( t > surf - > extents [ 1 ] ) t = surf - > extents [ 1 ] ;
t = l - t ;
// compare to minimum light
if ( ( s * s + t * t + dot * dot ) < maxdist )
{
SHM_Shadow_Cache_Surface ( surf ) ;
2013-12-01 10:54:16 +00:00
if ( sh_shmesh - > type = = SMT_SHADOWMAP )
{
SHM_MeshFrontOnly ( surf - > mesh - > numvertexes , surf - > mesh - > xyz_array , surf - > mesh - > numindexes , surf - > mesh - > indexes ) ;
continue ;
}
2013-06-23 02:17:02 +00:00
if ( sh_shmesh - > type ! = SMT_STENCILVOLUME )
2011-12-05 15:23:40 +00:00
continue ;
2009-11-04 21:16:50 +00:00
//build a list of the edges that are to be drawn.
for ( v = 0 ; v < surf - > numedges ; v + + )
{
int e , delta ;
e = cl . worldmodel - > surfedges [ surf - > firstedge + v ] ;
//negative edge means backwards edge.
if ( e < 0 )
{
e = - e ;
delta = - 1 ;
}
else
{
delta = 1 ;
}
if ( ! edge [ e ] . count )
{
if ( firstedge )
edge [ firstedge ] . prev = e ;
edge [ e ] . next = firstedge ;
edge [ e ] . prev = 0 ;
firstedge = e ;
edge [ e ] . count = delta ;
}
else
{
edge [ e ] . count + = delta ;
if ( ! edge [ e ] . count ) //unlink
{
if ( edge [ e ] . next )
{
edge [ edge [ e ] . next ] . prev = edge [ e ] . prev ;
}
if ( edge [ e ] . prev )
edge [ edge [ e ] . prev ] . next = edge [ e ] . next ;
else
firstedge = edge [ e ] . next ;
}
}
}
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
SHM_TriangleFan ( surf - > mesh - > numvertexes , surf - > mesh - > xyz_array , dl - > origin , PROJECTION_DISTANCE ) ;
2009-11-04 21:16:50 +00:00
}
}
}
}
// recurse down the back side
SHM_RecursiveWorldNodeQ2_r ( dl , node - > children [ ! side ] ) ;
}
# ifdef Q2BSPS
static void SHM_MarkLeavesQ2 ( dlight_t * dl , unsigned char * lvis , unsigned char * vvis )
{
mnode_t * node ;
int i ;
mleaf_t * leaf ;
int cluster ;
sh_shadowframe + + ;
if ( ! dl - > die )
{
//static
//variation on mark leaves
for ( i = 0 , leaf = cl . worldmodel - > leafs ; i < cl . worldmodel - > numleafs ; i + + , leaf + + )
{
cluster = leaf - > cluster ;
if ( cluster = = - 1 )
continue ;
if ( lvis [ cluster > > 3 ] & ( 1 < < ( cluster & 7 ) ) ) // && vvis[cluster>>3] & (1<<(cluster&7)))
{
node = ( mnode_t * ) leaf ;
do
{
if ( node - > shadowframe = = sh_shadowframe )
break ;
node - > shadowframe = sh_shadowframe ;
node = node - > parent ;
} while ( node ) ;
}
}
}
else
{
//dynamic lights will be discarded after this frame anyway, so only include leafs that are visible
//variation on mark leaves
for ( i = 0 , leaf = cl . worldmodel - > leafs ; i < cl . worldmodel - > numleafs ; i + + , leaf + + )
{
cluster = leaf - > cluster ;
if ( cluster = = - 1 )
continue ;
2013-10-29 17:38:22 +00:00
if ( lvis [ cluster > > 3 ] & /*vvis[cluster>>3] &*/ ( 1 < < ( cluster & 7 ) ) )
2009-11-04 21:16:50 +00:00
{
node = ( mnode_t * ) leaf ;
do
{
if ( node - > shadowframe = = sh_shadowframe )
break ;
node - > shadowframe = sh_shadowframe ;
node = node - > parent ;
} while ( node ) ;
}
}
}
}
# endif
2011-05-20 04:10:46 +00:00
static void SHM_MarkLeavesQ1 ( dlight_t * dl , unsigned char * lvis )
2009-11-04 21:16:50 +00:00
{
mnode_t * node ;
int i ;
sh_shadowframe + + ;
2011-05-20 04:10:46 +00:00
//variation on mark leaves
for ( i = 0 ; i < cl . worldmodel - > numleafs ; i + + )
2009-11-04 21:16:50 +00:00
{
2011-05-20 04:10:46 +00:00
if ( lvis [ i > > 3 ] & ( 1 < < ( i & 7 ) ) )
2009-11-04 21:16:50 +00:00
{
2011-05-20 04:10:46 +00:00
node = ( mnode_t * ) & cl . worldmodel - > leafs [ i + 1 ] ;
do
2009-11-04 21:16:50 +00:00
{
2011-05-20 04:10:46 +00:00
if ( node - > shadowframe = = sh_shadowframe )
break ;
node - > shadowframe = sh_shadowframe ;
node = node - > parent ;
} while ( node ) ;
2009-11-04 21:16:50 +00:00
}
}
}
# ifdef Q3BSPS
2011-07-30 14:14:56 +00:00
static void SHM_RecursiveWorldNodeQ3_r ( dlight_t * dl , mnode_t * node )
2009-11-04 21:16:50 +00:00
{
mplane_t * splitplane ;
float dist ;
msurface_t * * msurf ;
msurface_t * surf ;
mleaf_t * leaf ;
int i ;
if ( node - > contents ! = - 1 )
{
leaf = ( mleaf_t * ) node ;
2013-03-12 23:11:08 +00:00
if ( leaf - > cluster > = 0 )
sh_shmesh - > litleaves [ leaf - > cluster > > 3 ] | = 1 < < ( leaf - > cluster & 7 ) ;
2009-11-04 21:16:50 +00:00
// mark the polygons
msurf = leaf - > firstmarksurface ;
for ( i = 0 ; i < leaf - > nummarksurfaces ; i + + , msurf + + )
{
surf = * msurf ;
//only check each surface once. it can appear in multiple leafs.
if ( surf - > shadowframe = = sh_shadowframe )
continue ;
surf - > shadowframe = sh_shadowframe ;
2013-10-08 14:28:11 +00:00
//FIXME: radius check
2009-11-04 21:16:50 +00:00
SHM_Shadow_Cache_Surface ( surf ) ;
2013-10-08 14:28:11 +00:00
if ( sh_shmesh - > type = = SMT_SHADOWMAP )
SHM_MeshFrontOnly ( surf - > mesh - > numvertexes , surf - > mesh - > xyz_array , surf - > mesh - > numindexes , surf - > mesh - > indexes ) ;
2009-11-04 21:16:50 +00:00
}
return ;
}
splitplane = node - > plane ;
dist = DotProduct ( dl - > origin , splitplane - > normal ) - splitplane - > dist ;
if ( dist > dl - > radius )
{
SHM_RecursiveWorldNodeQ3_r ( dl , node - > children [ 0 ] ) ;
return ;
}
if ( dist < - dl - > radius )
{
SHM_RecursiveWorldNodeQ3_r ( dl , node - > children [ 1 ] ) ;
return ;
}
SHM_RecursiveWorldNodeQ3_r ( dl , node - > children [ 0 ] ) ;
SHM_RecursiveWorldNodeQ3_r ( dl , node - > children [ 1 ] ) ;
}
# endif
2011-12-05 15:23:40 +00:00
static struct {
unsigned int numtris ;
unsigned int maxtris ;
struct {
signed int edge [ 3 ] ;
} * tris ; /*negative for reverse edge*/
unsigned int numedges ;
unsigned int maxedges ;
struct {
unsigned int vert [ 2 ] ;
} * edges ;
unsigned int numpoints ;
unsigned int maxpoints ;
vec3_t * points ;
unsigned int maxedgeuses ;
int * edgeuses ; /*negative for back sides, so 0 means unused or used equally on both sides*/
} cv ;
2012-08-04 01:35:52 +00:00
static void SHM_Shutdown ( void )
{
2012-09-30 05:52:03 +00:00
SH_FreeShadowMesh_ ( & sh_tempshmesh ) ;
------------------------------------------------------------------------
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
BZ_Free ( sh_tempshmesh . litleaves ) ;
sh_tempshmesh . litleaves = NULL ;
sh_tempshmesh . leafbytes = 0 ;
2012-08-04 01:35:52 +00:00
free ( cv . tris ) ;
free ( cv . edges ) ;
free ( cv . points ) ;
memset ( & cv , 0 , sizeof ( cv ) ) ;
}
2011-12-05 15:23:40 +00:00
# define VERT_POS_EPSILON (1.0f / 32)
static int SHM_ComposeVolume_FindVert ( float * vert )
{
int i ;
for ( i = 0 ; i < cv . numpoints ; i + + )
{
# if 1
if ( cv . points [ i ] [ 0 ] = = vert [ 0 ] & &
cv . points [ i ] [ 1 ] = = vert [ 1 ] & &
cv . points [ i ] [ 2 ] = = vert [ 2 ] )
# else
vec3_t d ;
d [ 0 ] = cv . points [ i ] [ 0 ] - vert [ 0 ] ;
d [ 1 ] = cv . points [ i ] [ 1 ] - vert [ 1 ] ;
d [ 2 ] = cv . points [ i ] [ 2 ] - vert [ 2 ] ;
if ( d [ 0 ] * d [ 0 ] < VERT_POS_EPSILON & &
d [ 1 ] * d [ 1 ] < VERT_POS_EPSILON & &
d [ 2 ] * d [ 2 ] < VERT_POS_EPSILON )
# endif
return i ;
}
VectorCopy ( vert , cv . points [ i ] ) ;
cv . numpoints + + ;
return i ;
}
static int SHM_ComposeVolume_FindEdge ( int v1 , int v2 )
{
int i ;
for ( i = 0 ; i < cv . numedges ; i + + )
{
if ( cv . edges [ i ] . vert [ 0 ] = = v1 & & cv . edges [ i ] . vert [ 1 ] = = v2 )
return i ;
if ( cv . edges [ i ] . vert [ 0 ] = = v2 & & cv . edges [ i ] . vert [ 1 ] = = v1 )
return - ( i + 1 ) ;
}
cv . edges [ i ] . vert [ 0 ] = v1 ;
cv . edges [ i ] . vert [ 1 ] = v2 ;
cv . numedges + + ;
return i ;
}
/*each triangle is coplanar, and all face the light, and its a triangle fan. this is a special case that provides a slight speedup*/
static void SHM_ComposeVolume_Fan ( vecV_t * points , int numpoints )
{
int newmax ;
int lastedge ;
int i ;
# define MAX_ARRAY_VERTS 65535
2011-12-23 03:12:29 +00:00
static index_t pointidx [ MAX_ARRAY_VERTS ] ;
2011-12-05 15:23:40 +00:00
/*make sure there's space*/
newmax = ( cv . numpoints + numpoints + inc ) & ~ ( inc - 1 ) ;
if ( cv . maxpoints < newmax )
{
cv . maxpoints = newmax ;
cv . points = BZ_Realloc ( cv . points , newmax * sizeof ( * cv . points ) ) ;
}
newmax = ( cv . numedges + ( numpoints - 2 ) * 3 + inc ) & ~ ( inc - 1 ) ;
if ( cv . maxedges < newmax )
{
cv . maxedges = newmax ;
cv . edges = BZ_Realloc ( cv . edges , newmax * sizeof ( * cv . edges ) ) ;
}
newmax = ( cv . numtris + ( numpoints - 2 ) + inc ) & ~ ( inc - 1 ) ;
if ( cv . maxtris < newmax )
{
cv . maxtris = newmax ;
cv . tris = BZ_Realloc ( cv . tris , newmax * sizeof ( * cv . tris ) ) ;
}
for ( i = 0 ; i < numpoints ; i + + )
{
pointidx [ i ] = SHM_ComposeVolume_FindVert ( points [ i ] ) ;
}
lastedge = SHM_ComposeVolume_FindEdge ( pointidx [ 0 ] , pointidx [ 1 ] ) ;
for ( i = 2 ; i < numpoints ; i + + )
{
cv . tris [ cv . numtris ] . edge [ 0 ] = lastedge ;
cv . tris [ cv . numtris ] . edge [ 1 ] = SHM_ComposeVolume_FindEdge ( pointidx [ i - 1 ] , pointidx [ i ] ) ;
2011-12-23 03:12:29 +00:00
lastedge = SHM_ComposeVolume_FindEdge ( pointidx [ i ] , pointidx [ 0 ] ) ;
2011-12-05 15:23:40 +00:00
cv . tris [ cv . numtris ] . edge [ 2 ] = lastedge ;
lastedge = - ( lastedge + 1 ) ;
cv . numtris + + ;
}
}
2011-12-23 03:12:29 +00:00
static void SHM_ComposeVolume_Soup ( vecV_t * points , int numpoints , index_t * idx , int numidx )
2011-12-05 15:23:40 +00:00
{
int newmax ;
int i ;
# define MAX_ARRAY_VERTS 65535
2011-12-23 03:12:29 +00:00
static index_t pointidx [ MAX_ARRAY_VERTS ] ;
2011-12-05 15:23:40 +00:00
/*make sure there's space*/
newmax = ( cv . numpoints + numpoints + inc ) & ~ ( inc - 1 ) ;
if ( cv . maxpoints < newmax )
{
cv . maxpoints = newmax ;
cv . points = BZ_Realloc ( cv . points , newmax * sizeof ( * cv . points ) ) ;
}
newmax = ( cv . numedges + numidx + inc ) & ~ ( inc - 1 ) ;
if ( cv . maxedges < newmax )
{
cv . maxedges = newmax ;
cv . edges = BZ_Realloc ( cv . edges , newmax * sizeof ( * cv . edges ) ) ;
}
newmax = ( cv . numtris + numidx / 3 + inc ) & ~ ( inc - 1 ) ;
if ( cv . maxtris < newmax )
{
cv . maxtris = newmax ;
cv . tris = BZ_Realloc ( cv . tris , newmax * sizeof ( * cv . tris ) ) ;
}
for ( i = 0 ; i < numpoints ; i + + )
{
pointidx [ i ] = SHM_ComposeVolume_FindVert ( points [ i ] ) ;
}
for ( i = 0 ; i < numidx ; i + = 3 , idx + = 3 )
{
cv . tris [ cv . numtris ] . edge [ 0 ] = SHM_ComposeVolume_FindEdge ( pointidx [ idx [ 0 ] ] , pointidx [ idx [ 1 ] ] ) ;
cv . tris [ cv . numtris ] . edge [ 1 ] = SHM_ComposeVolume_FindEdge ( pointidx [ idx [ 1 ] ] , pointidx [ idx [ 2 ] ] ) ;
cv . tris [ cv . numtris ] . edge [ 2 ] = SHM_ComposeVolume_FindEdge ( pointidx [ idx [ 2 ] ] , pointidx [ idx [ 0 ] ] ) ;
cv . numtris + + ;
}
}
/*call this function after generating litsurfs meshes*/
2010-07-11 10:53:13 +00:00
static void SHM_ComposeVolume_BruteForce ( dlight_t * dl )
2009-11-04 21:16:50 +00:00
{
2012-05-09 15:30:53 +00:00
shadowmeshbatch_t * sms ;
2009-11-04 21:16:50 +00:00
unsigned int tno ;
unsigned int sno ;
2011-12-05 15:23:40 +00:00
int i , e ;
2009-11-04 21:16:50 +00:00
mesh_t * sm ;
2011-12-05 15:23:40 +00:00
vec3_t ext ;
2012-07-05 19:42:36 +00:00
float sc ;
2011-12-05 15:23:40 +00:00
cv . numedges = 0 ;
cv . numpoints = 0 ;
cv . numtris = 0 ;
2012-05-09 15:30:53 +00:00
for ( tno = 0 ; tno < sh_shmesh - > numbatches ; tno + + )
2009-11-04 21:16:50 +00:00
{
2012-05-09 15:30:53 +00:00
sms = & sh_shmesh - > batches [ tno ] ;
2009-11-04 21:16:50 +00:00
if ( ! sms - > count )
continue ;
2012-07-05 19:42:36 +00:00
if ( ( cl . worldmodel - > shadowbatches [ tno ] . tex - > shader - > flags & ( SHADER_BLEND | SHADER_NODRAW ) ) )
2011-12-05 15:23:40 +00:00
continue ;
2009-11-04 21:16:50 +00:00
for ( sno = 0 ; sno < sms - > count ; sno + + )
{
2010-07-11 02:22:39 +00:00
sm = sms - > s [ sno ] ;
2009-11-04 21:16:50 +00:00
if ( sm - > istrifan )
2011-12-05 15:23:40 +00:00
SHM_ComposeVolume_Fan ( sm - > xyz_array , sm - > numvertexes ) ;
else
SHM_ComposeVolume_Soup ( sm - > xyz_array , sm - > numvertexes , sm - > indexes , sm - > numindexes ) ;
}
}
2009-11-04 21:16:50 +00:00
2011-12-05 15:23:40 +00:00
/*FIXME: clip away overlapping triangles*/
2009-11-04 21:16:50 +00:00
2011-12-05 15:23:40 +00:00
if ( cv . maxedgeuses < cv . numedges )
{
BZ_Free ( cv . edgeuses ) ;
cv . maxedgeuses = cv . numedges ;
cv . edgeuses = Z_Malloc ( cv . maxedgeuses * sizeof ( * cv . edgeuses ) ) ;
}
else
memset ( cv . edgeuses , 0 , cv . numedges * sizeof ( * cv . edgeuses ) ) ;
i = ( sh_shmesh - > numverts + cv . numpoints * 6 + inc + 5 ) & ~ ( inc - 1 ) ; //and a bit of padding
if ( sh_shmesh - > maxverts < i )
{
sh_shmesh - > maxverts = i ;
sh_shmesh - > verts = BZ_Realloc ( sh_shmesh - > verts , i * sizeof ( * sh_shmesh - > verts ) ) ;
}
for ( i = 0 ; i < cv . numpoints ; i + + )
{
/*front face*/
sh_shmesh - > verts [ ( i * 2 ) + 0 ] [ 0 ] = cv . points [ i ] [ 0 ] ;
sh_shmesh - > verts [ ( i * 2 ) + 0 ] [ 1 ] = cv . points [ i ] [ 1 ] ;
sh_shmesh - > verts [ ( i * 2 ) + 0 ] [ 2 ] = cv . points [ i ] [ 2 ] ;
/*shadow direction*/
ext [ 0 ] = cv . points [ i ] [ 0 ] - dl - > origin [ 0 ] ;
ext [ 1 ] = cv . points [ i ] [ 1 ] - dl - > origin [ 1 ] ;
ext [ 2 ] = cv . points [ i ] [ 2 ] - dl - > origin [ 2 ] ;
2012-07-05 19:42:36 +00:00
sc = dl - > radius * VectorNormalize ( ext ) ;
2011-12-05 15:23:40 +00:00
/*back face*/
2012-07-05 19:42:36 +00:00
sh_shmesh - > verts [ ( i * 2 ) + 1 ] [ 0 ] = cv . points [ i ] [ 0 ] + ext [ 0 ] * sc ;
sh_shmesh - > verts [ ( i * 2 ) + 1 ] [ 1 ] = cv . points [ i ] [ 1 ] + ext [ 1 ] * sc ;
sh_shmesh - > verts [ ( i * 2 ) + 1 ] [ 2 ] = cv . points [ i ] [ 2 ] + ext [ 2 ] * sc ;
2011-12-05 15:23:40 +00:00
}
sh_shmesh - > numverts = i * 2 ;
i = ( sh_shmesh - > numindicies + cv . numtris * 6 + cv . numedges * 6 + inc + 5 ) & ~ ( inc - 1 ) ; //and a bit of padding
if ( sh_shmesh - > maxindicies < i )
{
sh_shmesh - > maxindicies = i ;
sh_shmesh - > indicies = BZ_Realloc ( sh_shmesh - > indicies , i * sizeof ( * sh_shmesh - > indicies ) ) ;
}
for ( tno = 0 ; tno < cv . numtris ; tno + + )
{
for ( i = 0 ; i < 3 ; i + + )
{
e = cv . tris [ tno ] . edge [ i ] ;
if ( e < 0 )
{
e = - ( e + 1 ) ;
cv . edgeuses [ e ] - - ;
e = cv . edges [ e ] . vert [ 1 ] ;
2009-11-04 21:16:50 +00:00
}
else
{
2011-12-05 15:23:40 +00:00
cv . edgeuses [ e ] + + ;
e = cv . edges [ e ] . vert [ 0 ] ;
2009-11-04 21:16:50 +00:00
}
2011-12-05 15:23:40 +00:00
sh_shmesh - > indicies [ sh_shmesh - > numindicies + i ] = e * 2 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + 5 - i ] = e * 2 + 1 ;
2009-11-04 21:16:50 +00:00
}
2011-12-05 15:23:40 +00:00
sh_shmesh - > numindicies + = 6 ;
2009-11-04 21:16:50 +00:00
}
2011-12-05 15:23:40 +00:00
for ( i = 0 ; i < cv . numedges ; i + + )
{
if ( cv . edgeuses [ i ] > 0 )
{
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 1 ] * 2 + 0 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 0 ] * 2 + 0 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 0 ] * 2 + 1 ;
2009-11-04 21:16:50 +00:00
2011-12-05 15:23:40 +00:00
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 0 ] * 2 + 1 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 1 ] * 2 + 1 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 1 ] * 2 + 0 ;
}
else if ( cv . edgeuses [ i ] < 0 )
{
//generally should not happen...
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 1 ] * 2 + 0 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 0 ] * 2 + 1 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 0 ] * 2 + 0 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 0 ] * 2 + 1 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 1 ] * 2 + 0 ;
sh_shmesh - > indicies [ sh_shmesh - > numindicies + + ] = cv . edges [ i ] . vert [ 1 ] * 2 + 1 ;
}
}
2009-11-04 21:16:50 +00:00
}
2013-06-23 02:17:02 +00:00
static struct shadowmesh_s * SHM_BuildShadowMesh ( dlight_t * dl , unsigned char * lvis , unsigned char * vvis , int type )
2009-11-04 21:16:50 +00:00
{
float * v1 , * v2 ;
vec3_t v3 , v4 ;
2013-06-23 02:17:02 +00:00
if ( dl - > worldshadowmesh & & ! dl - > rebuildcache & & dl - > worldshadowmesh - > type = = type )
2009-11-04 21:16:50 +00:00
return dl - > worldshadowmesh ;
2013-10-29 17:38:22 +00:00
if ( ! lvis )
{
int leaf ;
leaf = cl . worldmodel - > funcs . LeafnumForPoint ( cl . worldmodel , dl - > origin ) ;
lvis = cl . worldmodel - > funcs . LeafPVS ( cl . worldmodel , leaf , lvisb , sizeof ( lvisb ) ) ;
}
2011-12-05 15:23:40 +00:00
firstedge = 0 ;
2012-08-04 01:35:52 +00:00
if ( cl . worldmodel - > type = = mod_brush )
2009-11-04 21:16:50 +00:00
{
2013-10-29 17:38:22 +00:00
switch ( cl . worldmodel - > fromgame )
2011-12-23 03:12:29 +00:00
{
2013-10-29 17:38:22 +00:00
case fg_quake :
case fg_halflife :
/*if (!dl->die)
{
SHM_BeginShadowMesh ( dl , true ) ;
SHM_MarkLeavesQ1 ( dl , lvis ) ;
SHM_RecursiveWorldNodeQ1_r ( dl , cl . worldmodel - > nodes ) ;
if ( ! surfonly )
SHM_ComposeVolume_BruteForce ( dl ) ;
}
else */
{
SHM_BeginShadowMesh ( dl , type ) ;
2013-10-08 14:28:11 +00:00
#if 0
{
2013-10-29 17:38:22 +00:00
int i ;
msurface_t * surf ;
for ( i = 0 ; i < cl . worldmodel - > numsurfaces ; i + = 2 )
{
surf = & cl . worldmodel - > surfaces [ i ] ;
SHM_Shadow_Cache_Surface ( surf ) ;
SHM_MeshFrontOnly ( surf - > mesh - > numvertexes , surf - > mesh - > xyz_array , surf - > mesh - > numindexes , surf - > mesh - > indexes ) ;
}
memset ( sh_shmesh - > litleaves , 0xff , sh_shmesh - > leafbytes ) ;
2013-10-08 14:28:11 +00:00
}
# else
2013-10-29 17:38:22 +00:00
SHM_MarkLeavesQ1 ( dl , lvis ) ;
SHM_RecursiveWorldNodeQ1_r ( dl , cl . worldmodel - > nodes ) ;
2013-10-08 14:28:11 +00:00
# endif
2013-10-29 17:38:22 +00:00
}
break ;
2011-12-05 15:23:40 +00:00
# ifdef Q2BSPS
2013-10-29 17:38:22 +00:00
case fg_quake2 :
SHM_BeginShadowMesh ( dl , type ) ;
SHM_MarkLeavesQ2 ( dl , lvis , vvis ) ;
SHM_RecursiveWorldNodeQ2_r ( dl , cl . worldmodel - > nodes ) ;
break ;
2011-12-05 15:23:40 +00:00
# endif
2009-11-04 21:16:50 +00:00
# ifdef Q3BSPS
2013-10-29 17:38:22 +00:00
case fg_quake3 :
/*q3 doesn't have edge info*/
SHM_BeginShadowMesh ( dl , type ) ;
2013-10-08 14:28:11 +00:00
#if 0
{
2013-10-29 17:38:22 +00:00
int i ;
msurface_t * surf ;
for ( i = 0 ; i < cl . worldmodel - > numsurfaces ; i + + )
{
surf = & cl . worldmodel - > surfaces [ i ] ;
SHM_Shadow_Cache_Surface ( surf ) ;
SHM_MeshFrontOnly ( surf - > mesh - > numvertexes , surf - > mesh - > xyz_array , surf - > mesh - > numindexes , surf - > mesh - > indexes ) ;
}
memset ( sh_shmesh - > litleaves , 0xff , sh_shmesh - > leafbytes ) ;
2013-10-08 14:28:11 +00:00
}
# else
2013-10-29 17:38:22 +00:00
sh_shadowframe + + ;
SHM_RecursiveWorldNodeQ3_r ( dl , cl . worldmodel - > nodes ) ;
if ( type = = SMT_STENCILVOLUME )
SHM_ComposeVolume_BruteForce ( dl ) ;
2013-10-08 14:28:11 +00:00
# endif
2013-10-29 17:38:22 +00:00
break ;
2009-11-04 21:16:50 +00:00
# endif
2013-10-29 17:38:22 +00:00
default :
return NULL ;
}
}
else
{
SHM_BeginShadowMesh ( dl , type ) ;
sh_shadowframe + + ;
2011-12-05 15:23:40 +00:00
}
2009-11-04 21:16:50 +00:00
2011-12-05 15:23:40 +00:00
/*generate edge polys for map types that need it (q1/q2)*/
2013-06-23 02:17:02 +00:00
switch ( type )
2009-11-04 21:16:50 +00:00
{
2013-06-23 02:17:02 +00:00
case SMT_STENCILVOLUME :
2011-07-30 14:14:56 +00:00
SHM_BeginQuads ( ) ;
while ( firstedge )
{
//border
v1 = cl . worldmodel - > vertexes [ cl . worldmodel - > edges [ firstedge ] . v [ 0 ] ] . position ;
v2 = cl . worldmodel - > vertexes [ cl . worldmodel - > edges [ firstedge ] . v [ 1 ] ] . position ;
2009-11-04 21:16:50 +00:00
2011-07-30 14:14:56 +00:00
//get positions of v3 and v4 based on the light position
v3 [ 0 ] = v1 [ 0 ] + ( v1 [ 0 ] - dl - > origin [ 0 ] ) * PROJECTION_DISTANCE ;
v3 [ 1 ] = v1 [ 1 ] + ( v1 [ 1 ] - dl - > origin [ 1 ] ) * PROJECTION_DISTANCE ;
v3 [ 2 ] = v1 [ 2 ] + ( v1 [ 2 ] - dl - > origin [ 2 ] ) * PROJECTION_DISTANCE ;
2009-11-04 21:16:50 +00:00
2011-07-30 14:14:56 +00:00
v4 [ 0 ] = v2 [ 0 ] + ( v2 [ 0 ] - dl - > origin [ 0 ] ) * PROJECTION_DISTANCE ;
v4 [ 1 ] = v2 [ 1 ] + ( v2 [ 1 ] - dl - > origin [ 1 ] ) * PROJECTION_DISTANCE ;
v4 [ 2 ] = v2 [ 2 ] + ( v2 [ 2 ] - dl - > origin [ 2 ] ) * PROJECTION_DISTANCE ;
2009-11-04 21:16:50 +00:00
2011-07-30 14:14:56 +00:00
if ( edge [ firstedge ] . count > 0 )
{
SHM_Vertex3fv ( v3 ) ;
SHM_Vertex3fv ( v4 ) ;
SHM_Vertex3fv ( v2 ) ;
SHM_Vertex3fv ( v1 ) ;
}
else
{
SHM_Vertex3fv ( v1 ) ;
SHM_Vertex3fv ( v2 ) ;
SHM_Vertex3fv ( v4 ) ;
SHM_Vertex3fv ( v3 ) ;
}
edge [ firstedge ] . count = 0 ;
2009-11-04 21:16:50 +00:00
2011-07-30 14:14:56 +00:00
firstedge = edge [ firstedge ] . next ;
}
SHM_End ( ) ;
2013-06-23 02:17:02 +00:00
break ;
2009-11-04 21:16:50 +00:00
}
return SHM_FinishShadowMesh ( dl ) ;
}
2010-07-11 16:23:04 +00:00
static qboolean Sh_VisOverlaps ( qbyte * v1 , qbyte * v2 )
{
int i , m ;
2011-05-20 04:10:46 +00:00
if ( ! v2 )
return false ;
2013-03-12 22:53:23 +00:00
m = ( cl . worldmodel - > numleafs + 7 ) > > 3 ;
for ( i = ( m & ~ 3 ) ; i < m ; i + + )
2010-07-11 16:23:04 +00:00
{
if ( v1 [ i ] & v2 [ i ] )
return true ;
}
2013-03-12 22:53:23 +00:00
m > > = 2 ;
for ( i = 0 ; i < m ; i + + )
{
if ( ( ( unsigned int * ) v1 ) [ i ] & ( ( unsigned int * ) v2 ) [ i ] )
return true ;
}
2010-07-11 16:23:04 +00:00
return false ;
}
2012-11-27 03:23:19 +00:00
# if 1
# define Sh_LeafInView Sh_VisOverlaps
# else
2010-07-11 16:23:04 +00:00
static qboolean Sh_LeafInView ( qbyte * lightvis , qbyte * vvis )
{
int i ;
int m = ( cl . worldmodel - > numleafs ) ;
mleaf_t * wl = cl . worldmodel - > leafs ;
unsigned char lv ;
/*we can potentially walk off the end of the leafs, but lightvis shouldn't be set for those*/
for ( i = 0 ; i < m ; i + = 1 < < 3 )
{
lv = lightvis [ i > > 3 ] ; // & vvis[i>>3];
if ( ! lv )
continue ;
if ( ( lv & 0x01 ) & & wl [ i + 0 ] . visframe = = r_visframecount ) return true ;
if ( ( lv & 0x02 ) & & wl [ i + 1 ] . visframe = = r_visframecount ) return true ;
if ( ( lv & 0x04 ) & & wl [ i + 2 ] . visframe = = r_visframecount ) return true ;
if ( ( lv & 0x08 ) & & wl [ i + 3 ] . visframe = = r_visframecount ) return true ;
if ( ( lv & 0x10 ) & & wl [ i + 4 ] . visframe = = r_visframecount ) return true ;
if ( ( lv & 0x20 ) & & wl [ i + 5 ] . visframe = = r_visframecount ) return true ;
if ( ( lv & 0x40 ) & & wl [ i + 6 ] . visframe = = r_visframecount ) return true ;
if ( ( lv & 0x80 ) & & wl [ i + 7 ] . visframe = = r_visframecount ) return true ;
}
return false ;
}
2012-11-27 03:23:19 +00:00
# endif
2009-11-04 21:16:50 +00:00
2013-06-23 02:17:02 +00:00
/*
static void Sh_Scissor ( srect_t * r )
2009-11-04 21:16:50 +00:00
{
2013-03-12 22:47:42 +00:00
//float xs = vid.pixelwidth / (float)vid.width, ys = vid.pixelheight / (float)vid.height;
2012-01-01 02:26:42 +00:00
switch ( qrenderer )
2011-10-27 16:16:29 +00:00
{
2013-03-12 22:47:42 +00:00
case QR_NONE :
case QR_SOFTWARE :
case QR_DIRECT3D11 :
default :
break ;
2012-01-01 02:26:42 +00:00
case QR_OPENGL :
2013-03-12 22:47:42 +00:00
# ifdef GLQUAKE
------------------------------------------------------------------------
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
qglScissor (
2013-06-23 02:17:02 +00:00
floor ( r_refdef . pxrect . x + r - > x * r_refdef . pxrect . width ) ,
floor ( ( r_refdef . pxrect . y + r - > y * r_refdef . pxrect . height ) - r_refdef . pxrect . height ) ,
ceil ( r - > width * r_refdef . pxrect . width ) ,
ceil ( r - > height * r_refdef . pxrect . height ) ) ;
2012-09-30 05:52:03 +00:00
qglEnable ( GL_SCISSOR_TEST ) ;
2012-01-01 02:26:42 +00:00
if ( qglDepthBoundsEXT )
{
2013-06-23 02:17:02 +00:00
qglDepthBoundsEXT ( r - > dmin , r - > dmax ) ;
2012-01-01 02:26:42 +00:00
qglEnable ( GL_DEPTH_BOUNDS_TEST_EXT ) ;
}
# endif
2013-03-12 22:47:42 +00:00
break ;
2012-09-30 05:52:03 +00:00
case QR_DIRECT3D9 :
2013-03-12 22:47:42 +00:00
# ifdef D3D9QUAKE
2012-01-01 02:26:42 +00:00
{
RECT rect ;
2013-06-23 02:17:02 +00:00
rect . left = r - > x ;
rect . right = r - > x + r - > width ;
rect . top = r - > y ;
rect . bottom = r - > y + r - > height ;
2012-01-01 02:26:42 +00:00
IDirect3DDevice9_SetScissorRect ( pD3DDev9 , & rect ) ;
}
# endif
2013-03-12 22:47:42 +00:00
break ;
2011-10-27 16:16:29 +00:00
}
}
2012-09-30 05:52:03 +00:00
static void Sh_ScissorOff ( void )
{
switch ( qrenderer )
{
2013-03-12 22:47:42 +00:00
default :
break ;
2012-09-30 05:52:03 +00:00
case QR_OPENGL :
2013-03-12 22:47:42 +00:00
# ifdef GLQUAKE
2012-09-30 05:52:03 +00:00
qglDisable ( GL_SCISSOR_TEST ) ;
if ( qglDepthBoundsEXT )
qglDisable ( GL_DEPTH_BOUNDS_TEST_EXT ) ;
# endif
break ;
2013-03-12 22:47:42 +00:00
case QR_DIRECT3D9 :
# ifdef D3D9QUAKE
2012-09-30 05:52:03 +00:00
# endif
2013-03-12 22:47:42 +00:00
break ;
2012-09-30 05:52:03 +00:00
}
}
2013-06-23 02:17:02 +00:00
*/
2011-10-27 16:16:29 +00:00
#if 0
static qboolean Sh_ScissorForSphere ( vec3_t center , float radius , vrect_t * rect )
{
/*return false to say that its fully offscreen*/
float v [ 4 ] , tempv [ 4 ] ;
extern cvar_t temp1 ;
int i ;
vrect_t r ;
radius * = temp1 . value ;
rect - > x = 0 ;
rect - > y = 0 ;
rect - > width = vid . pixelwidth ;
rect - > height = vid . pixelheight ;
/*
for ( i = 0 ; i < 4 ; i + + )
{
v [ 3 ] = 1 ;
VectorMA ( center , radius , frustum [ i ] . normal , v ) ;
tempv [ 0 ] = r_refdef . m_view [ 0 ] * v [ 0 ] + r_refdef . m_view [ 4 ] * v [ 1 ] + r_refdef . m_view [ 8 ] * v [ 2 ] + r_refdef . m_view [ 12 ] * v [ 3 ] ;
tempv [ 1 ] = r_refdef . m_view [ 1 ] * v [ 0 ] + r_refdef . m_view [ 5 ] * v [ 1 ] + r_refdef . m_view [ 9 ] * v [ 2 ] + r_refdef . m_view [ 13 ] * v [ 3 ] ;
tempv [ 2 ] = r_refdef . m_view [ 2 ] * v [ 0 ] + r_refdef . m_view [ 6 ] * v [ 1 ] + r_refdef . m_view [ 10 ] * v [ 2 ] + r_refdef . m_view [ 14 ] * v [ 3 ] ;
tempv [ 3 ] = r_refdef . m_view [ 3 ] * v [ 0 ] + r_refdef . m_view [ 7 ] * v [ 1 ] + r_refdef . m_view [ 11 ] * v [ 2 ] + r_refdef . m_view [ 15 ] * v [ 3 ] ;
product [ 0 ] = r_refdef . m_projection [ 0 ] * tempv [ 0 ] + r_refdef . m_projection [ 4 ] * tempv [ 1 ] + r_refdef . m_projection [ 8 ] * tempv [ 2 ] + r_refdef . m_projection [ 12 ] * tempv [ 3 ] ;
product [ 1 ] = r_refdef . m_projection [ 1 ] * tempv [ 0 ] + r_refdef . m_projection [ 5 ] * tempv [ 1 ] + r_refdef . m_projection [ 9 ] * tempv [ 2 ] + r_refdef . m_projection [ 13 ] * tempv [ 3 ] ;
product [ 2 ] = r_refdef . m_projection [ 2 ] * tempv [ 0 ] + r_refdef . m_projection [ 6 ] * tempv [ 1 ] + r_refdef . m_projection [ 10 ] * tempv [ 2 ] + r_refdef . m_projection [ 14 ] * tempv [ 3 ] ;
product [ 3 ] = r_refdef . m_projection [ 3 ] * tempv [ 0 ] + r_refdef . m_projection [ 7 ] * tempv [ 1 ] + r_refdef . m_projection [ 11 ] * tempv [ 2 ] + r_refdef . m_projection [ 15 ] * tempv [ 3 ] ;
v [ 0 ] / = v [ 3 ] ;
v [ 1 ] / = v [ 3 ] ;
v [ 2 ] / = v [ 3 ] ;
out [ 0 ] = ( 1 + v [ 0 ] ) / 2 ;
out [ 1 ] = ( 1 + v [ 1 ] ) / 2 ;
out [ 2 ] = ( 1 + v [ 2 ] ) / 2 ;
r . x
}
*/
return false ;
2009-11-04 21:16:50 +00:00
}
2011-10-27 16:16:29 +00:00
# endif
2009-11-04 21:16:50 +00:00
# define BoxesOverlap(a,b,c,d) ((a)[0] <= (d)[0] && (b)[0] >= (c)[0] && (a)[1] <= (d)[1] && (b)[1] >= (c)[1] && (a)[2] <= (d)[2] && (b)[2] >= (c)[2])
2011-10-27 16:16:29 +00:00
static qboolean Sh_ScissorForBox ( vec3_t mins , vec3_t maxs , srect_t * r )
{
2013-03-12 22:47:42 +00:00
static const int edge [ 12 ] [ 2 ] =
2011-10-27 16:16:29 +00:00
{
{ 0 , 1 } , { 0 , 2 } , { 1 , 3 } , { 2 , 3 } ,
{ 4 , 5 } , { 4 , 6 } , { 5 , 7 } , { 6 , 7 } ,
{ 0 , 4 } , { 1 , 5 } , { 2 , 6 } , { 3 , 7 }
} ;
//the box is a simple cube.
//clip each vert to the near clip plane
//insert a replacement vertex for edges that cross the nearclip plane where it crosses
//calc the scissor rect from projecting the verts that survived, plus the clipped edge ones.
float ncpdist ;
float dist [ 8 ] ;
int sign [ 8 ] ;
vec4_t vert [ 20 ] ;
vec3_t p [ 8 ] ;
int numverts = 0 , i , v1 , v2 ;
vec4_t v , tv ;
float frac ;
float x , x1 , x2 , y , y1 , y2 ;
double z , z1 , z2 ;
extern cvar_t gl_mindist ;
r - > x = 0 ;
r - > y = 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
r - > width = 1 ;
r - > height = 1 ;
2011-10-27 16:16:29 +00:00
r - > dmin = 0 ;
r - > dmax = 1 ;
2013-10-08 14:28:11 +00:00
if ( ! r_shadow_scissor . ival )
2011-10-27 16:16:29 +00:00
{
2013-10-08 14:28:11 +00:00
r - > x = 0 ;
r - > y = 0 ;
r - > width = 1 ;
r - > height = 1 ;
2011-10-27 16:16:29 +00:00
return false ;
}
/*if view is inside the box, then skip this maths*/
// if (BoxesOverlap(r_refdef.vieworg, r_refdef.vieworg, mins, maxs))
// {
// return false;
// }
ncpdist = DotProduct ( r_refdef . vieworg , vpn ) + gl_mindist . value ;
for ( i = 0 ; i < 8 ; i + + )
{
p [ i ] [ 0 ] = ( i & 1 ) ? mins [ 0 ] : maxs [ 0 ] ;
p [ i ] [ 1 ] = ( i & 2 ) ? mins [ 1 ] : maxs [ 1 ] ;
p [ i ] [ 2 ] = ( i & 4 ) ? mins [ 2 ] : maxs [ 2 ] ;
dist [ i ] = ncpdist - DotProduct ( p [ i ] , vpn ) ;
sign [ i ] = ( dist [ i ] > 0 ) ;
if ( ! sign [ i ] )
{
VectorCopy ( p [ i ] , vert [ numverts ] ) ;
numverts + + ;
}
}
/*fully clipped by near plane*/
if ( ! numverts )
return true ;
if ( numverts ! = 8 )
{
/*crosses near clip plane somewhere*/
for ( i = 0 ; i < 12 ; i + + )
{
v1 = edge [ i ] [ 0 ] ;
v2 = edge [ i ] [ 1 ] ;
if ( sign [ v1 ] ! = sign [ v2 ] )
{
frac = dist [ v1 ] / ( dist [ v1 ] - dist [ v2 ] ) ;
VectorInterpolate ( p [ v1 ] , frac , p [ v2 ] , vert [ numverts ] ) ;
numverts + + ;
}
}
}
x1 = y1 = z1 = 1 ;
x2 = y2 = z2 = - 1 ;
/*transform each vert to get the screen pos*/
for ( i = 0 ; i < numverts ; i + + )
{
vert [ i ] [ 3 ] = 1 ;
Matrix4x4_CM_Transform4 ( r_refdef . m_view , vert [ i ] , tv ) ;
Matrix4x4_CM_Transform4 ( r_refdef . m_projection , tv , v ) ;
x = v [ 0 ] / v [ 3 ] ;
y = v [ 1 ] / v [ 3 ] ;
z = ( double ) v [ 2 ] / v [ 3 ] ;
if ( x < x1 ) x1 = x ;
if ( x > x2 ) x2 = x ;
if ( y < y1 ) y1 = y ;
if ( y > y2 ) y2 = y ;
if ( z < z1 ) z1 = z ;
if ( z > z2 ) z2 = z ;
}
------------------------------------------------------------------------
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
x1 = ( 1 + x1 ) / 2 ;
x2 = ( 1 + x2 ) / 2 ;
y1 = ( 1 + y1 ) / 2 ;
y2 = ( 1 + y2 ) / 2 ;
2011-10-27 16:16:29 +00:00
z1 = ( 1 + z1 ) / 2 ;
z2 = ( 1 + z2 ) / 2 ;
if ( x1 < 0 )
x1 = 0 ;
if ( y1 < 0 )
y1 = 0 ;
if ( x2 < 0 )
x2 = 0 ;
2011-12-05 15:23:40 +00:00
if ( y2 < 0 )
y2 = 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
if ( x1 > 1 )
x1 = 1 ;
if ( y1 > 1 )
y1 = 1 ;
if ( x2 > 1 )
x2 = 1 ;
if ( y2 > 1 )
y2 = 1 ;
r - > x = x1 ;
r - > y = y1 ;
r - > width = x2 - r - > x ;
r - > height = y2 - r - > y ;
if ( r - > width = = 0 | | r - > height = = 0 )
return true ; //meh
2011-10-27 16:16:29 +00:00
r - > dmin = z1 ;
r - > dmax = z2 ;
return false ;
}
#if 0
static qboolean Sh_ScissorForBox ( vec3_t mins , vec3_t maxs , vrect_t * r )
2009-11-04 21:16:50 +00:00
{
int i , ix1 , iy1 , ix2 , iy2 ;
float x1 , y1 , x2 , y2 , x , y , f ;
vec3_t smins , smaxs ;
vec4_t v , v2 ;
2011-10-27 16:16:29 +00:00
r - > x = 0 ;
r - > y = 0 ;
r - > width = vid . pixelwidth ;
r - > height = vid . pixelheight ;
2009-11-04 21:16:50 +00:00
if ( 0 ) //!r_shadow_scissor.integer)
{
return false ;
}
2011-10-27 16:16:29 +00:00
// if view is inside the box, just say yes it's fully visible
2009-11-04 21:16:50 +00:00
if ( BoxesOverlap ( r_refdef . vieworg , r_refdef . vieworg , mins , maxs ) )
{
return false ;
}
for ( i = 0 ; i < 3 ; i + + )
{
if ( vpn [ i ] > = 0 )
{
v [ i ] = mins [ i ] ;
v2 [ i ] = maxs [ i ] ;
}
else
{
v [ i ] = maxs [ i ] ;
v2 [ i ] = mins [ i ] ;
}
}
2011-10-27 16:16:29 +00:00
f = DotProduct ( vpn , r_refdef . vieworg ) ;
2009-11-04 21:16:50 +00:00
if ( DotProduct ( vpn , v2 ) < = f )
{
2011-10-27 16:16:29 +00:00
// entirely behind nearclip plane, entirely obscured
2009-11-04 21:16:50 +00:00
return true ;
}
if ( DotProduct ( vpn , v ) > = f )
{
// entirely infront of nearclip plane
x1 = y1 = x2 = y2 = 0 ;
for ( i = 0 ; i < 8 ; i + + )
{
v [ 0 ] = ( i & 1 ) ? mins [ 0 ] : maxs [ 0 ] ;
v [ 1 ] = ( i & 2 ) ? mins [ 1 ] : maxs [ 1 ] ;
v [ 2 ] = ( i & 4 ) ? mins [ 2 ] : maxs [ 2 ] ;
v [ 3 ] = 1.0f ;
2011-07-30 14:14:56 +00:00
Matrix4x4_CM_Project ( v , v2 , r_refdef . viewangles , r_refdef . vieworg , r_refdef . fov_x , r_refdef . fov_y ) ;
2011-10-27 16:16:29 +00:00
v2 [ 0 ] * = vid . pixelwidth ;
v2 [ 1 ] * = vid . pixelheight ;
2009-11-04 21:16:50 +00:00
// GL_TransformToScreen(v, v2);
//Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
x = v2 [ 0 ] ;
y = v2 [ 1 ] ;
if ( i )
{
if ( x1 > x ) x1 = x ;
if ( x2 < x ) x2 = x ;
if ( y1 > y ) y1 = y ;
if ( y2 < y ) y2 = y ;
}
else
{
x1 = x2 = x ;
y1 = y2 = y ;
}
}
}
else
{
// clipped by nearclip plane
// this is nasty and crude...
// create viewspace bbox
2011-01-29 21:01:40 +00:00
i = 0 ;
/*unrolled the first iteration to avoid warnings*/
v [ 0 ] = ( ( i & 1 ) ? mins [ 0 ] : maxs [ 0 ] ) - r_refdef . vieworg [ 0 ] ;
v [ 1 ] = ( ( i & 2 ) ? mins [ 1 ] : maxs [ 1 ] ) - r_refdef . vieworg [ 1 ] ;
v [ 2 ] = ( ( i & 4 ) ? mins [ 2 ] : maxs [ 2 ] ) - r_refdef . vieworg [ 2 ] ;
v2 [ 0 ] = DotProduct ( v , vright ) ;
v2 [ 1 ] = DotProduct ( v , vup ) ;
v2 [ 2 ] = DotProduct ( v , vpn ) ;
smins [ 0 ] = smaxs [ 0 ] = v2 [ 0 ] ;
smins [ 1 ] = smaxs [ 1 ] = v2 [ 1 ] ;
smins [ 2 ] = smaxs [ 2 ] = v2 [ 2 ] ;
for ( i = 1 ; i < 8 ; i + + )
2009-11-04 21:16:50 +00:00
{
v [ 0 ] = ( ( i & 1 ) ? mins [ 0 ] : maxs [ 0 ] ) - r_refdef . vieworg [ 0 ] ;
v [ 1 ] = ( ( i & 2 ) ? mins [ 1 ] : maxs [ 1 ] ) - r_refdef . vieworg [ 1 ] ;
v [ 2 ] = ( ( i & 4 ) ? mins [ 2 ] : maxs [ 2 ] ) - r_refdef . vieworg [ 2 ] ;
v2 [ 0 ] = DotProduct ( v , vright ) ;
v2 [ 1 ] = DotProduct ( v , vup ) ;
v2 [ 2 ] = DotProduct ( v , vpn ) ;
2011-01-29 21:01:40 +00:00
if ( smins [ 0 ] > v2 [ 0 ] ) smins [ 0 ] = v2 [ 0 ] ;
if ( smaxs [ 0 ] < v2 [ 0 ] ) smaxs [ 0 ] = v2 [ 0 ] ;
if ( smins [ 1 ] > v2 [ 1 ] ) smins [ 1 ] = v2 [ 1 ] ;
if ( smaxs [ 1 ] < v2 [ 1 ] ) smaxs [ 1 ] = v2 [ 1 ] ;
if ( smins [ 2 ] > v2 [ 2 ] ) smins [ 2 ] = v2 [ 2 ] ;
if ( smaxs [ 2 ] < v2 [ 2 ] ) smaxs [ 2 ] = v2 [ 2 ] ;
2009-11-04 21:16:50 +00:00
}
// now we have a bbox in viewspace
// clip it to the view plane
if ( smins [ 2 ] < 1 )
smins [ 2 ] = 1 ;
// return true if that culled the box
if ( smins [ 2 ] > = smaxs [ 2 ] )
return true ;
// ok some of it is infront of the view, transform each corner back to
// worldspace and then to screenspace and make screen rect
// initialize these variables just to avoid compiler warnings
x1 = y1 = x2 = y2 = 0 ;
for ( i = 0 ; i < 8 ; i + + )
{
v2 [ 0 ] = ( i & 1 ) ? smins [ 0 ] : smaxs [ 0 ] ;
v2 [ 1 ] = ( i & 2 ) ? smins [ 1 ] : smaxs [ 1 ] ;
v2 [ 2 ] = ( i & 4 ) ? smins [ 2 ] : smaxs [ 2 ] ;
v [ 0 ] = v2 [ 0 ] * vright [ 0 ] + v2 [ 1 ] * vup [ 0 ] + v2 [ 2 ] * vpn [ 0 ] + r_refdef . vieworg [ 0 ] ;
v [ 1 ] = v2 [ 0 ] * vright [ 1 ] + v2 [ 1 ] * vup [ 1 ] + v2 [ 2 ] * vpn [ 1 ] + r_refdef . vieworg [ 1 ] ;
v [ 2 ] = v2 [ 0 ] * vright [ 2 ] + v2 [ 1 ] * vup [ 2 ] + v2 [ 2 ] * vpn [ 2 ] + r_refdef . vieworg [ 2 ] ;
v [ 3 ] = 1.0f ;
2011-07-30 14:14:56 +00:00
Matrix4x4_CM_Project ( v , v2 , r_refdef . viewangles , r_refdef . vieworg , r_refdef . fov_x , r_refdef . fov_y ) ;
2011-10-27 16:16:29 +00:00
v2 [ 0 ] * = vid . pixelwidth ;
v2 [ 1 ] * = vid . pixelheight ;
2009-11-04 21:16:50 +00:00
//Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
x = v2 [ 0 ] ;
y = v2 [ 1 ] ;
if ( i )
{
if ( x1 > x ) x1 = x ;
if ( x2 < x ) x2 = x ;
if ( y1 > y ) y1 = y ;
if ( y2 < y ) y2 = y ;
}
else
{
x1 = x2 = x ;
y1 = y2 = y ;
}
}
2011-02-25 04:22:14 +00:00
# if 1
2009-11-04 21:16:50 +00:00
// this code doesn't handle boxes with any points behind view properly
x1 = 1000 ; x2 = - 1000 ;
y1 = 1000 ; y2 = - 1000 ;
for ( i = 0 ; i < 8 ; i + + )
{
v [ 0 ] = ( i & 1 ) ? mins [ 0 ] : maxs [ 0 ] ;
v [ 1 ] = ( i & 2 ) ? mins [ 1 ] : maxs [ 1 ] ;
v [ 2 ] = ( i & 4 ) ? mins [ 2 ] : maxs [ 2 ] ;
v [ 3 ] = 1.0f ;
2011-07-30 14:14:56 +00:00
Matrix4x4_CM_Project ( v , v2 , r_refdef . viewangles , r_refdef . vieworg , r_refdef . fov_x , r_refdef . fov_y ) ;
2011-10-27 16:16:29 +00:00
v2 [ 0 ] * = vid . pixelwidth ;
v2 [ 1 ] * = vid . pixelheight ;
2009-11-04 21:16:50 +00:00
//Con_Printf("%.3f %.3f %.3f %.3f transformed to %.3f %.3f %.3f %.3f\n", v[0], v[1], v[2], v[3], v2[0], v2[1], v2[2], v2[3]);
if ( v2 [ 2 ] > 0 )
{
x = v2 [ 0 ] ;
y = v2 [ 1 ] ;
if ( x1 > x ) x1 = x ;
if ( x2 < x ) x2 = x ;
if ( y1 > y ) y1 = y ;
if ( y2 < y ) y2 = y ;
}
}
# endif
}
ix1 = x1 - 1.0f ;
iy1 = y1 - 1.0f ;
ix2 = x2 + 1.0f ;
iy2 = y2 + 1.0f ;
//Con_Printf("%f %f %f %f\n", x1, y1, x2, y2);
2011-10-27 16:16:29 +00:00
if ( ix1 < r - > x ) ix1 = r - > x ;
if ( iy1 < r - > y ) iy1 = r - > y ;
if ( ix2 > r - > x + r - > width ) ix2 = r - > x + r - > width ;
if ( iy2 > r - > y + r - > height ) iy2 = r - > y + r - > height ;
2009-11-04 21:16:50 +00:00
if ( ix2 < = ix1 | | iy2 < = iy1 )
return true ;
// set up the scissor rectangle
2011-10-27 16:16:29 +00:00
r - > x = ix1 ;
r - > y = iy1 ;
r - > width = ix2 - ix1 ;
r - > height = iy2 - iy1 ;
2009-11-04 21:16:50 +00:00
return false ;
}
2011-10-27 16:16:29 +00:00
# endif
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
# ifdef GLQUAKE
2012-08-04 01:35:52 +00:00
# ifdef DBG_COLOURNOTDEPTH
void GL_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);
qglDrawBuffer ( GL_COLOR_ATTACHMENT0_EXT ) ;
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
2009-11-04 21:16:50 +00:00
void GL_BeginRenderBuffer_DepthOnly ( texid_t depthtexture )
{
2010-07-11 02:22:39 +00:00
if ( gl_config . ext_framebuffer_objects )
2009-11-04 21:16:50 +00:00
{
2010-07-11 02:22:39 +00:00
if ( ! shadow_fbo_id )
2009-11-04 21:16:50 +00:00
{
2011-09-03 03:49:43 +00:00
qglGenFramebuffersEXT ( 1 , & shadow_fbo_id ) ;
2010-07-11 02:22:39 +00:00
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shadow_fbo_id ) ;
2009-11-04 21:16:50 +00:00
qglDrawBuffer ( GL_NONE ) ;
qglReadBuffer ( GL_NONE ) ;
}
else
2010-07-11 02:22:39 +00:00
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , shadow_fbo_id ) ;
2009-11-04 21:16:50 +00:00
2013-10-08 14:28:11 +00:00
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 ) ;
}
2009-11-04 21:16:50 +00:00
}
}
2012-08-04 01:35:52 +00:00
# endif
2013-10-29 17:38:22 +00:00
void GL_EndRenderBuffer_DepthOnly ( int restorefbo , texid_t depthtexture , int texsize )
2009-11-04 21:16:50 +00:00
{
2010-07-11 02:22:39 +00:00
if ( gl_config . ext_framebuffer_objects )
2009-11-04 21:16:50 +00:00
{
2013-10-29 17:38:22 +00:00
qglBindFramebufferEXT ( GL_FRAMEBUFFER_EXT , restorefbo ) ;
2009-11-04 21:16:50 +00:00
}
else
{
2011-02-25 04:22:14 +00:00
GL_MTBind ( 0 , GL_TEXTURE_2D , depthtexture ) ;
2009-11-04 21:16:50 +00:00
qglCopyTexSubImage2D ( GL_TEXTURE_2D , 0 , 0 , 0 , 0 , 0 , texsize , texsize ) ;
}
}
2013-11-21 23:02:28 +00:00
# endif
void D3D11BE_BeginShadowmapFace ( void ) ;
2009-11-04 21:16:50 +00:00
2013-10-08 14:28:11 +00:00
//determine the 5 bounding points of a shadowmap light projection side
2013-10-29 17:38:22 +00:00
//needs to match Sh_GenShadowFace
2013-10-08 14:28:11 +00:00
static void Sh_LightFrustumPlanes ( dlight_t * l , vec4_t * planes , int face )
{
vec3_t tmp ;
int axis0 , axis1 , axis2 ;
int dir ;
int i ;
//+x,+y,+z,-x,-y,-z
axis0 = ( face + 0 ) % 3 ; //our major axis
axis1 = ( face + 1 ) % 3 ;
axis2 = ( face + 2 ) % 3 ;
dir = ( face > = 3 ) ? - 1 : 1 ;
//center point is always the same
VectorCopy ( l - > origin , planes [ 4 ] ) ;
VectorScale ( l - > axis [ axis0 ] , dir , planes [ 4 ] ) ;
VectorNormalize ( planes [ 4 ] ) ;
planes [ 4 ] [ 3 ] = r_shadow_shadowmapping_nearclip . value + DotProduct ( planes [ 4 ] , l - > origin ) ;
for ( i = 0 ; i < 4 ; i + + )
{
VectorScale ( l - > axis [ axis0 ] , dir , tmp ) ;
VectorMA ( tmp , ( ( i & 1 ) ? 1 : - 1 ) , l - > axis [ axis1 ] , tmp ) ;
VectorMA ( tmp , ( ( i & 2 ) ? 1 : - 1 ) , l - > axis [ axis2 ] , planes [ i ] ) ;
VectorNormalize ( planes [ i ] ) ;
planes [ i ] [ 3 ] = DotProduct ( planes [ i ] , l - > origin ) ;
}
}
2013-10-29 17:38:22 +00:00
//culling for the face happens in the caller.
//these faces should thus match Sh_LightFrustumPlanes
2013-03-12 23:13:39 +00:00
static void Sh_GenShadowFace ( dlight_t * l , shadowmesh_t * smesh , int face , int smsize , float proj [ 16 ] )
2009-11-04 21:16:50 +00:00
{
2013-10-29 17:38:22 +00:00
vec3_t t1 , t2 , t3 ;
2012-08-04 01:35:52 +00:00
texture_t * tex ;
int tno ;
2009-11-04 21:16:50 +00:00
2013-11-21 23:02:28 +00:00
/* if (face >= 3)
face - = 3 ;
else
face + = 3 ;
*/
2010-07-11 02:22:39 +00:00
switch ( face )
{
case 0 :
2013-10-29 17:38:22 +00:00
//down
VectorCopy ( l - > axis [ 0 ] , t1 ) ;
VectorCopy ( l - > axis [ 1 ] , t2 ) ;
VectorCopy ( l - > axis [ 2 ] , t3 ) ;
Matrix4x4_CM_LightMatrixFromAxis ( r_refdef . m_view , t1 , t2 , t3 , l - > origin ) ;
2013-10-08 14:28:11 +00:00
r_refdef . flipcull = 0 ;
2010-07-11 02:22:39 +00:00
break ;
case 1 :
2013-10-29 17:38:22 +00:00
//back
VectorCopy ( l - > axis [ 2 ] , t1 ) ;
VectorCopy ( l - > axis [ 1 ] , t2 ) ;
VectorCopy ( l - > axis [ 0 ] , t3 ) ;
Matrix4x4_CM_LightMatrixFromAxis ( r_refdef . m_view , t1 , t2 , t3 , l - > origin ) ;
2013-10-08 14:28:11 +00:00
r_refdef . flipcull = SHADER_CULL_FLIP ;
2010-07-11 02:22:39 +00:00
break ;
case 2 :
2013-10-29 17:38:22 +00:00
//right
VectorCopy ( l - > axis [ 0 ] , t1 ) ;
VectorCopy ( l - > axis [ 2 ] , t2 ) ;
VectorCopy ( l - > axis [ 1 ] , t3 ) ;
Matrix4x4_CM_LightMatrixFromAxis ( r_refdef . m_view , t1 , t2 , t3 , l - > origin ) ;
2013-10-08 14:28:11 +00:00
r_refdef . flipcull = SHADER_CULL_FLIP ;
2010-07-11 02:22:39 +00:00
break ;
case 3 :
2013-10-29 17:38:22 +00:00
//up
VectorCopy ( l - > axis [ 0 ] , t1 ) ;
VectorCopy ( l - > axis [ 1 ] , t2 ) ;
VectorCopy ( l - > axis [ 2 ] , t3 ) ;
VectorNegate ( t3 , t3 ) ;
Matrix4x4_CM_LightMatrixFromAxis ( r_refdef . m_view , t1 , t2 , t3 , l - > origin ) ;
2013-10-08 14:28:11 +00:00
r_refdef . flipcull = SHADER_CULL_FLIP ;
2010-07-11 02:22:39 +00:00
break ;
case 4 :
2013-10-29 17:38:22 +00:00
//forward
VectorCopy ( l - > axis [ 2 ] , t1 ) ;
VectorCopy ( l - > axis [ 1 ] , t2 ) ;
VectorCopy ( l - > axis [ 0 ] , t3 ) ;
VectorNegate ( t3 , t3 ) ;
Matrix4x4_CM_LightMatrixFromAxis ( r_refdef . m_view , t1 , t2 , t3 , l - > origin ) ;
2013-10-08 14:28:11 +00:00
r_refdef . flipcull = 0 ;
2010-07-11 02:22:39 +00:00
break ;
case 5 :
2013-10-29 17:38:22 +00:00
//left
VectorCopy ( l - > axis [ 0 ] , t1 ) ;
VectorCopy ( l - > axis [ 2 ] , t2 ) ;
VectorCopy ( l - > axis [ 1 ] , t3 ) ;
VectorNegate ( t3 , t3 ) ;
Matrix4x4_CM_LightMatrixFromAxis ( r_refdef . m_view , t1 , t2 , t3 , l - > origin ) ;
2013-10-08 14:28:11 +00:00
r_refdef . flipcull = 0 ;
2010-07-11 02:22:39 +00:00
break ;
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
if ( l - > fov )
2013-10-29 17:38:22 +00:00
{
2013-11-21 23:02:28 +00:00
r_refdef . pxrect . x = ( SHADOWMAP_SIZE - smsize ) / 2 ;
2013-10-29 17:38:22 +00:00
r_refdef . pxrect . width = smsize ;
r_refdef . pxrect . height = smsize ;
2013-11-21 23:02:28 +00:00
r_refdef . pxrect . y = ( SHADOWMAP_SIZE - smsize ) / 2 ;
r_refdef . pxrect . maxheight = SHADOWMAP_SIZE ;
2013-10-29 17:38:22 +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
else
{
2013-10-29 17:38:22 +00:00
r_refdef . pxrect . x = ( face % 3 * SHADOWMAP_SIZE ) + ( SHADOWMAP_SIZE - smsize ) / 2 ;
r_refdef . pxrect . width = smsize ;
r_refdef . pxrect . height = smsize ;
2013-11-21 23:02:28 +00:00
r_refdef . pxrect . y = ( ( ( face < 3 ) * SHADOWMAP_SIZE ) + ( SHADOWMAP_SIZE - smsize ) / 2 ) ;
r_refdef . pxrect . maxheight = SHADOWMAP_SIZE * 2 ;
------------------------------------------------------------------------
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
}
2012-08-04 01:35:52 +00:00
R_SetFrustum ( proj , r_refdef . m_view ) ;
2009-11-04 21:16:50 +00:00
2012-08-04 01:35:52 +00:00
# ifdef DBG_COLOURNOTDEPTH
BE_SelectMode ( BEM_STANDARD ) ;
# else
BE_SelectMode ( BEM_DEPTHONLY ) ;
# endif
2009-11-04 21:16:50 +00:00
2012-08-04 01:35:52 +00:00
BE_SelectEntity ( & r_worldentity ) ;
2010-07-11 02:22:39 +00:00
2013-10-08 14:28:11 +00:00
2013-11-21 23:02:28 +00:00
switch ( qrenderer )
2013-10-08 14:28:11 +00:00
{
2013-11-21 23:02:28 +00:00
# ifdef GLQUAKE
case QR_OPENGL :
GL_ViewportUpdate ( ) ;
GL_CullFace ( SHADER_CULL_FRONT ) ;
2013-10-08 14:28:11 +00:00
GLBE_RenderShadowBuffer ( smesh - > numverts , smesh - > vebo [ 0 ] , smesh - > verts , smesh - > numindicies , smesh - > vebo [ 1 ] , smesh - > indicies ) ;
2013-11-21 23:02:28 +00:00
break ;
2013-06-23 02:17:02 +00:00
# endif
2013-11-21 23:02:28 +00:00
# ifdef D3D11QUAKE
case QR_DIRECT3D11 :
//d3d render targets are upside down
r_refdef . pxrect . y = r_refdef . pxrect . maxheight - ( r_refdef . pxrect . y + r_refdef . pxrect . height ) ;
D3D11BE_BeginShadowmapFace ( ) ;
D3D11BE_RenderShadowBuffer ( smesh - > numverts , smesh - > d3d11_vbuffer , smesh - > numindicies , smesh - > d3d11_ibuffer ) ;
break ;
# endif
default :
2013-06-23 02:17:02 +00:00
//FIXME: should be able to merge batches between textures+lightmaps.
for ( tno = 0 ; tno < smesh - > numbatches ; tno + + )
{
if ( ! smesh - > batches [ tno ] . count )
continue ;
tex = cl . worldmodel - > shadowbatches [ tno ] . tex ;
2013-12-02 14:30:30 +00:00
if ( tex - > shader - > flags & SHADER_NODLIGHT ) //FIXME: shadows not lights
2013-06-23 02:17:02 +00:00
continue ;
BE_DrawMesh_List ( tex - > shader , smesh - > batches [ tno ] . count , smesh - > batches [ tno ] . s , cl . worldmodel - > shadowbatches [ tno ] . vbo , & tex - > shader - > defaulttextures , 0 ) ;
}
2013-11-21 23:02:28 +00:00
break ;
2009-11-04 21:16:50 +00:00
}
2012-08-04 01:35:52 +00:00
2013-06-23 02:17:02 +00:00
//fixme: this walks through the entity lists up to 6 times per frame.
2012-01-01 11:22:24 +00:00
switch ( qrenderer )
{
2013-03-12 22:47:42 +00:00
default :
break ;
# ifdef GLQUAKE
2013-11-21 23:02:28 +00:00
case QR_OPENGL :
2012-01-01 11:22:24 +00:00
GLBE_BaseEntTextures ( ) ;
2013-03-12 22:47:42 +00:00
break ;
2013-11-21 23:02:28 +00:00
# endif
2013-03-12 22:47:42 +00:00
# ifdef D3D9QUAKE
2013-11-21 23:02:28 +00:00
case QR_DIRECT3D9 :
2012-09-30 05:52:03 +00:00
D3D9BE_BaseEntTextures ( ) ;
2013-11-21 23:02:28 +00:00
break ;
2012-01-01 11:22:24 +00:00
# endif
2013-11-21 23:02:28 +00:00
# ifdef D3D11QUAKE
case QR_DIRECT3D11 :
D3D11BE_BaseEntTextures ( ) ;
2013-03-12 22:47:42 +00:00
break ;
2013-11-21 23:02:28 +00:00
# endif
2012-01-01 11:22:24 +00:00
}
2012-08-04 01:35:52 +00:00
/*
2009-11-04 21:16:50 +00:00
{
int i ;
2010-07-11 02:22:39 +00:00
static float depth [ SHADOWMAP_SIZE * SHADOWMAP_SIZE ] ;
2009-11-04 21:16:50 +00:00
qglReadPixels ( 0 , 0 , smsize , smsize ,
GL_DEPTH_COMPONENT , GL_FLOAT , depth ) ;
2010-07-11 02:22:39 +00:00
for ( i = SHADOWMAP_SIZE * SHADOWMAP_SIZE ; i - - > 0 ; )
2009-11-04 21:16:50 +00:00
{
if ( depth [ i ] = = 1 )
* ( ( unsigned int * ) depth + i ) = 0 ;
else
* ( ( unsigned int * ) depth + i ) = 0xff000000 | ( ( ( ( unsigned char ) ( int ) ( depth [ i ] * 128 ) ) ) * 0x10101 ) ;
}
2012-08-04 01:35:52 +00:00
2009-11-04 21:16:50 +00:00
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA ,
smsize , smsize , 0 ,
GL_RGBA , GL_UNSIGNED_BYTE , depth ) ;
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 ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP ) ;
}
2012-08-04 01:35:52 +00:00
*/
2009-11-04 21:16:50 +00:00
}
2013-11-21 23:02:28 +00:00
void D3D11_BeginShadowMap ( int id , int w , int h ) ;
void D3D11_EndShadowMap ( void ) ;
void D3D11BE_SetupForShadowMap ( dlight_t * dl , qboolean isspot , int texwidth , int texheight , float shadowscale ) ;
2013-10-08 14:28:11 +00:00
qboolean Sh_GenShadowMap ( dlight_t * l , qbyte * lvis , int smsize )
2009-11-04 21:16:50 +00:00
{
2013-11-21 23:02:28 +00:00
int restorefbo = 0 ;
2009-11-04 21:16:50 +00:00
int f ;
2012-08-04 01:35:52 +00:00
float oproj [ 16 ] , oview [ 16 ] ;
2013-11-21 23:02:28 +00:00
pxrect_t oprect ;
2009-11-04 21:16:50 +00:00
shadowmesh_t * smesh ;
2012-08-04 01:35:52 +00:00
int isspot = ( l - > fov ! = 0 ) ;
2013-10-08 14:28:11 +00:00
extern cvar_t r_shadow_shadowmapping_precision ;
int sidevisible ;
int oldflip = r_refdef . flipcull ;
int oldexternalview = r_refdef . externalview ;
if ( ! R_CullSphere ( l - > origin , 0 ) )
sidevisible = l - > fov ? 1 : 0x3f ; //assume all are visible if the central point is onscreen
else
{
sidevisible = 0 ;
//FIXME: if the fov is < 90, we need to clip by the near lightplane first
for ( f = 0 ; f < ( l - > fov ? 1 : 6 ) ; f + + )
{
vec4_t planes [ 5 ] ;
float dist ;
int fp , lp ;
Sh_LightFrustumPlanes ( l , planes , f ) ;
2013-10-29 17:38:22 +00:00
for ( fp = 0 ; fp < r_refdef . frustum_numplanes ; fp + + )
2013-10-08 14:28:11 +00:00
{
vec3_t nearest ;
//make a guess based upon the frustum plane
2013-10-29 17:38:22 +00:00
VectorMA ( l - > origin , l - > radius , r_refdef . frustum [ fp ] . normal , nearest ) ;
2013-10-08 14:28:11 +00:00
//clip that point to the various planes
for ( lp = 0 ; lp < 5 ; lp + + )
{
dist = DotProduct ( nearest , planes [ lp ] ) - planes [ lp ] [ 3 ] ;
if ( dist < 0 )
VectorMA ( nearest , dist , planes [ lp ] , nearest ) ;
}
// P_RunParticleEffect(nearest, vec3_origin, 15, 1);
//give up if the best point for any frustum plane is offscreen
2013-10-29 17:38:22 +00:00
dist = DotProduct ( r_refdef . frustum [ fp ] . normal , nearest ) - r_refdef . frustum [ fp ] . dist ;
2013-10-08 14:28:11 +00:00
if ( dist < = 0 )
break ;
}
2013-10-29 17:38:22 +00:00
if ( fp = = r_refdef . frustum_numplanes )
2013-10-08 14:28:11 +00:00
sidevisible | = 1u < < f ;
}
}
//if nothing is visible, then there's no point generating any shadowmaps at all...
if ( ! sidevisible )
return false ;
2009-11-04 21:16:50 +00:00
2013-11-21 23:02:28 +00:00
memcpy ( oproj , r_refdef . m_projection , sizeof ( oproj ) ) ;
memcpy ( oview , r_refdef . m_view , sizeof ( oview ) ) ;
oprect = r_refdef . pxrect ;
smesh = SHM_BuildShadowMesh ( l , lvis , NULL , SMT_SHADOWMAP ) ;
Matrix4x4_CM_Projection_Far ( r_refdef . m_projection , l - > fov ? l - > fov : 90 , l - > fov ? l - > fov : 90 , r_shadow_shadowmapping_nearclip . value , l - > radius ) ;
switch ( qrenderer )
2010-07-11 02:22:39 +00:00
{
2013-11-21 23:02:28 +00:00
# ifdef GLQUAKE
case QR_OPENGL :
if ( ! TEXVALID ( shadowmap [ isspot ] ) )
2012-08-04 01:35:52 +00:00
{
2013-11-21 23:02:28 +00:00
if ( isspot )
{
shadowmap [ isspot ] = GL_AllocNewTexture ( " ***shadowmap2dspot*** " , SHADOWMAP_SIZE , SHADOWMAP_SIZE , 0 ) ;
GL_MTBind ( 0 , GL_TEXTURE_2D , shadowmap [ isspot ] ) ;
# ifdef DBG_COLOURNOTDEPTH
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , SHADOWMAP_SIZE , SHADOWMAP_SIZE , 0 , GL_RGBA , GL_UNSIGNED_BYTE , NULL ) ;
# else
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_DEPTH_COMPONENT16_ARB , SHADOWMAP_SIZE , SHADOWMAP_SIZE , 0 , GL_DEPTH_COMPONENT , GL_UNSIGNED_BYTE , NULL ) ;
# endif
}
else
{
shadowmap [ isspot ] = GL_AllocNewTexture ( " ***shadowmap2dcube*** " , SHADOWMAP_SIZE * 3 , SHADOWMAP_SIZE * 2 , 0 ) ;
GL_MTBind ( 0 , GL_TEXTURE_2D , shadowmap [ isspot ] ) ;
# ifdef DBG_COLOURNOTDEPTH
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , SHADOWMAP_SIZE * 3 , SHADOWMAP_SIZE * 2 , 0 , GL_RGBA , GL_UNSIGNED_BYTE , NULL ) ;
# else
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_DEPTH_COMPONENT16_ARB , SHADOWMAP_SIZE * 3 , SHADOWMAP_SIZE * 2 , 0 , GL_DEPTH_COMPONENT , GL_UNSIGNED_BYTE , NULL ) ;
# endif
}
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
# if 1 //def DBG_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
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 ) ;
}
/*set framebuffer*/
GL_BeginRenderBuffer_DepthOnly ( shadowmap [ isspot ] ) ;
restorefbo = GLBE_SetupForShadowMap ( shadowmap [ isspot ] , isspot ? smsize : smsize * 3 , isspot ? smsize : smsize * 2 , ( smsize - 4 ) / ( float ) SHADOWMAP_SIZE ) ;
BE_Scissor ( NULL ) ;
qglViewport ( 0 , 0 , smsize * 3 , smsize * 2 ) ;
qglClear ( GL_DEPTH_BUFFER_BIT ) ;
2012-08-04 01:35:52 +00:00
# ifdef DBG_COLOURNOTDEPTH
2013-11-21 23:02:28 +00:00
qglClearColor ( 0 , 1 , 0 , 1 ) ;
qglClear ( GL_COLOR_BUFFER_BIT ) ;
2012-08-04 01:35:52 +00:00
# endif
2013-11-21 23:02:28 +00:00
if ( ! gl_config . nofixedfunc )
2012-08-04 01:35:52 +00:00
{
2013-11-21 23:02:28 +00:00
qglMatrixMode ( GL_PROJECTION ) ;
qglLoadMatrixf ( r_refdef . m_projection ) ;
qglMatrixMode ( GL_MODELVIEW ) ;
2012-08-04 01:35:52 +00:00
}
2013-11-21 23:02:28 +00:00
break ;
2012-08-04 01:35:52 +00:00
# endif
2013-11-21 23:02:28 +00:00
# ifdef D3D11QUAKE
case QR_DIRECT3D11 :
D3D11_BeginShadowMap ( isspot , ( isspot ? SHADOWMAP_SIZE : ( SHADOWMAP_SIZE * 3 ) ) , ( isspot ? SHADOWMAP_SIZE : ( SHADOWMAP_SIZE * 2 ) ) ) ;
2012-08-04 01:35:52 +00:00
2013-11-21 23:02:28 +00:00
// BE_Scissor(&rect);
break ;
2012-08-04 01:35:52 +00:00
# endif
2013-10-08 14:28:11 +00:00
}
r_refdef . externalview = true ; //never any viewmodels
2010-07-11 02:22:39 +00:00
2013-10-08 14:28:11 +00:00
/*generate faces*/
for ( f = 0 ; f < 6 ; f + + )
{
if ( sidevisible & ( 1u < < f ) )
2009-11-04 21:16:50 +00:00
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_SHADOWSIDES , 1 ) ;
2013-03-12 23:13:39 +00:00
Sh_GenShadowFace ( l , smesh , f , smsize , r_refdef . m_projection ) ;
2009-11-04 21:16:50 +00:00
}
}
2013-10-08 14:28:11 +00:00
2012-08-04 01:35:52 +00:00
memcpy ( r_refdef . m_view , oview , sizeof ( r_refdef . m_view ) ) ;
memcpy ( r_refdef . m_projection , oproj , sizeof ( r_refdef . m_projection ) ) ;
2010-07-11 02:22:39 +00:00
2013-11-21 23:02:28 +00:00
r_refdef . pxrect = oprect ;
2010-07-11 16:23:04 +00:00
2013-10-08 14:28:11 +00:00
r_refdef . flipcull = oldflip ;
r_refdef . externalview = oldexternalview ;
2010-07-11 16:23:04 +00:00
R_SetFrustum ( r_refdef . m_projection , r_refdef . m_view ) ;
2013-10-08 14:28:11 +00:00
2013-11-21 23:02:28 +00:00
switch ( qrenderer )
{
# ifdef GLQUAKE
case QR_OPENGL :
/*end framebuffer*/
GL_EndRenderBuffer_DepthOnly ( restorefbo , shadowmap [ isspot ] , smsize ) ;
if ( ! gl_config . nofixedfunc )
{
qglMatrixMode ( GL_PROJECTION ) ;
qglLoadMatrixf ( r_refdef . m_projection ) ;
qglMatrixMode ( GL_MODELVIEW ) ;
qglLoadMatrixf ( r_refdef . m_view ) ;
}
GL_ViewportUpdate ( ) ;
break ;
# endif
# ifdef D3D11QUAKE
case QR_DIRECT3D11 :
D3D11_EndShadowMap ( ) ;
D3D11BE_DoneShadows ( ) ;
break ;
# endif
}
2013-10-08 14:28:11 +00:00
return true ;
2009-11-04 21:16:50 +00:00
}
2010-07-11 16:23:04 +00:00
static void Sh_DrawShadowMapLight ( dlight_t * l , vec3_t colour , qbyte * vvis )
2009-11-04 21:16:50 +00:00
{
2010-07-11 02:22:39 +00:00
vec3_t mins , maxs ;
2010-07-11 16:23:04 +00:00
qbyte * lvis ;
2011-10-27 16:16:29 +00:00
srect_t rect ;
2013-10-08 14:28:11 +00:00
int smsize ;
2013-11-21 23:02:28 +00:00
qboolean isspot ;
2010-07-11 02:22:39 +00:00
if ( R_CullSphere ( l - > origin , l - > radius ) )
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_FRUSTUM , 1 ) ;
2010-07-11 02:22:39 +00:00
return ; //this should be the more common case
}
2009-11-04 21:16:50 +00:00
2010-07-11 02:22:39 +00:00
mins [ 0 ] = l - > origin [ 0 ] - l - > radius ;
mins [ 1 ] = l - > origin [ 1 ] - l - > radius ;
mins [ 2 ] = l - > origin [ 2 ] - l - > radius ;
maxs [ 0 ] = l - > origin [ 0 ] + l - > radius ;
maxs [ 1 ] = l - > origin [ 1 ] + l - > radius ;
maxs [ 2 ] = l - > origin [ 2 ] + l - > radius ;
2011-10-27 16:16:29 +00:00
if ( Sh_ScissorForBox ( mins , maxs , & rect ) )
2010-07-11 02:22:39 +00:00
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_SCISSOR , 1 ) ;
2010-07-11 02:22:39 +00:00
return ;
}
2012-08-04 01:35:52 +00:00
if ( vvis )
2010-07-11 16:23:04 +00:00
{
2013-03-12 23:13:39 +00:00
if ( ! l - > rebuildcache & & l - > worldshadowmesh )
2010-07-11 16:23:04 +00:00
{
2012-08-04 01:35:52 +00:00
lvis = l - > worldshadowmesh - > litleaves ;
//fixme: check head node first?
if ( ! Sh_LeafInView ( l - > worldshadowmesh - > litleaves , vvis ) )
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_PVS , 1 ) ;
return ;
2012-08-04 01:35:52 +00:00
}
}
else
{
int leaf ;
leaf = cl . worldmodel - > funcs . LeafnumForPoint ( cl . worldmodel , l - > origin ) ;
lvis = cl . worldmodel - > funcs . LeafPVS ( cl . worldmodel , leaf , lvisb , sizeof ( lvisb ) ) ;
if ( ! Sh_VisOverlaps ( lvis , vvis ) ) //The two viewing areas do not intersect.
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_PVS , 1 ) ;
2012-08-04 01:35:52 +00:00
return ;
}
2010-07-11 16:23:04 +00:00
}
}
2012-09-30 05:52:03 +00:00
else
lvis = NULL ;
2010-07-11 16:23:04 +00:00
2010-07-11 02:22:39 +00:00
2013-11-21 23:02:28 +00:00
isspot = l - > fov ! = 0 ;
if ( isspot )
2013-10-08 14:28:11 +00:00
smsize = SHADOWMAP_SIZE ;
else
{
//Stolen from DP. Actually, LH pasted it to me in IRC.
vec3_t nearestpoint ;
vec3_t d ;
float distance , lodlinear ;
nearestpoint [ 0 ] = bound ( l - > origin [ 0 ] - l - > radius , r_origin [ 0 ] , l - > origin [ 0 ] + l - > radius ) ;
nearestpoint [ 1 ] = bound ( l - > origin [ 1 ] - l - > radius , r_origin [ 1 ] , l - > origin [ 1 ] + l - > radius ) ;
nearestpoint [ 2 ] = bound ( l - > origin [ 2 ] - l - > radius , r_origin [ 2 ] , l - > origin [ 2 ] + l - > radius ) ;
VectorSubtract ( nearestpoint , r_origin , d ) ;
distance = VectorLength ( d ) ;
lodlinear = ( l - > radius * r_shadow_shadowmapping_precision . value ) / sqrt ( max ( 1.0f , distance / l - > radius ) ) ;
smsize = bound ( 16 , lodlinear , SHADOWMAP_SIZE ) ;
}
2013-11-21 23:02:28 +00:00
# ifdef D3D11QUAKE
if ( qrenderer = = QR_DIRECT3D11 )
D3D11BE_SetupForShadowMap ( l , isspot , isspot ? smsize : smsize * 3 , isspot ? smsize : smsize * 2 , ( smsize - 4 ) / ( float ) SHADOWMAP_SIZE ) ;
# endif
if ( ! BE_SelectDLight ( l , colour , isspot ? LSHADER_SPOT : LSHADER_SMAP ) )
return ;
2013-10-08 14:28:11 +00:00
if ( ! Sh_GenShadowMap ( l , lvis , smsize ) )
return ;
2009-11-04 21:16:50 +00:00
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_DRAWN , 1 ) ;
2009-11-04 21:16:50 +00:00
2012-08-04 01:35:52 +00:00
//may as well use scissors
2013-06-23 02:17:02 +00:00
BE_Scissor ( & rect ) ;
2009-11-04 21:16:50 +00:00
2012-08-04 01:35:52 +00:00
BE_SelectEntity ( & r_worldentity ) ;
2013-10-08 14:28:11 +00:00
BE_SelectMode ( BEM_LIGHT ) ;
2009-11-04 21:16:50 +00:00
Sh_DrawEntLighting ( l , colour ) ;
}
/*
draws faces facing the light
Note : Backend mode must have been selected in advance , as must the light to light from
*/
static void Sh_DrawEntLighting ( dlight_t * light , vec3_t colour )
{
2010-07-11 02:22:39 +00:00
int tno ;
2009-11-04 21:16:50 +00:00
texture_t * tex ;
2013-12-02 14:30:30 +00:00
shader_t * shader ;
2009-11-04 21:16:50 +00:00
shadowmesh_t * sm ;
sm = light - > worldshadowmesh ;
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
if ( light - > rebuildcache )
sm = & sh_tempshmesh ;
2009-11-04 21:16:50 +00:00
if ( sm )
{
2012-05-09 15:30:53 +00:00
for ( tno = 0 ; tno < sm - > numbatches ; tno + + )
2009-11-04 21:16:50 +00:00
{
2012-05-09 15:30:53 +00:00
if ( ! sm - > batches [ tno ] . count )
2009-11-04 21:16:50 +00:00
continue ;
2012-05-09 15:30:53 +00:00
tex = cl . worldmodel - > shadowbatches [ tno ] . tex ;
2013-12-02 14:30:30 +00:00
shader = R_TextureAnimation ( false , tex ) - > shader ;
if ( shader - > flags & SHADER_NODLIGHT )
2011-04-20 03:31:41 +00:00
continue ;
2013-10-08 14:28:11 +00:00
//FIXME: it may be worth building a dedicated ebo
2013-12-02 14:30:30 +00:00
BE_DrawMesh_List ( shader , sm - > batches [ tno ] . count , sm - > batches [ tno ] . s , cl . worldmodel - > shadowbatches [ tno ] . vbo , & shader - > defaulttextures , 0 ) ;
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_LITFACES , sm - > batches [ tno ] . count ) ;
2009-11-04 21:16:50 +00:00
}
2012-01-01 11:22:24 +00:00
switch ( qrenderer )
{
2013-03-12 22:47:42 +00:00
default :
break ;
# ifdef GLQUAKE
2013-11-21 23:02:28 +00:00
case QR_OPENGL :
2012-01-01 11:22:24 +00:00
GLBE_BaseEntTextures ( ) ;
2013-03-12 22:47:42 +00:00
break ;
2013-11-21 23:02:28 +00:00
# endif
2013-03-12 22:47:42 +00:00
# ifdef D3D9QUAKE
2013-11-21 23:02:28 +00:00
case QR_DIRECT3D9 :
2012-09-30 05:52:03 +00:00
D3D9BE_BaseEntTextures ( ) ;
2013-11-21 23:02:28 +00:00
break ;
2012-01-01 11:22:24 +00:00
# endif
2013-11-21 23:02:28 +00:00
# ifdef D3D11QUAKE
case QR_DIRECT3D11 :
D3D11BE_BaseEntTextures ( ) ;
2013-03-12 22:47:42 +00:00
break ;
2013-11-21 23:02:28 +00:00
# endif
2012-01-01 11:22:24 +00:00
}
2009-11-04 21:16:50 +00:00
}
}
/*Fixme: this is brute forced*/
2011-10-27 16:16:29 +00:00
# ifdef warningmsg
# pragma warningmsg("brush shadows are bruteforced")
2011-05-29 04:26:29 +00:00
# endif
2009-11-04 21:16:50 +00:00
static void Sh_DrawBrushModelShadow ( dlight_t * dl , entity_t * e )
{
2012-01-01 02:26:42 +00:00
# ifdef GLQUAKE
2009-11-04 21:16:50 +00:00
int v ;
float * v1 , * v2 ;
vec3_t v3 , v4 ;
vec3_t lightorg ;
int i ;
model_t * model ;
msurface_t * surf ;
if ( BE_LightCullModel ( e - > origin , e - > model ) )
return ;
2011-05-19 13:34:07 +00:00
RotateLightVector ( ( void * ) e - > axis , e - > origin , dl - > origin , lightorg ) ;
2009-11-04 21:16:50 +00:00
2010-08-28 17:14:38 +00:00
BE_SelectEntity ( e ) ;
2009-11-04 21:16:50 +00:00
2012-11-27 03:23:19 +00:00
GL_DeselectVAO ( ) ;
2009-11-04 21:16:50 +00:00
GL_SelectVBO ( 0 ) ;
GL_SelectEBO ( 0 ) ;
qglEnableClientState ( GL_VERTEX_ARRAY ) ;
2012-09-30 05:52:03 +00:00
GLBE_PushOffsetShadow ( true ) ;
2010-07-11 02:22:39 +00:00
2009-11-04 21:16:50 +00:00
model = e - > model ;
surf = model - > surfaces + model - > firstmodelsurface ;
for ( i = 0 ; i < model - > nummodelsurfaces ; i + + , surf + + )
{
if ( surf - > flags & SURF_PLANEBACK )
{ //inverted normal.
if ( DotProduct ( surf - > plane - > normal , lightorg ) - surf - > plane - > dist > = - 0.1 )
continue ;
}
else
{
if ( DotProduct ( surf - > plane - > normal , lightorg ) - surf - > plane - > dist < = 0.1 )
continue ;
}
if ( surf - > flags & ( SURF_DRAWALPHA | SURF_DRAWTILED ) )
{ // no shadows
continue ;
}
2009-11-17 00:15:44 +00:00
if ( ! surf - > mesh )
continue ;
2009-11-04 21:16:50 +00:00
//front face
qglVertexPointer ( 3 , GL_FLOAT , sizeof ( vecV_t ) , surf - > mesh - > xyz_array ) ;
qglDrawArrays ( GL_POLYGON , 0 , surf - > mesh - > numvertexes ) ;
// qglDrawRangeElements(GL_TRIANGLES, 0, surf->mesh->numvertexes, surf->mesh->numindexes, GL_INDEX_TYPE, surf->mesh->indexes);
2011-04-30 17:21:10 +00:00
RQuantAdd ( RQUANT_SHADOWFACES , surf - > mesh - > numvertexes ) ;
2009-11-04 21:16:50 +00:00
for ( v = 0 ; v < surf - > mesh - > numvertexes ; v + + )
{
//border
v1 = surf - > mesh - > xyz_array [ v ] ;
v2 = surf - > mesh - > xyz_array [ ( v + 1 ) % surf - > mesh - > numvertexes ] ;
//get positions of v3 and v4 based on the light position
2011-12-23 03:12:29 +00:00
v3 [ 0 ] = ( v1 [ 0 ] - lightorg [ 0 ] ) ;
v3 [ 1 ] = ( v1 [ 1 ] - lightorg [ 1 ] ) ;
v3 [ 2 ] = ( v1 [ 2 ] - lightorg [ 2 ] ) ;
VectorNormalizeFast ( v3 ) ;
VectorScale ( v3 , PROJECTION_DISTANCE , v3 ) ;
v4 [ 0 ] = ( v2 [ 0 ] - lightorg [ 0 ] ) ;
v4 [ 1 ] = ( v2 [ 1 ] - lightorg [ 1 ] ) ;
v4 [ 2 ] = ( v2 [ 2 ] - lightorg [ 2 ] ) ;
VectorNormalizeFast ( v4 ) ;
VectorScale ( v4 , PROJECTION_DISTANCE , v4 ) ;
2009-11-04 21:16:50 +00:00
//Now draw the quad from the two verts to the projected light
//verts
qglBegin ( GL_QUAD_STRIP ) ;
qglVertex3fv ( v1 ) ;
qglVertex3f ( v1 [ 0 ] + v3 [ 0 ] , v1 [ 1 ] + v3 [ 1 ] , v1 [ 2 ] + v3 [ 2 ] ) ;
qglVertex3fv ( v2 ) ;
qglVertex3f ( v2 [ 0 ] + v4 [ 0 ] , v2 [ 1 ] + v4 [ 1 ] , v2 [ 2 ] + v4 [ 2 ] ) ;
qglEnd ( ) ;
}
2011-05-15 13:23:13 +00:00
2009-11-04 21:16:50 +00:00
//back
//the same applies as earlier
qglBegin ( GL_POLYGON ) ;
for ( v = surf - > mesh - > numvertexes - 1 ; v > = 0 ; v - - )
{
v1 = surf - > mesh - > xyz_array [ v ] ;
2011-12-23 03:12:29 +00:00
v3 [ 0 ] = ( v1 [ 0 ] - lightorg [ 0 ] ) ;
v3 [ 1 ] = ( v1 [ 1 ] - lightorg [ 1 ] ) ;
v3 [ 2 ] = ( v1 [ 2 ] - lightorg [ 2 ] ) ;
VectorNormalizeFast ( v3 ) ;
VectorScale ( v3 , PROJECTION_DISTANCE , v3 ) ;
2009-11-04 21:16:50 +00:00
qglVertex3f ( v1 [ 0 ] + v3 [ 0 ] , v1 [ 1 ] + v3 [ 1 ] , v1 [ 2 ] + v3 [ 2 ] ) ;
}
qglEnd ( ) ;
}
2010-07-11 02:22:39 +00:00
2012-09-30 05:52:03 +00:00
GLBE_PushOffsetShadow ( false ) ;
2012-01-01 02:26:42 +00:00
# endif
2009-11-04 21:16:50 +00:00
}
/*when this is called, the gl state has been set up to draw the stencil volumes using whatever extensions we have
if secondside is set , then the gpu sucks and we ' re drawing stuff the slow 2 - pass way , and this is the second pass .
*/
static void Sh_DrawStencilLightShadows ( dlight_t * dl , qbyte * lvis , qbyte * vvis , qboolean secondside )
{
extern cvar_t gl_part_flame ;
int i ;
struct shadowmesh_s * sm ;
2010-08-28 17:14:38 +00:00
entity_t * ent ;
2009-11-04 21:16:50 +00:00
2013-10-29 17:38:22 +00:00
sm = SHM_BuildShadowMesh ( dl , lvis , vvis , SMT_STENCILVOLUME ) ;
2009-11-04 21:16:50 +00:00
if ( ! sm )
Sh_DrawBrushModelShadow ( dl , & r_worldentity ) ;
else
{
2012-01-01 02:26:42 +00:00
switch ( qrenderer )
{
2013-03-12 22:47:42 +00:00
case QR_NONE :
case QR_SOFTWARE :
default :
break ;
2013-11-21 23:02:28 +00:00
# ifdef D3D11QUAKE
case QR_DIRECT3D11 :
D3D11BE_RenderShadowBuffer ( sm - > numverts , sm - > d3d11_vbuffer , sm - > numindicies , sm - > d3d11_ibuffer ) ;
break ;
2012-01-01 02:26:42 +00:00
# endif
2013-11-21 23:02:28 +00:00
# ifdef D3D9QUAKE
case QR_DIRECT3D9 :
D3D9BE_RenderShadowBuffer ( sm - > numverts , sm - > d3d9_vbuffer , sm - > numindicies , sm - > d3d9_ibuffer ) ;
2013-03-12 22:47:42 +00:00
break ;
2013-11-21 23:02:28 +00:00
# endif
2013-03-12 22:47:42 +00:00
# ifdef GLQUAKE
2013-11-21 23:02:28 +00:00
case QR_OPENGL :
2012-01-01 02:26:42 +00:00
GLBE_RenderShadowBuffer ( sm - > numverts , sm - > vebo [ 0 ] , sm - > verts , sm - > numindicies , sm - > vebo [ 1 ] , sm - > indicies ) ;
2013-03-12 22:47:42 +00:00
break ;
2013-11-21 23:02:28 +00:00
# endif
2012-01-01 02:26:42 +00:00
}
2009-11-04 21:16:50 +00:00
}
if ( ! r_drawentities . value )
return ;
2013-11-21 23:02:28 +00:00
if ( qrenderer = = QR_DIRECT3D11 )
return ;
2012-04-24 07:59:11 +00:00
# ifdef GLQUAKE
if ( gl_config . nofixedfunc )
return ; /*hackzone*/
# endif
2009-11-04 21:16:50 +00:00
// draw sprites seperately, because of alpha blending
for ( i = 0 ; i < cl_numvisedicts ; i + + )
{
2010-08-28 17:14:38 +00:00
ent = & cl_visedicts [ i ] ;
2009-11-04 21:16:50 +00:00
2010-08-28 17:14:38 +00:00
if ( ent - > flags & ( RF_NOSHADOW | Q2RF_BEAM ) )
2009-11-04 21:16:50 +00:00
continue ;
2013-10-08 14:28:11 +00:00
if ( ent - > keynum = = dl - > key & & ent - > keynum )
continue ;
2010-08-28 17:14:38 +00:00
if ( ! ent - > model )
2009-11-04 21:16:50 +00:00
continue ;
2012-07-20 01:46:05 +00:00
if ( cls . allow_anyparticles ) //allowed or static
2009-11-04 21:16:50 +00:00
{
2010-08-28 17:14:38 +00:00
if ( ent - > model - > engineflags & MDLF_ENGULPHS )
2009-11-04 21:16:50 +00:00
{
if ( gl_part_flame . value )
continue ;
}
}
2010-08-28 17:14:38 +00:00
switch ( ent - > model - > type )
2009-11-04 21:16:50 +00:00
{
case mod_alias :
2010-08-28 17:14:38 +00:00
R_DrawGAliasShadowVolume ( ent , dl - > origin , dl - > radius ) ;
2009-11-04 21:16:50 +00:00
break ;
case mod_brush :
2010-08-28 17:14:38 +00:00
Sh_DrawBrushModelShadow ( dl , ent ) ;
2009-11-04 21:16:50 +00:00
break ;
default :
break ;
}
}
2010-08-28 17:14:38 +00:00
BE_SelectEntity ( & r_worldentity ) ;
2009-11-04 21:16:50 +00:00
}
//draws a light using stencil shadows.
//redraws world geometry up to 3 times per light...
static qboolean Sh_DrawStencilLight ( dlight_t * dl , vec3_t colour , qbyte * vvis )
{
2011-12-05 15:23:40 +00:00
int sref ;
2009-11-04 21:16:50 +00:00
int leaf ;
qbyte * lvis ;
2011-10-27 16:16:29 +00:00
srect_t rect ;
2009-11-04 21:16:50 +00:00
vec3_t mins ;
vec3_t maxs ;
if ( R_CullSphere ( dl - > origin , dl - > radius ) )
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_FRUSTUM , 1 ) ;
2009-11-04 21:16:50 +00:00
return false ; //this should be the more common case
}
mins [ 0 ] = dl - > origin [ 0 ] - dl - > radius ;
mins [ 1 ] = dl - > origin [ 1 ] - dl - > radius ;
mins [ 2 ] = dl - > origin [ 2 ] - dl - > radius ;
maxs [ 0 ] = dl - > origin [ 0 ] + dl - > radius ;
maxs [ 1 ] = dl - > origin [ 1 ] + dl - > radius ;
maxs [ 2 ] = dl - > origin [ 2 ] + dl - > radius ;
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
if ( ! dl - > rebuildcache )
2009-11-04 21:16:50 +00:00
{
//fixme: check head node first?
if ( ! Sh_LeafInView ( dl - > worldshadowmesh - > litleaves , vvis ) )
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_PVS , 1 ) ;
2009-11-04 21:16:50 +00:00
return false ;
}
lvis = NULL ;
}
else
{
leaf = cl . worldmodel - > funcs . LeafnumForPoint ( cl . worldmodel , dl - > origin ) ;
lvis = cl . worldmodel - > funcs . LeafPVS ( cl . worldmodel , leaf , lvisb , sizeof ( lvisb ) ) ;
if ( ! Sh_VisOverlaps ( lvis , vvis ) ) //The two viewing areas do not intersect.
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_PVS , 1 ) ;
2009-11-04 21:16:50 +00:00
return false ;
}
}
//sets up the gl scissor (and culls to view)
2011-10-27 16:16:29 +00:00
if ( Sh_ScissorForBox ( mins , maxs , & rect ) )
2009-11-04 21:16:50 +00:00
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_SCISSOR , 1 ) ;
2009-11-04 21:16:50 +00:00
return false ; //this doesn't cull often.
}
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_DRAWN , 1 ) ;
2009-11-04 21:16:50 +00:00
2013-10-08 14:28:11 +00:00
BE_SelectDLight ( dl , colour , LSHADER_STANDARD ) ;
2011-04-20 23:34:13 +00:00
BE_SelectMode ( BEM_STENCIL ) ;
2009-11-04 21:16:50 +00:00
//The backend doesn't maintain scissor state.
//The backend doesn't maintain stencil test state either - it needs to be active for more than just stencils, or disabled. its awkward.
2013-06-23 02:17:02 +00:00
BE_Scissor ( & rect ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
switch ( qrenderer )
2009-11-04 21:16:50 +00:00
{
2013-03-12 22:47:42 +00:00
default :
break ;
2012-01-01 02:26:42 +00:00
# ifdef GLQUAKE
case QR_OPENGL :
{
int sfrontfail ;
int sbackfail ;
qglEnable ( GL_STENCIL_TEST ) ;
//FIXME: is it practical to test to see if scissors allow not clearing the stencil buffer?
/*we don't need all that much stencil buffer depth, and if we don't get enough or have dodgy volumes, wrap if we can*/
# ifdef I_LIVE_IN_A_FREE_COUNTRY
sref = 0 ;
sbackfail = GL_INCR ;
sfrontfail = GL_DECR ;
if ( gl_config . ext_stencil_wrap )
{ //minimise damage...
sbackfail = GL_INCR_WRAP_EXT ;
2013-03-12 23:09:25 +00:00
sfrontfail = GL_DECR_WRAP_EXT ;
2012-01-01 02:26:42 +00:00
}
# else
sref = ( 1 < < gl_stencilbits ) - 1 ; /*this is halved for two-sided stencil support, just in case there's no wrap support*/
sbackfail = GL_DECR ;
sfrontfail = GL_INCR ;
if ( gl_config . ext_stencil_wrap )
{ //minimise damage...
sbackfail = GL_DECR_WRAP_EXT ;
sfrontfail = GL_INCR_WRAP_EXT ;
}
# endif
//our stencil writes.
if ( gl_config . arb_depth_clamp )
qglEnable ( GL_DEPTH_CLAMP_ARB ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
#if 0 //def _DEBUG
// if (r_shadows.value == 666) //testing (visible shadow volumes)
{
qglColorMask ( GL_TRUE , GL_TRUE , GL_TRUE , GL_TRUE ) ;
qglColor3f ( dl - > color [ 0 ] , dl - > color [ 1 ] , dl - > color [ 2 ] ) ;
qglDisable ( GL_STENCIL_TEST ) ;
2013-03-12 23:09:25 +00:00
// qglEnable(GL_POLYGON_OFFSET_FILL);
// qglPolygonOffset(-1, -1);
2012-01-01 02:26:42 +00:00
// qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
Sh_DrawStencilLightShadows ( dl , lvis , vvis , false ) ;
2013-03-12 23:09:25 +00:00
// qglDisable(GL_POLYGON_OFFSET_FILL);
// qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2012-01-01 02:26:42 +00:00
}
# endif
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
if ( qglStencilOpSeparateATI )
{
2013-03-12 23:09:25 +00:00
//ATI/GLES/ARB method
2012-01-01 02:26:42 +00:00
sref / = 2 ;
qglClearStencil ( sref ) ;
qglClear ( GL_STENCIL_BUFFER_BIT ) ;
GL_CullFace ( 0 ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
qglStencilFunc ( GL_ALWAYS , 0 , ~ 0 ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
qglStencilOpSeparateATI ( GL_BACK , GL_KEEP , sbackfail , GL_KEEP ) ;
qglStencilOpSeparateATI ( GL_FRONT , GL_KEEP , sfrontfail , GL_KEEP ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
Sh_DrawStencilLightShadows ( dl , lvis , vvis , false ) ;
qglStencilOpSeparateATI ( GL_FRONT_AND_BACK , GL_KEEP , GL_KEEP , GL_KEEP ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
GL_CullFace ( SHADER_CULL_FRONT ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
qglStencilFunc ( GL_EQUAL , sref , ~ 0 ) ;
}
else if ( qglActiveStencilFaceEXT )
{
2013-03-12 23:09:25 +00:00
//Nvidia-specific method.
2012-01-01 02:26:42 +00:00
sref / = 2 ;
qglClearStencil ( sref ) ;
qglClear ( GL_STENCIL_BUFFER_BIT ) ;
GL_CullFace ( 0 ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
qglEnable ( GL_STENCIL_TEST_TWO_SIDE_EXT ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
qglActiveStencilFaceEXT ( GL_BACK ) ;
qglStencilOp ( GL_KEEP , sbackfail , GL_KEEP ) ;
qglStencilFunc ( GL_ALWAYS , 0 , ~ 0 ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
qglActiveStencilFaceEXT ( GL_FRONT ) ;
qglStencilOp ( GL_KEEP , sfrontfail , GL_KEEP ) ;
qglStencilFunc ( GL_ALWAYS , 0 , ~ 0 ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
Sh_DrawStencilLightShadows ( dl , lvis , vvis , false ) ;
2010-07-11 02:22:39 +00:00
2012-01-01 02:26:42 +00:00
qglActiveStencilFaceEXT ( GL_BACK ) ;
qglStencilOp ( GL_KEEP , GL_KEEP , GL_KEEP ) ;
qglStencilFunc ( GL_ALWAYS , 0 , ~ 0 ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
qglActiveStencilFaceEXT ( GL_FRONT ) ;
qglStencilOp ( GL_KEEP , GL_KEEP , GL_KEEP ) ;
qglStencilFunc ( GL_EQUAL , sref , ~ 0 ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
qglDisable ( GL_STENCIL_TEST_TWO_SIDE_EXT ) ;
}
else //your graphics card sucks and lacks efficient stencil shadow techniques.
{ //centered around 0. Will only be increased then decreased less.
qglClearStencil ( sref ) ;
qglClear ( GL_STENCIL_BUFFER_BIT ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
qglStencilFunc ( GL_ALWAYS , 0 , ~ 0 ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
GL_CullFace ( SHADER_CULL_BACK ) ;
qglStencilOp ( GL_KEEP , sbackfail , GL_KEEP ) ;
Sh_DrawStencilLightShadows ( dl , lvis , vvis , false ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
GL_CullFace ( SHADER_CULL_FRONT ) ;
qglStencilOp ( GL_KEEP , sfrontfail , GL_KEEP ) ;
Sh_DrawStencilLightShadows ( dl , lvis , vvis , true ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
qglStencilOp ( GL_KEEP , GL_KEEP , GL_KEEP ) ;
qglStencilFunc ( GL_EQUAL , sref , ~ 0 ) ;
}
if ( gl_config . arb_depth_clamp )
qglDisable ( GL_DEPTH_CLAMP_ARB ) ;
//end stencil writing.
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
BE_SelectMode ( BEM_LIGHT ) ;
Sh_DrawEntLighting ( dl , colour ) ;
qglDisable ( GL_STENCIL_TEST ) ;
qglStencilFunc ( GL_ALWAYS , 0 , ~ 0 ) ;
}
break ;
2009-11-04 21:16:50 +00:00
# endif
2012-09-30 05:52:03 +00:00
# ifdef D3D9QUAKE
case QR_DIRECT3D9 :
2012-01-01 02:26:42 +00:00
sref = ( 1 < < 8 ) - 1 ;
sref / = 2 ;
/*clear the stencil buffer*/
IDirect3DDevice9_Clear ( pD3DDev9 , 0 , NULL , D3DCLEAR_STENCIL , D3DCOLOR_XRGB ( 0 , 0 , 0 ) , 1.0f , sref ) ;
/*set up 2-sided stenciling*/
2012-09-30 05:52:03 +00:00
D3D9BE_Cull ( 0 ) ;
2012-01-01 02:26:42 +00:00
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_STENCILENABLE , true ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_STENCILFUNC , D3DCMP_ALWAYS ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_TWOSIDEDSTENCILMODE , true ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_STENCILFAIL , D3DSTENCILOP_KEEP ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_STENCILZFAIL , D3DSTENCILOP_DECR ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_STENCILPASS , D3DSTENCILOP_KEEP ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_STENCILFUNC , D3DCMP_ALWAYS ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_CCW_STENCILFAIL , D3DSTENCILOP_KEEP ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_CCW_STENCILZFAIL , D3DSTENCILOP_INCR ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_CCW_STENCILPASS , D3DSTENCILOP_KEEP ) ;
/*draw the shadows*/
Sh_DrawStencilLightShadows ( dl , lvis , vvis , false ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
//disable stencil writing, switch culling back to normal
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_STENCILZFAIL , D3DSTENCILOP_KEEP ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_TWOSIDEDSTENCILMODE , false ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_CULLMODE , D3DCULL_CW ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_STENCILFUNC , D3DCMP_EQUAL ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_STENCILREF , sref ) ;
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_STENCILMASK , ~ 0 ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
/*draw the light*/
BE_SelectMode ( BEM_LIGHT ) ;
Sh_DrawEntLighting ( dl , colour ) ;
2009-11-04 21:16:50 +00:00
2012-01-01 02:26:42 +00:00
/*okay, no more stencil stuff*/
IDirect3DDevice9_SetRenderState ( pD3DDev9 , D3DRS_STENCILENABLE , false ) ;
break ;
# endif
}
2010-07-11 02:22:39 +00:00
2009-11-04 21:16:50 +00:00
return true ;
}
static void Sh_DrawShadowlessLight ( dlight_t * dl , vec3_t colour , qbyte * vvis )
{
vec3_t mins , maxs ;
2011-10-27 16:16:29 +00:00
srect_t rect ;
2009-11-04 21:16:50 +00:00
if ( R_CullSphere ( dl - > origin , dl - > radius ) )
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_FRUSTUM , 1 ) ;
2009-11-04 21:16:50 +00:00
return ; //this should be the more common case
}
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
if ( ! dl - > rebuildcache )
2009-11-04 21:16:50 +00:00
{
//fixme: check head node first?
if ( ! Sh_LeafInView ( dl - > worldshadowmesh - > litleaves , vvis ) )
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_PVS , 1 ) ;
2009-11-04 21:16:50 +00:00
return ;
}
}
else
{
int leaf ;
qbyte * lvis ;
leaf = cl . worldmodel - > funcs . LeafnumForPoint ( cl . worldmodel , dl - > origin ) ;
lvis = cl . worldmodel - > funcs . LeafPVS ( cl . worldmodel , leaf , lvisb , sizeof ( lvisb ) ) ;
2013-10-29 17:38:22 +00:00
SHM_BuildShadowMesh ( dl , lvis , vvis , SMT_SHADOWLESS ) ;
2009-11-04 21:16:50 +00:00
if ( ! Sh_VisOverlaps ( lvis , vvis ) ) //The two viewing areas do not intersect.
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_PVS , 1 ) ;
2009-11-04 21:16:50 +00:00
return ;
}
}
mins [ 0 ] = dl - > origin [ 0 ] - dl - > radius ;
mins [ 1 ] = dl - > origin [ 1 ] - dl - > radius ;
mins [ 2 ] = dl - > origin [ 2 ] - dl - > radius ;
maxs [ 0 ] = dl - > origin [ 0 ] + dl - > radius ;
maxs [ 1 ] = dl - > origin [ 1 ] + dl - > radius ;
maxs [ 2 ] = dl - > origin [ 2 ] + dl - > radius ;
2011-10-27 16:16:29 +00:00
//sets up the gl scissor (actually just culls to view)
if ( Sh_ScissorForBox ( mins , maxs , & rect ) )
2010-07-11 02:22:39 +00:00
{
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_CULL_SCISSOR , 1 ) ;
2009-11-04 21:16:50 +00:00
return ; //was culled.
2010-07-11 02:22:39 +00:00
}
2012-01-01 02:26:42 +00:00
2012-09-30 05:52:03 +00:00
//should we actually scissor here? there's not really much point I suppose.
2013-06-23 02:17:02 +00:00
BE_Scissor ( NULL ) ;
2009-11-04 21:16:50 +00:00
2013-10-08 14:28:11 +00:00
RQuantAdd ( RQUANT_RTLIGHT_DRAWN , 1 ) ;
2009-11-04 21:16:50 +00:00
2013-10-08 14:28:11 +00:00
BE_SelectDLight ( dl , colour , LSHADER_STANDARD ) ;
2011-04-20 23:34:13 +00:00
BE_SelectMode ( BEM_LIGHT ) ;
2009-11-04 21:16:50 +00:00
Sh_DrawEntLighting ( dl , colour ) ;
}
2012-05-14 01:41:08 +00:00
void GLBE_SubmitMeshes ( qboolean drawworld , int start , int stop ) ;
2012-05-11 01:57:00 +00:00
2012-05-14 01:41:08 +00:00
void Sh_DrawCrepuscularLight ( dlight_t * dl , float * colours )
2011-12-05 15:23:40 +00:00
{
2012-01-01 02:26:42 +00:00
# ifdef GLQUAKE
2011-12-05 15:23:40 +00:00
static mesh_t mesh ;
static vecV_t xyz [ 4 ] =
{
{ - 1 , - 1 , - 1 } ,
{ - 1 , 1 , - 1 } ,
{ 1 , 1 , - 1 } ,
{ 1 , - 1 , - 1 }
} ;
static vec2_t tc [ 4 ] =
{
{ 0 , 0 } ,
{ 0 , 1 } ,
{ 1 , 1 } ,
{ 1 , 0 }
} ;
static index_t idx [ 6 ] =
{
0 , 1 , 2 ,
0 , 2 , 3
} ;
2012-01-01 02:26:42 +00:00
if ( qrenderer ! = QR_OPENGL )
return ;
2011-12-05 15:23:40 +00:00
mesh . numindexes = 6 ;
mesh . numvertexes = 4 ;
mesh . xyz_array = xyz ;
mesh . st_array = tc ;
mesh . indexes = idx ;
2012-01-01 02:26:42 +00:00
2011-12-05 15:23:40 +00:00
/*
a crepuscular light ( seriously , that ' s the correct spelling ) is one that gives ' god rays ' , rather than regular light .
our implementation doesn ' t cast shadows . this allows it to actually be outside the map , and to shine through cloud layers in the sky .
we could cast shadows if the light was actually inside , I suppose .
Anyway , its done using an FBO , where everything but the sky is black ( stuff that occludes the sky is black too ) .
which is then blitted onto the screen in 2 d - space .
*/
/*requires an FBO, as stated above*/
if ( ! gl_config . ext_framebuffer_objects )
return ;
2012-04-24 07:59:11 +00:00
2012-09-30 05:52:03 +00:00
//fixme: we should add an extra few pixels each side to the fbo, to avoid too much weirdness at screen edges.
2012-05-11 01:57:00 +00:00
if ( ! crepuscular_texture_id . num )
2011-12-05 15:23:40 +00:00
{
/*FIXME: requires npot*/
2013-08-21 07:14:39 +00:00
crepuscular_shader = R_RegisterShader ( " crepuscular_screen " , SUF_NONE ,
2011-12-05 15:23:40 +00:00
" { \n "
" program crepuscular_rays \n "
" { \n "
2012-05-11 01:57:00 +00:00
" map $sourcecolour \n "
2011-12-05 15:23:40 +00:00
" blend add \n "
" } \n "
" } \n "
) ;
2012-05-11 01:57:00 +00:00
2012-09-30 05:52:03 +00:00
crepuscular_texture_id = GL_AllocNewTexture ( " ***crepusculartexture*** " , vid . pixelwidth , vid . pixelheight , 0 ) ;
2011-12-05 15:23:40 +00:00
GL_MTBind ( 0 , GL_TEXTURE_2D , crepuscular_texture_id ) ;
qglTexImage2D ( GL_TEXTURE_2D , 0 , GL_RGBA , vid . pixelwidth , vid . pixelheight , 0 , GL_RGBA , GL_UNSIGNED_BYTE , NULL ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_NEAREST ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_S , GL_CLAMP ) ;
qglTexParameteri ( GL_TEXTURE_2D , GL_TEXTURE_WRAP_T , GL_CLAMP ) ;
}
2012-05-11 01:57:00 +00:00
2013-06-23 02:17:02 +00:00
BE_Scissor ( NULL ) ;
2012-09-30 05:52:03 +00:00
2013-03-12 23:13:39 +00:00
GLBE_RenderToTexture ( r_nulltex , r_nulltex , crepuscular_texture_id , r_nulltex , false ) ;
2012-05-11 01:57:00 +00:00
2011-12-05 15:23:40 +00:00
BE_SelectMode ( BEM_CREPUSCULAR ) ;
2013-10-08 14:28:11 +00:00
BE_SelectDLight ( dl , colours , LSHADER_STANDARD ) ;
2012-05-14 01:41:08 +00:00
GLBE_SubmitMeshes ( true , SHADER_SORT_PORTAL , SHADER_SORT_BLEND ) ;
2012-05-11 01:57:00 +00:00
2013-03-12 23:13:39 +00:00
GLBE_RenderToTexture ( crepuscular_texture_id , r_nulltex , r_nulltex , r_nulltex , false ) ;
2011-12-05 15:23:40 +00:00
BE_SelectMode ( BEM_STANDARD ) ;
GLBE_DrawMesh_Single ( crepuscular_shader , & mesh , NULL , & crepuscular_shader - > defaulttextures , 0 ) ;
2012-05-11 01:57:00 +00:00
2013-03-12 23:13:39 +00:00
GLBE_RenderToTexture ( r_nulltex , r_nulltex , r_nulltex , r_nulltex , false ) ;
2011-12-05 15:23:40 +00:00
# endif
}
2012-05-09 15:30:53 +00:00
void Sh_PurgeShadowMeshes ( void )
{
dlight_t * dl ;
int i ;
for ( dl = cl_dlights , i = 0 ; i < cl_maxdlights ; i + + , dl + + )
{
if ( dl - > worldshadowmesh )
{
SH_FreeShadowMesh ( dl - > worldshadowmesh ) ;
dl - > worldshadowmesh = NULL ;
2013-10-29 17:38:22 +00:00
dl - > rebuildcache = true ;
2012-05-09 15:30:53 +00:00
}
}
}
2011-12-23 03:12:29 +00:00
void Sh_PreGenerateLights ( void )
{
unsigned int ignoreflags ;
dlight_t * dl ;
2013-10-08 14:28:11 +00:00
int shadowtype ;
2011-12-23 03:12:29 +00:00
int leaf ;
qbyte * lvis ;
int i ;
2013-07-14 12:22:51 +00:00
if ( r_shadow_realtime_dlight . ival | | r_shadow_realtime_world . ival )
{
2013-10-08 14:28:11 +00:00
if ( rtlights_first = = rtlights_max )
R_LoadRTLights ( ) ;
2013-07-14 12:22:51 +00:00
if ( rtlights_first = = rtlights_max )
R_ImportRTLights ( cl . worldmodel - > entities ) ;
}
2011-12-23 03:12:29 +00:00
ignoreflags = ( r_shadow_realtime_world . value ? LFLAG_REALTIMEMODE : LFLAG_NORMALMODE ) ;
for ( dl = cl_dlights + rtlights_first , i = rtlights_first ; i < rtlights_max ; i + + , dl + + )
{
2013-10-29 17:38:22 +00:00
dl - > rebuildcache = true ;
2013-10-08 14:28:11 +00:00
if ( dl - > radius )
{
if ( dl - > flags & ignoreflags )
{
if ( dl - > flags & LFLAG_CREPUSCULAR )
continue ;
2011-12-23 03:12:29 +00:00
2013-10-29 17:38:22 +00:00
if ( ( ( ! dl - > die ) ? ! r_shadow_realtime_world_shadows . ival : ! r_shadow_realtime_dlight_shadows . ival ) | | ( dl - > flags & LFLAG_NOSHADOWS ) )
2013-10-08 14:28:11 +00:00
shadowtype = SMT_SHADOWLESS ;
else if ( dl - > flags & LFLAG_SHADOWMAP | | r_shadow_shadowmapping . ival )
shadowtype = SMT_SHADOWMAP ;
else
shadowtype = SMT_STENCILVOLUME ;
2011-12-23 03:12:29 +00:00
2013-10-08 14:28:11 +00:00
leaf = cl . worldmodel - > funcs . LeafnumForPoint ( cl . worldmodel , dl - > origin ) ;
lvis = cl . worldmodel - > funcs . LeafPVS ( cl . worldmodel , leaf , lvisb , sizeof ( lvisb ) ) ;
2011-12-23 03:12:29 +00:00
2013-10-08 14:28:11 +00:00
SHM_BuildShadowMesh ( dl , lvis , NULL , shadowtype ) ;
continue ;
}
}
2011-12-23 03:12:29 +00:00
2013-10-08 14:28:11 +00:00
if ( dl - > worldshadowmesh )
{
SH_FreeShadowMesh ( dl - > worldshadowmesh ) ;
dl - > worldshadowmesh = NULL ;
dl - > rebuildcache = true ;
}
2011-12-23 03:12:29 +00:00
}
}
2012-05-09 15:30:53 +00:00
void Com_ParseVector ( char * str , vec3_t out )
{
str = COM_Parse ( str ) ;
out [ 0 ] = atof ( com_token ) ;
str = COM_Parse ( str ) ;
out [ 1 ] = atof ( com_token ) ;
str = COM_Parse ( str ) ;
out [ 2 ] = atof ( com_token ) ;
}
2013-11-21 23:02:28 +00:00
void Sh_CheckSettings ( void )
2009-11-04 21:16:50 +00:00
{
2013-11-21 23:02:28 +00:00
qboolean canstencil = false , cansmap = false ;
r_shadow_shadowmapping . ival = r_shadow_shadowmapping . value ;
r_shadow_realtime_world . ival = r_shadow_realtime_world . value ;
r_shadow_realtime_dlight . ival = r_shadow_realtime_dlight . value ;
2009-11-04 21:16:50 +00:00
2013-10-29 17:38:22 +00:00
switch ( qrenderer )
2011-09-03 03:49:43 +00:00
{
2013-10-29 17:38:22 +00:00
# ifdef GLQUAKE
case QR_OPENGL :
2013-11-21 23:02:28 +00:00
if ( gl_config . arb_shader_objects & & gl_config . ext_framebuffer_objects & & gl_config . arb_shadow )
cansmap = true ;
if ( gl_stencilbits )
canstencil = true ;
2013-10-29 17:38:22 +00:00
break ;
# endif
# ifdef D3D9QUAKE
case QR_DIRECT3D9 :
2013-11-21 23:02:28 +00:00
# ifndef GLQUAKE
2013-10-29 17:38:22 +00:00
//the code still has a lot of ifdefs, so will crash if you try it in a merged build.
//its not really usable in d3d-only builds either, so no great loss.
2013-11-21 23:02:28 +00:00
canstencil = true ;
2013-10-29 17:38:22 +00:00
# endif
break ;
2013-11-21 23:02:28 +00:00
# endif
# ifdef D3D11QUAKE
case QR_DIRECT3D11 :
cansmap = true ;
break ;
2013-10-29 17:38:22 +00:00
# endif
default :
2013-11-21 23:02:28 +00:00
r_shadow_realtime_world . ival = 0 ;
r_shadow_realtime_dlight . ival = 0 ;
2009-11-04 21:16:50 +00:00
return ;
2011-09-03 03:49:43 +00:00
}
2009-11-04 21:16:50 +00:00
2013-11-21 23:02:28 +00:00
if ( ! canstencil & & ! cansmap )
{
//no shadow methods available at all.
Con_Printf ( " Missing GL extensions: realtime lighting is not possible. \n " ) ;
r_shadow_realtime_world . ival = 0 ;
r_shadow_realtime_dlight . ival = 0 ;
}
else if ( ! canstencil | | ! cansmap )
{
//only one shadow method
if ( ! ! r_shadow_shadowmapping . ival ! = cansmap )
{
Con_Printf ( " Missing GL extensions: forcing shadowmapping %s. \n " , cansmap ? " on " : " off " ) ;
r_shadow_shadowmapping . ival = cansmap ;
}
}
else
{
//both shadow methods available.
}
}
void Sh_DrawLights ( qbyte * vis )
{
vec3_t colour ;
dlight_t * dl ;
int i ;
unsigned int ignoreflags ;
2013-07-14 12:22:51 +00:00
if ( r_shadow_realtime_world . modified | |
2013-10-29 17:38:22 +00:00
r_shadow_realtime_world_shadows . modified | |
2013-07-14 12:22:51 +00:00
r_shadow_realtime_dlight . modified | |
r_shadow_realtime_dlight_shadows . modified | |
r_shadow_shadowmapping . modified )
{
r_shadow_realtime_world . modified =
2013-10-29 17:38:22 +00:00
r_shadow_realtime_world_shadows . modified =
2013-07-14 12:22:51 +00:00
r_shadow_realtime_dlight . modified =
r_shadow_realtime_dlight_shadows . modified =
r_shadow_shadowmapping . modified =
false ;
2013-11-21 23:02:28 +00:00
Sh_CheckSettings ( ) ;
2013-07-14 12:22:51 +00:00
//make sure the lighting is reloaded
Sh_PreGenerateLights ( ) ;
}
2013-10-29 17:38:22 +00:00
if ( ! r_shadow_realtime_world . ival & & ! r_shadow_realtime_dlight . ival )
2011-06-05 23:53:33 +00:00
{
2009-11-04 21:16:50 +00:00
return ;
2010-09-05 10:42:23 +00:00
}
2009-11-04 21:16:50 +00:00
ignoreflags = ( r_shadow_realtime_world . value ? LFLAG_REALTIMEMODE : LFLAG_NORMALMODE ) ;
2013-10-29 17:38:22 +00:00
// if (r_refdef.recurse)
2009-11-04 21:16:50 +00:00
for ( dl = cl_dlights + rtlights_first , i = rtlights_first ; i < rtlights_max ; i + + , dl + + )
{
if ( ! dl - > radius )
continue ; //dead
if ( ! ( dl - > flags & ignoreflags ) )
continue ;
2011-12-26 15:19:13 +00:00
colour [ 0 ] = dl - > color [ 0 ] ;
colour [ 1 ] = dl - > color [ 1 ] ;
colour [ 2 ] = dl - > color [ 2 ] ;
2009-11-04 21:16:50 +00:00
if ( dl - > style )
{
if ( cl_lightstyle [ dl - > style - 1 ] . colour & 1 )
colour [ 0 ] * = d_lightstylevalue [ dl - > style - 1 ] / 255.0f ;
else
colour [ 0 ] = 0 ;
if ( cl_lightstyle [ dl - > style - 1 ] . colour & 2 )
colour [ 1 ] * = d_lightstylevalue [ dl - > style - 1 ] / 255.0f ;
else
colour [ 1 ] = 0 ;
if ( cl_lightstyle [ dl - > style - 1 ] . colour & 4 )
colour [ 2 ] * = d_lightstylevalue [ dl - > style - 1 ] / 255.0f ;
else
colour [ 2 ] = 0 ;
}
if ( colour [ 0 ] < 0.001 & & colour [ 1 ] < 0.001 & & colour [ 2 ] < 0.001 )
continue ; //just switch these off.
2011-12-05 15:23:40 +00:00
if ( dl - > flags & LFLAG_CREPUSCULAR )
2012-05-14 01:41:08 +00:00
Sh_DrawCrepuscularLight ( dl , colour ) ;
2012-02-27 12:23:15 +00:00
else if ( ( ( i > = RTL_FIRST ) ? ! r_shadow_realtime_world_shadows . ival : ! r_shadow_realtime_dlight_shadows . ival ) | | dl - > flags & LFLAG_NOSHADOWS )
2009-11-04 21:16:50 +00:00
{
Sh_DrawShadowlessLight ( dl , colour , vis ) ;
}
2012-10-08 04:36:10 +00:00
else if ( ( dl - > flags & LFLAG_SHADOWMAP ) | | r_shadow_shadowmapping . ival )
2009-11-04 21:16:50 +00:00
{
2010-07-11 16:23:04 +00:00
Sh_DrawShadowMapLight ( dl , colour , vis ) ;
2009-11-04 21:16:50 +00:00
}
else
{
Sh_DrawStencilLight ( dl , colour , vis ) ;
}
}
2013-10-29 17:38:22 +00:00
# ifdef GLQUAKE
if ( gl_config . arb_shader_objects )
2012-05-09 15:30:53 +00:00
{
dlight_t sun = { 0 } ;
vec3_t sundir ;
float dot ;
Com_ParseVector ( r_sun_dir . string , sundir ) ;
Com_ParseVector ( r_sun_colour . string , colour ) ;
//fade it out if we're looking at an angle parallel to it (to avoid nasty visible graduations or backwards rays!)
dot = DotProduct ( vpn , sundir ) ;
dot = 1 - dot ;
dot * = dot ;
dot = 1 - dot ;
VectorScale ( colour , dot , colour ) ;
if ( colour [ 0 ] > 0.001 | | colour [ 1 ] > 0.001 | | colour [ 2 ] > 0.001 )
{
//only do this if we can see some sky surfaces. pointless otherwise
batch_t * b ;
for ( b = cl . worldmodel - > batches [ SHADER_SORT_SKY ] ; b ; b = b - > next )
{
if ( b - > meshes )
break ;
}
if ( b )
{
VectorNormalize ( sundir ) ;
VectorMA ( r_origin , 1000 , sundir , sun . origin ) ;
2012-05-14 01:41:08 +00:00
Sh_DrawCrepuscularLight ( & sun , colour ) ;
2012-05-09 15:30:53 +00:00
}
}
}
2013-10-29 17:38:22 +00:00
# endif
2012-05-09 15:30:53 +00:00
2013-06-23 02:17:02 +00:00
BE_Scissor ( NULL ) ;
2012-01-01 02:26:42 +00:00
2011-04-20 23:34:13 +00:00
BE_SelectMode ( BEM_STANDARD ) ;
2009-11-04 21:16:50 +00:00
2010-07-11 02:22:39 +00:00
// if (developer.value)
// Con_Printf("%i lights drawn, %i frustum culled, %i pvs culled, %i scissor culled\n", bench.numlights, bench.numfrustumculled, bench.numpvsculled, bench.numscissorculled);
// memset(&bench, 0, sizeof(bench));
2009-11-04 21:16:50 +00:00
}
# endif
2013-10-08 14:28:11 +00:00
//stencil shadows generally require that the farclip distance is really really far away
//so this little function is used to check if its needed or not.
qboolean Sh_StencilShadowsActive ( void )
{
# ifdef RTLIGHTS
//if shadowmapping is forced on all lights then we don't need special depth stuff
// if (r_shadow_shadowmapping.ival)
// return false;
return ( r_shadow_realtime_dlight . ival & & r_shadow_realtime_dlight_shadows . ival ) | |
( r_shadow_realtime_world . ival & & r_shadow_realtime_world_shadows . ival ) ;
# else
return false ;
# endif
}
void Sh_RegisterCvars ( void )
{
# ifdef RTLIGHTS
# define REALTIMELIGHTING "Realtime Lighting"
Cvar_Register ( & r_shadow_scissor , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_realtime_world , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_realtime_world_shadows , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_realtime_dlight , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_realtime_dlight_ambient , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_realtime_dlight_diffuse , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_realtime_dlight_specular , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_realtime_dlight_shadows , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_realtime_world_lightmaps , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_shadowmapping , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_shadowmapping_precision , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_shadowmapping_nearclip , REALTIMELIGHTING ) ;
Cvar_Register ( & r_shadow_shadowmapping_bias , REALTIMELIGHTING ) ;
Cvar_Register ( & r_sun_dir , REALTIMELIGHTING ) ;
Cvar_Register ( & r_sun_colour , REALTIMELIGHTING ) ;
# endif
}