2010-02-15 23:26:55 +00:00
/*
Copyright ( C ) 1996 - 2001 Id Software , Inc .
Copyright ( C ) 2002 - 2009 John Fitzgibbons and others
2014-09-22 08:55:46 +00:00
Copyright ( C ) 2010 - 2014 QuakeSpasm developers
2010-02-15 23:26:55 +00:00
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
//r_alias.c -- alias model rendering
# include "quakedef.h"
extern cvar_t r_drawflat , gl_overbright_models , gl_fullbrights , r_lerpmodels , r_lerpmove ; //johnfitz
2021-09-02 17:50:50 +00:00
extern cvar_t scr_fov , cl_gun_fovscale ;
2010-02-15 23:26:55 +00:00
# define NUMVERTEXNORMALS 162
2014-09-22 08:55:46 +00:00
float r_avertexnormals [ NUMVERTEXNORMALS ] [ 3 ] =
{
2010-02-15 23:26:55 +00:00
# include "anorms.h"
} ;
extern vec3_t lightcolor ; //johnfitz -- replaces "float shadelight" for lit support
// precalculated dot products for quantized angles
# define SHADEDOT_QUANT 16
float r_avertexnormal_dots [ SHADEDOT_QUANT ] [ 256 ] =
2014-09-22 08:55:46 +00:00
{
2010-02-15 23:26:55 +00:00
# include "anorm_dots.h"
2014-09-22 08:55:46 +00:00
} ;
2010-02-15 23:26:55 +00:00
extern vec3_t lightspot ;
float * shadedots = r_avertexnormal_dots [ 0 ] ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
vec3_t shadevector ;
2015-08-23 09:53:05 +00:00
2010-02-15 23:26:55 +00:00
float entalpha ; //johnfitz
qboolean overbright ; //johnfitz
qboolean shading = true ; //johnfitz -- if false, disable vertex shading for various reasons (fullbright, r_lightmap, showtris, etc)
//johnfitz -- struct for passing lerp information to drawing functions
typedef struct {
short pose1 ;
short pose2 ;
float blend ;
vec3_t origin ;
vec3_t angles ;
2019-11-02 15:50:53 +00:00
bonepose_t * bonestate ;
2010-02-15 23:26:55 +00:00
} lerpdata_t ;
//johnfitz
2019-11-02 15:50:53 +00:00
enum
{
ALIAS_GLSL_BASIC ,
ALIAS_GLSL_SKELETAL ,
ALIAS_GLSL_MODES
} ;
typedef struct
{
int maxbones ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
2019-11-02 15:50:53 +00:00
GLuint program ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
2019-11-02 15:50:53 +00:00
// uniforms used in vert shader
GLuint bonesLoc ;
GLuint blendLoc ;
GLuint shadevectorLoc ;
GLuint lightColorLoc ;
// uniforms used in frag shader
GLuint texLoc ;
2023-07-07 09:57:40 +00:00
GLuint lowerTexLoc ;
GLuint upperTexLoc ;
2019-11-02 15:50:53 +00:00
GLuint fullbrightTexLoc ;
GLuint useFullbrightTexLoc ;
GLuint useOverbrightLoc ;
GLuint useAlphaTestLoc ;
2023-07-07 09:57:40 +00:00
GLuint colorTintLoc ;
2019-11-02 15:50:53 +00:00
} aliasglsl_t ;
static aliasglsl_t r_alias_glsl [ ALIAS_GLSL_MODES ] ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
2017-07-28 20:01:19 +00:00
# define pose1VertexAttrIndex 0
# define pose1NormalAttrIndex 1
# define pose2VertexAttrIndex 2
# define pose2NormalAttrIndex 3
# define texCoordsAttrIndex 4
2019-11-02 15:50:53 +00:00
# define vertColoursAttrIndex 5
# define boneWeightAttrIndex pose2VertexAttrIndex
# define boneIndexAttrIndex pose2NormalAttrIndex
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
/*
= = = = = = = = = = = = =
GLARB_GetXYZOffset
Returns the offset of the first vertex ' s meshxyz_t . xyz in the vbo for the given
model and pose .
= = = = = = = = = = = = =
*/
2017-09-17 02:12:53 +00:00
static void * GLARB_GetXYZOffset_MDL ( aliashdr_t * hdr , int pose )
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
{
2017-09-17 02:12:53 +00:00
const size_t xyzoffs = offsetof ( meshxyz_mdl_t , xyz ) ;
return currententity - > model - > meshvboptr + ( hdr - > vbovertofs + ( hdr - > numverts_vbo * pose * sizeof ( meshxyz_mdl_t ) ) + xyzoffs ) ;
}
2019-01-30 01:54:49 +00:00
static void * GLARB_GetXYZOffset_MDLQF ( aliashdr_t * hdr , int pose )
{
const size_t xyzoffs = offsetof ( meshxyz_mdl16_t , xyz ) ;
return currententity - > model - > meshvboptr + ( hdr - > vbovertofs + ( hdr - > numverts_vbo * pose * sizeof ( meshxyz_mdl16_t ) ) + xyzoffs ) ;
}
2017-09-17 02:12:53 +00:00
static void * GLARB_GetXYZOffset_MD3 ( aliashdr_t * hdr , int pose )
{
const size_t xyzoffs = offsetof ( meshxyz_md3_t , xyz ) ;
return currententity - > model - > meshvboptr + ( hdr - > vbovertofs + ( hdr - > numverts_vbo * pose * sizeof ( meshxyz_md3_t ) ) + xyzoffs ) ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
}
/*
= = = = = = = = = = = = =
GLARB_GetNormalOffset
Returns the offset of the first vertex ' s meshxyz_t . normal in the vbo for the
given model and pose .
= = = = = = = = = = = = =
*/
2017-09-17 02:12:53 +00:00
static void * GLARB_GetNormalOffset_MDL ( aliashdr_t * hdr , int pose )
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
{
2017-09-17 02:12:53 +00:00
const size_t normaloffs = offsetof ( meshxyz_mdl_t , normal ) ;
return currententity - > model - > meshvboptr + ( hdr - > vbovertofs + ( hdr - > numverts_vbo * pose * sizeof ( meshxyz_mdl_t ) ) + normaloffs ) ;
}
2019-01-30 01:54:49 +00:00
static void * GLARB_GetNormalOffset_MDLQF ( aliashdr_t * hdr , int pose )
{
const size_t normaloffs = offsetof ( meshxyz_mdl16_t , normal ) ;
return currententity - > model - > meshvboptr + ( hdr - > vbovertofs + ( hdr - > numverts_vbo * pose * sizeof ( meshxyz_mdl16_t ) ) + normaloffs ) ;
}
2017-09-17 02:12:53 +00:00
static void * GLARB_GetNormalOffset_MD3 ( aliashdr_t * hdr , int pose )
{
const size_t normaloffs = offsetof ( meshxyz_md3_t , normal ) ;
return currententity - > model - > meshvboptr + ( hdr - > vbovertofs + ( hdr - > numverts_vbo * pose * sizeof ( meshxyz_md3_t ) ) + normaloffs ) ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
}
/*
= = = = = = = = = = = = =
GLAlias_CreateShaders
= = = = = = = = = = = = =
*/
void GLAlias_CreateShaders ( void )
{
2019-11-02 15:50:53 +00:00
int i ;
aliasglsl_t * glsl ;
char processedVertSource [ 8192 ] , * defines ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
const glsl_attrib_binding_t bindings [ ] = {
{ " TexCoords " , texCoordsAttrIndex } ,
{ " Pose1Vert " , pose1VertexAttrIndex } ,
{ " Pose1Normal " , pose1NormalAttrIndex } ,
{ " Pose2Vert " , pose2VertexAttrIndex } ,
2019-11-02 15:50:53 +00:00
{ " Pose2Normal " , pose2NormalAttrIndex } ,
{ " VertColours " , vertColoursAttrIndex }
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
} ;
const GLchar * vertSource = \
" #version 110 \n "
2019-11-02 15:50:53 +00:00
" %s "
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
" \n "
" uniform vec3 ShadeVector; \n "
" uniform vec4 LightColor; \n "
" attribute vec4 TexCoords; // only xy are used \n "
" attribute vec4 Pose1Vert; \n "
" attribute vec3 Pose1Normal; \n "
2019-11-02 15:50:53 +00:00
" #ifdef SKELETAL \n "
" #define BoneWeight Pose2Vert \n "
" #define BoneIndex Pose2Normal \n "
" attribute vec4 BoneWeight; \n "
" attribute vec4 BoneIndex; \n "
" attribute vec4 VertColours; \n "
" uniform vec4 BoneTable[MAXBONES*3]; \n " //fixme: should probably try to use a UBO or SSBO.
" #else \n "
" uniform float Blend; \n "
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
" attribute vec4 Pose2Vert; \n "
" attribute vec3 Pose2Normal; \n "
2019-11-02 15:50:53 +00:00
" #endif \n "
2017-12-24 18:59:44 +00:00
" \n "
" varying float FogFragCoord; \n "
" \n "
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
" float r_avertexnormal_dot(vec3 vertexnormal) // from MH \n "
" { \n "
" float dot = dot(vertexnormal, ShadeVector); \n "
" // wtf - this reproduces anorm_dots within as reasonable a degree of tolerance as the >= 0 case \n "
" if (dot < 0.0) \n "
" return 1.0 + dot * (13.0 / 44.0); \n "
" else \n "
" return 1.0 + dot; \n "
" } \n "
" void main() \n "
" { \n "
" gl_TexCoord[0] = TexCoords; \n "
2019-11-02 15:50:53 +00:00
" #ifdef SKELETAL \n "
" mat4 wmat; "
" wmat[0] = BoneTable[0+3*int(BoneIndex.x)] * BoneWeight.x; "
" wmat[0] += BoneTable[0+3*int(BoneIndex.y)] * BoneWeight.y; "
" wmat[0] += BoneTable[0+3*int(BoneIndex.z)] * BoneWeight.z; "
" wmat[0] += BoneTable[0+3*int(BoneIndex.w)] * BoneWeight.w; "
" wmat[1] = BoneTable[1+3*int(BoneIndex.x)] * BoneWeight.x; "
" wmat[1] += BoneTable[1+3*int(BoneIndex.y)] * BoneWeight.y; "
" wmat[1] += BoneTable[1+3*int(BoneIndex.z)] * BoneWeight.z; "
" wmat[1] += BoneTable[1+3*int(BoneIndex.w)] * BoneWeight.w; "
" wmat[2] = BoneTable[2+3*int(BoneIndex.x)] * BoneWeight.x; "
" wmat[2] += BoneTable[2+3*int(BoneIndex.y)] * BoneWeight.y; "
" wmat[2] += BoneTable[2+3*int(BoneIndex.z)] * BoneWeight.z; "
" wmat[2] += BoneTable[2+3*int(BoneIndex.w)] * BoneWeight.w; "
" wmat[3] = vec4(0.0,0.0,0.0,1.0); \n "
" vec4 lerpedVert = (vec4(Pose1Vert.xyz, 1.0) * wmat); \n "
2021-09-03 07:11:57 +00:00
" float dot1 = r_avertexnormal_dot(normalize((vec4(Pose1Normal.xyz, 0.0) * wmat).xyz)); \n "
2019-11-02 15:50:53 +00:00
" #else \n "
2017-12-24 18:59:44 +00:00
" vec4 lerpedVert = mix(vec4(Pose1Vert.xyz, 1.0), vec4(Pose2Vert.xyz, 1.0), Blend); \n "
2019-11-02 15:50:53 +00:00
" float dot1 = mix(r_avertexnormal_dot(Pose1Normal), r_avertexnormal_dot(Pose2Normal), Blend); \n "
" #endif \n "
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
" gl_Position = gl_ModelViewProjectionMatrix * lerpedVert; \n "
2017-12-24 18:59:44 +00:00
" FogFragCoord = gl_Position.w; \n "
2019-11-02 15:50:53 +00:00
" gl_FrontColor = LightColor * vec4(vec3(dot1), 1.0); \n "
" #ifdef SKELETAL \n "
" gl_FrontColor *= VertColours; \n " //this is basically only useful for vertex alphas.
" #endif \n "
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
" } \n " ;
const GLchar * fragSource = \
" #version 110 \n "
" \n "
" uniform sampler2D Tex; \n "
2023-07-07 09:57:40 +00:00
" uniform sampler2D LowerTex; \n " //team colour
" uniform sampler2D UpperTex; \n " //personal colour
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
" uniform sampler2D FullbrightTex; \n "
" uniform bool UseFullbrightTex; \n "
" uniform bool UseOverbright; \n "
2017-08-04 19:45:11 +00:00
" uniform bool UseAlphaTest; \n "
2023-07-07 09:57:40 +00:00
" uniform vec4 ColourTint[3]; \n " //base+bot+top+fb
2017-12-24 18:59:44 +00:00
" \n "
" varying float FogFragCoord; \n "
" \n "
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
" void main() \n "
" { \n "
2023-07-07 09:57:40 +00:00
" vec4 result = texture2D(Tex, gl_TexCoord[0].xy); \n " //base
" if (ColourTint[0].a != 0.0) result.rgb += texture2D(LowerTex, gl_TexCoord[0].xy).rgb * ColourTint[0].rgb; \n " //team/lower/trousers
" if (ColourTint[1].a != 0.0) result.rgb += texture2D(UpperTex, gl_TexCoord[0].xy).rgb * ColourTint[1].rgb; \n " //personal/upper/torso
2017-08-04 19:45:11 +00:00
" if (UseAlphaTest && (result.a < 0.666)) \n "
" discard; \n "
2023-07-07 09:57:40 +00:00
" result *= gl_Color; \n " //vertex lighting results (and colormod).
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
" if (UseOverbright) \n "
" result.rgb *= 2.0; \n "
" if (UseFullbrightTex) \n "
2023-07-07 09:57:40 +00:00
" result += texture2D(FullbrightTex, gl_TexCoord[0].xy) * ColourTint[2]; \n " //fullbrights (with glowmod)
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
" result = clamp(result, 0.0, 1.0); \n "
2017-12-24 18:59:44 +00:00
" float fog = exp(-gl_Fog.density * gl_Fog.density * FogFragCoord * FogFragCoord); \n "
2019-01-31 03:21:38 +00:00
" fog = clamp(fog, 0.0, 1.0) * gl_Fog.color.a; \n "
" result.rgb = mix(gl_Fog.color.rgb, result.rgb, fog); \n "
" result.a *= gl_Color.a; \n " // FIXME: This will make almost transparent things cut holes though heavy fog
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
" gl_FragColor = result; \n "
" } \n " ;
2015-02-20 00:24:05 +00:00
if ( ! gl_glsl_alias_able )
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
return ;
2019-11-02 15:50:53 +00:00
for ( i = 0 ; i < ALIAS_GLSL_MODES ; i + + )
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
{
2019-11-02 15:50:53 +00:00
glsl = & r_alias_glsl [ i ] ;
if ( i = = ALIAS_GLSL_SKELETAL )
{
defines = " #define SKELETAL \n #define MAXBONES 64 \n " ;
glsl - > maxbones = 64 ;
}
else
{
defines = " " ;
glsl - > maxbones = 0 ;
}
q_snprintf ( processedVertSource , sizeof ( processedVertSource ) , vertSource , defines ) ;
glsl - > program = GL_CreateProgram ( processedVertSource , fragSource , sizeof ( bindings ) / sizeof ( bindings [ 0 ] ) , bindings ) ;
if ( glsl - > program ! = 0 )
{
// get uniform locations
if ( i = = ALIAS_GLSL_SKELETAL )
{
glsl - > bonesLoc = GL_GetUniformLocation ( & glsl - > program , " BoneTable " ) ;
glsl - > blendLoc = - 1 ;
}
else
{
glsl - > bonesLoc = - 1 ;
glsl - > blendLoc = GL_GetUniformLocation ( & glsl - > program , " Blend " ) ;
}
glsl - > shadevectorLoc = GL_GetUniformLocation ( & glsl - > program , " ShadeVector " ) ;
glsl - > lightColorLoc = GL_GetUniformLocation ( & glsl - > program , " LightColor " ) ;
glsl - > texLoc = GL_GetUniformLocation ( & glsl - > program , " Tex " ) ;
2023-07-07 09:57:40 +00:00
glsl - > lowerTexLoc = GL_GetUniformLocation ( & glsl - > program , " LowerTex " ) ;
glsl - > upperTexLoc = GL_GetUniformLocation ( & glsl - > program , " UpperTex " ) ;
2019-11-02 15:50:53 +00:00
glsl - > fullbrightTexLoc = GL_GetUniformLocation ( & glsl - > program , " FullbrightTex " ) ;
glsl - > useFullbrightTexLoc = GL_GetUniformLocation ( & glsl - > program , " UseFullbrightTex " ) ;
glsl - > useOverbrightLoc = GL_GetUniformLocation ( & glsl - > program , " UseOverbright " ) ;
glsl - > useAlphaTestLoc = GL_GetUniformLocation ( & glsl - > program , " UseAlphaTest " ) ;
2023-07-07 09:57:40 +00:00
glsl - > colorTintLoc = GL_GetUniformLocation ( & glsl - > program , " ColourTint " ) ;
//we can do this here, its not going to change.
GL_UseProgramFunc ( glsl - > program ) ;
GL_Uniform1iFunc ( glsl - > texLoc , 0 ) ;
GL_Uniform1iFunc ( glsl - > fullbrightTexLoc , 1 ) ;
GL_Uniform1iFunc ( glsl - > lowerTexLoc , 2 ) ;
GL_Uniform1iFunc ( glsl - > upperTexLoc , 3 ) ;
GL_UseProgramFunc ( 0 ) ;
2019-11-02 15:50:53 +00:00
}
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
}
}
/*
= = = = = = = = = = = = =
GL_DrawAliasFrame_GLSL - - ericw
Optimized alias model drawing codepath .
Compared to the original GL_DrawAliasFrame , this makes 1 draw call ,
no vertex data is uploaded ( it ' s already in the r_meshvbo and r_meshindexesvbo
static VBOs ) , and lerping and lighting is done in the vertex shader .
Supports optional overbright , optional fullbright pixels .
Based on code by MH from RMQEngine
= = = = = = = = = = = = =
*/
2023-07-07 09:57:40 +00:00
static void GL_DrawAliasFrame_GLSL ( aliasglsl_t * glsl , aliashdr_t * paliashdr , lerpdata_t lerpdata , struct skintextures_s tex , entity_t * e )
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
{
2023-07-07 09:57:40 +00:00
GLfloat tints [ 3 ] [ 4 ] ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
float blend ;
if ( lerpdata . pose1 ! = lerpdata . pose2 )
{
blend = lerpdata . blend ;
}
else // poses the same means either 1. the entity has paused its animation, or 2. r_lerpmodels is disabled
{
blend = 0 ;
}
2019-11-02 15:50:53 +00:00
GL_UseProgramFunc ( glsl - > program ) ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
2015-09-20 20:10:49 +00:00
GL_BindBuffer ( GL_ARRAY_BUFFER , currententity - > model - > meshvbo ) ;
GL_BindBuffer ( GL_ELEMENT_ARRAY_BUFFER , currententity - > model - > meshindexesvbo ) ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
GL_EnableVertexAttribArrayFunc ( texCoordsAttrIndex ) ;
GL_EnableVertexAttribArrayFunc ( pose1VertexAttrIndex ) ;
GL_EnableVertexAttribArrayFunc ( pose2VertexAttrIndex ) ;
GL_EnableVertexAttribArrayFunc ( pose1NormalAttrIndex ) ;
GL_EnableVertexAttribArrayFunc ( pose2NormalAttrIndex ) ;
2019-01-30 01:54:49 +00:00
switch ( paliashdr - > poseverttype )
2017-09-17 02:12:53 +00:00
{
2019-01-30 01:54:49 +00:00
case PV_QUAKE1 :
2019-11-02 15:50:53 +00:00
GL_VertexAttribPointerFunc ( texCoordsAttrIndex , 2 , GL_FLOAT , GL_FALSE , 0 , currententity - > model - > meshvboptr + paliashdr - > vbostofs ) ;
2017-09-17 02:12:53 +00:00
GL_VertexAttribPointerFunc ( pose1VertexAttrIndex , 4 , GL_UNSIGNED_BYTE , GL_FALSE , sizeof ( meshxyz_mdl_t ) , GLARB_GetXYZOffset_MDL ( paliashdr , lerpdata . pose1 ) ) ;
GL_VertexAttribPointerFunc ( pose2VertexAttrIndex , 4 , GL_UNSIGNED_BYTE , GL_FALSE , sizeof ( meshxyz_mdl_t ) , GLARB_GetXYZOffset_MDL ( paliashdr , lerpdata . pose2 ) ) ;
// GL_TRUE to normalize the signed bytes to [-1 .. 1]
GL_VertexAttribPointerFunc ( pose1NormalAttrIndex , 4 , GL_BYTE , GL_TRUE , sizeof ( meshxyz_mdl_t ) , GLARB_GetNormalOffset_MDL ( paliashdr , lerpdata . pose1 ) ) ;
GL_VertexAttribPointerFunc ( pose2NormalAttrIndex , 4 , GL_BYTE , GL_TRUE , sizeof ( meshxyz_mdl_t ) , GLARB_GetNormalOffset_MDL ( paliashdr , lerpdata . pose2 ) ) ;
2019-01-30 01:54:49 +00:00
break ;
case PV_QUAKEFORGE :
2019-11-02 15:50:53 +00:00
GL_VertexAttribPointerFunc ( texCoordsAttrIndex , 2 , GL_FLOAT , GL_FALSE , 0 , currententity - > model - > meshvboptr + paliashdr - > vbostofs ) ;
2019-01-30 01:54:49 +00:00
GL_VertexAttribPointerFunc ( pose1VertexAttrIndex , 4 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof ( meshxyz_mdl16_t ) , GLARB_GetXYZOffset_MDLQF ( paliashdr , lerpdata . pose1 ) ) ;
GL_VertexAttribPointerFunc ( pose2VertexAttrIndex , 4 , GL_UNSIGNED_SHORT , GL_FALSE , sizeof ( meshxyz_mdl16_t ) , GLARB_GetXYZOffset_MDLQF ( paliashdr , lerpdata . pose2 ) ) ;
// GL_TRUE to normalize the signed bytes to [-1 .. 1]
GL_VertexAttribPointerFunc ( pose1NormalAttrIndex , 4 , GL_BYTE , GL_TRUE , sizeof ( meshxyz_mdl16_t ) , GLARB_GetNormalOffset_MDLQF ( paliashdr , lerpdata . pose1 ) ) ;
GL_VertexAttribPointerFunc ( pose2NormalAttrIndex , 4 , GL_BYTE , GL_TRUE , sizeof ( meshxyz_mdl16_t ) , GLARB_GetNormalOffset_MDLQF ( paliashdr , lerpdata . pose2 ) ) ;
break ;
case PV_QUAKE3 :
2019-11-02 15:50:53 +00:00
GL_VertexAttribPointerFunc ( texCoordsAttrIndex , 2 , GL_FLOAT , GL_FALSE , 0 , currententity - > model - > meshvboptr + paliashdr - > vbostofs ) ;
2017-09-17 02:12:53 +00:00
GL_VertexAttribPointerFunc ( pose1VertexAttrIndex , 4 , GL_SHORT , GL_FALSE , sizeof ( meshxyz_md3_t ) , GLARB_GetXYZOffset_MD3 ( paliashdr , lerpdata . pose1 ) ) ;
GL_VertexAttribPointerFunc ( pose2VertexAttrIndex , 4 , GL_SHORT , GL_FALSE , sizeof ( meshxyz_md3_t ) , GLARB_GetXYZOffset_MD3 ( paliashdr , lerpdata . pose2 ) ) ;
// GL_TRUE to normalize the signed bytes to [-1 .. 1]
GL_VertexAttribPointerFunc ( pose1NormalAttrIndex , 4 , GL_BYTE , GL_TRUE , sizeof ( meshxyz_md3_t ) , GLARB_GetNormalOffset_MD3 ( paliashdr , lerpdata . pose1 ) ) ;
GL_VertexAttribPointerFunc ( pose2NormalAttrIndex , 4 , GL_BYTE , GL_TRUE , sizeof ( meshxyz_md3_t ) , GLARB_GetNormalOffset_MD3 ( paliashdr , lerpdata . pose2 ) ) ;
2019-01-30 01:54:49 +00:00
break ;
2019-11-02 15:50:53 +00:00
case PV_IQM :
{
const iqmvert_t * pose = ( const iqmvert_t * ) ( currententity - > model - > meshvboptr + paliashdr - > vbovertofs + ( paliashdr - > numverts_vbo * 0 * sizeof ( iqmvert_t ) ) ) ;
GL_VertexAttribPointerFunc ( pose1VertexAttrIndex , 3 , GL_FLOAT , GL_FALSE , sizeof ( iqmvert_t ) , pose - > xyz ) ;
GL_VertexAttribPointerFunc ( pose1NormalAttrIndex , 3 , GL_FLOAT , GL_FALSE , sizeof ( iqmvert_t ) , pose - > norm ) ;
GL_VertexAttribPointerFunc ( boneWeightAttrIndex , 4 , GL_FLOAT , GL_FALSE , sizeof ( iqmvert_t ) , pose - > weight ) ;
GL_VertexAttribPointerFunc ( boneIndexAttrIndex , 4 , GL_UNSIGNED_BYTE , GL_FALSE , sizeof ( iqmvert_t ) , pose - > idx ) ;
GL_VertexAttribPointerFunc ( texCoordsAttrIndex , 2 , GL_FLOAT , GL_FALSE , sizeof ( iqmvert_t ) , pose - > st ) ;
GL_EnableVertexAttribArrayFunc ( vertColoursAttrIndex ) ;
GL_VertexAttribPointerFunc ( vertColoursAttrIndex , 4 , GL_FLOAT , GL_FALSE , sizeof ( iqmvert_t ) , pose - > rgba ) ;
}
break ;
2017-09-17 02:12:53 +00:00
}
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
2023-07-07 09:57:40 +00:00
# define MyVectorScale(a,s,b) do{(b)[0]=(s)*(a)[0];(b)[1]=(s)*(a)[1];(b)[2]=(s)*(a)[2];}while(0)
if ( e - > netstate . colormap > 0 & & e - > netstate . colormap < = cl . maxclients )
{
scoreboard_t * sb = & cl . scores [ e - > netstate . colormap - 1 ] ;
byte * pal ;
pal = CL_PLColours_ToRGB ( & sb - > pants ) ;
MyVectorScale ( pal , 1.0 / 255 , tints [ 0 ] ) ;
pal = CL_PLColours_ToRGB ( & sb - > shirt ) ;
MyVectorScale ( pal , 1.0 / 255 , tints [ 1 ] ) ;
}
else
{
MyVectorScale ( ( byte * ) & d_8to24table [ BOTTOM_RANGE + 15 ] , 1.0 / 255 , tints [ 0 ] ) ;
MyVectorScale ( ( byte * ) & d_8to24table [ TOP_RANGE + 15 ] , 1.0 / 255 , tints [ 1 ] ) ;
}
tints [ 0 ] [ 3 ] = 1 ;
tints [ 1 ] [ 3 ] = 1 ;
MyVectorScale ( e - > netstate . glowmod , 1.0 / 32 , tints [ 2 ] ) ; tints [ 2 ] [ 3 ] = 1 ;
// set textures
GL_SelectTexture ( GL_TEXTURE0 ) ;
GL_Bind ( tex . base ) ;
if ( tex . luma )
{
GL_SelectTexture ( GL_TEXTURE1 ) ;
GL_Bind ( tex . luma ) ;
}
else
tints [ 2 ] [ 0 ] = tints [ 2 ] [ 1 ] = tints [ 2 ] [ 2 ] = tints [ 2 ] [ 3 ] = 0 ;
if ( tex . lower )
{
GL_SelectTexture ( GL_TEXTURE2 ) ;
GL_Bind ( tex . lower ) ;
}
else
tints [ 0 ] [ 0 ] = tints [ 0 ] [ 1 ] = tints [ 0 ] [ 2 ] = tints [ 0 ] [ 3 ] = 0 ; //ask the glsl to not read it
if ( tex . upper )
{
GL_SelectTexture ( GL_TEXTURE3 ) ;
GL_Bind ( tex . upper ) ;
}
else
tints [ 1 ] [ 0 ] = tints [ 1 ] [ 1 ] = tints [ 1 ] [ 2 ] = tints [ 1 ] [ 3 ] = 0 ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
// set uniforms
2019-11-02 15:50:53 +00:00
if ( glsl - > blendLoc ! = - 1 )
GL_Uniform1fFunc ( glsl - > blendLoc , blend ) ;
if ( glsl - > bonesLoc ! = - 1 )
GL_Uniform4fvFunc ( glsl - > bonesLoc , paliashdr - > numbones * 3 , lerpdata . bonestate - > mat ) ;
GL_Uniform3fFunc ( glsl - > shadevectorLoc , shadevector [ 0 ] , shadevector [ 1 ] , shadevector [ 2 ] ) ;
2023-07-07 09:57:40 +00:00
GL_Uniform4fFunc ( glsl - > lightColorLoc , lightcolor [ 0 ] , lightcolor [ 1 ] , lightcolor [ 2 ] , entalpha ) ; //this includes colormod
GL_Uniform1iFunc ( glsl - > useFullbrightTexLoc , ( tex . luma ! = NULL ) ? 1 : 0 ) ;
2019-11-02 15:50:53 +00:00
GL_Uniform1fFunc ( glsl - > useOverbrightLoc , overbright ? 1 : 0 ) ;
GL_Uniform1iFunc ( glsl - > useAlphaTestLoc , ( currententity - > model - > flags & MF_HOLEY ) ? 1 : 0 ) ;
2023-07-07 09:57:40 +00:00
GL_Uniform4fvFunc ( glsl - > colorTintLoc , countof ( tints ) , tints [ 0 ] ) ; //colourmapping and glowmod.
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
// draw
2017-09-17 02:12:53 +00:00
glDrawElements ( GL_TRIANGLES , paliashdr - > numindexes , GL_UNSIGNED_SHORT , currententity - > model - > meshindexesvboptr + paliashdr - > eboofs ) ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
// clean up
GL_DisableVertexAttribArrayFunc ( texCoordsAttrIndex ) ;
GL_DisableVertexAttribArrayFunc ( pose1VertexAttrIndex ) ;
GL_DisableVertexAttribArrayFunc ( pose2VertexAttrIndex ) ;
GL_DisableVertexAttribArrayFunc ( pose1NormalAttrIndex ) ;
GL_DisableVertexAttribArrayFunc ( pose2NormalAttrIndex ) ;
2019-11-02 15:50:53 +00:00
GL_DisableVertexAttribArrayFunc ( vertColoursAttrIndex ) ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
GL_UseProgramFunc ( 0 ) ;
GL_SelectTexture ( GL_TEXTURE0 ) ;
rs_aliaspasses + = paliashdr - > numtris ;
}
2010-02-15 23:26:55 +00:00
/*
= = = = = = = = = = = = =
2017-09-17 02:12:53 +00:00
GL_DrawAliasFrame
- - johnfitz - - rewritten to support colored light , lerping , entalpha , multitexture , and r_drawflat
- - spike - - rewritten to use vertex arrays , which should be slightly faster thanks to less branches + gl calls ( note that this requires gl1 .1 , which we depend on anyway for texture objects , and is pretty much universal .
2010-02-15 23:26:55 +00:00
= = = = = = = = = = = = =
*/
void GL_DrawAliasFrame ( aliashdr_t * paliashdr , lerpdata_t lerpdata )
{
2017-09-17 02:12:53 +00:00
static vec3_t vpos [ 65536 ] ;
static vec4_t vc [ 65536 ] ;
int i ;
2010-02-15 23:26:55 +00:00
float blend , iblend ;
2019-11-02 15:50:53 +00:00
const float * texcoords = ( const float * ) ( currententity - > model - > meshvboptr + paliashdr - > vbostofs ) ;
int texcoordstride = 0 ;
2010-02-15 23:26:55 +00:00
if ( lerpdata . pose1 ! = lerpdata . pose2 )
{
blend = lerpdata . blend ;
2017-09-17 02:12:53 +00:00
iblend = 1.0 - blend ;
2010-02-15 23:26:55 +00:00
}
else // poses the same means either 1. the entity has paused its animation, or 2. r_lerpmodels is disabled
{
2017-09-17 02:12:53 +00:00
blend = 1 ;
iblend = 0 ;
2010-02-15 23:26:55 +00:00
}
2017-09-17 02:12:53 +00:00
//pose1*iblend + pose2*blend
2010-02-15 23:26:55 +00:00
2017-09-17 02:12:53 +00:00
if ( shading & & r_drawflat_cheatsafe )
2010-02-15 23:26:55 +00:00
{
2017-09-17 02:12:53 +00:00
shading = false ;
glColor4f ( rand ( ) % 256 / 255.0 , rand ( ) % 256 / 255.0 , rand ( ) % 256 / 255.0 , entalpha ) ;
}
2010-02-15 23:26:55 +00:00
2017-09-17 02:12:53 +00:00
glEnableClientState ( GL_VERTEX_ARRAY ) ;
2019-01-30 01:54:49 +00:00
switch ( paliashdr - > poseverttype )
2017-09-17 02:12:53 +00:00
{
2019-01-30 01:54:49 +00:00
case PV_QUAKE1 :
case PV_QUAKEFORGE : //just going to ignore the extra data here.
2010-02-15 23:26:55 +00:00
{
2019-01-30 01:54:49 +00:00
trivertx_t * verts1 = ( trivertx_t * ) ( ( byte * ) paliashdr + paliashdr - > vertexes ) + lerpdata . pose1 * paliashdr - > numverts_vbo * ( paliashdr - > poseverttype = = PV_QUAKEFORGE ? 2 : 1 ) ;
trivertx_t * verts2 = ( trivertx_t * ) ( ( byte * ) paliashdr + paliashdr - > vertexes ) + lerpdata . pose2 * paliashdr - > numverts_vbo * ( paliashdr - > poseverttype = = PV_QUAKEFORGE ? 2 : 1 ) ;
2010-02-15 23:26:55 +00:00
2019-01-30 01:54:49 +00:00
if ( iblend )
2010-02-15 23:26:55 +00:00
{
2017-09-17 02:12:53 +00:00
for ( i = 0 ; i < paliashdr - > numverts_vbo ; i + + )
2010-02-15 23:26:55 +00:00
{
2019-01-30 01:54:49 +00:00
vpos [ i ] [ 0 ] = verts1 [ i ] . v [ 0 ] * iblend + blend * verts2 [ i ] . v [ 0 ] ;
vpos [ i ] [ 1 ] = verts1 [ i ] . v [ 1 ] * iblend + blend * verts2 [ i ] . v [ 1 ] ;
vpos [ i ] [ 2 ] = verts1 [ i ] . v [ 2 ] * iblend + blend * verts2 [ i ] . v [ 2 ] ;
}
GL_BindBuffer ( GL_ARRAY_BUFFER , 0 ) ;
glVertexPointer ( 3 , GL_FLOAT , sizeof ( vpos [ 0 ] ) , vpos ) ;
if ( shading )
{
for ( i = 0 ; i < paliashdr - > numverts_vbo ; i + + )
{
vc [ i ] [ 0 ] = ( shadedots [ verts1 - > lightnormalindex ] * iblend + shadedots [ verts2 - > lightnormalindex ] * blend ) * lightcolor [ 0 ] ;
vc [ i ] [ 1 ] = ( shadedots [ verts1 - > lightnormalindex ] * iblend + shadedots [ verts2 - > lightnormalindex ] * blend ) * lightcolor [ 1 ] ;
vc [ i ] [ 2 ] = ( shadedots [ verts1 - > lightnormalindex ] * iblend + shadedots [ verts2 - > lightnormalindex ] * blend ) * lightcolor [ 2 ] ;
vc [ i ] [ 3 ] = entalpha ;
}
glEnableClientState ( GL_COLOR_ARRAY ) ;
glColorPointer ( 4 , GL_FLOAT , sizeof ( * vc ) , vc ) ;
2010-02-15 23:26:55 +00:00
}
2017-09-17 02:12:53 +00:00
}
2019-01-30 01:54:49 +00:00
else
2017-09-17 02:12:53 +00:00
{
2019-01-30 01:54:49 +00:00
if ( shading )
{
for ( i = 0 ; i < paliashdr - > numverts_vbo ; i + + )
{
vc [ i ] [ 0 ] = shadedots [ verts2 - > lightnormalindex ] * lightcolor [ 0 ] ;
vc [ i ] [ 1 ] = shadedots [ verts2 - > lightnormalindex ] * lightcolor [ 1 ] ;
vc [ i ] [ 2 ] = shadedots [ verts2 - > lightnormalindex ] * lightcolor [ 2 ] ;
vc [ i ] [ 3 ] = entalpha ;
}
glEnableClientState ( GL_COLOR_ARRAY ) ;
GL_BindBuffer ( GL_ARRAY_BUFFER , 0 ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , vc ) ;
}
//glVertexPointer may not take GL_UNSIGNED_BYTE, which means we can't use our vbos. attribute 0 MAY be vertex coords, but I don't want to depend on that.
2017-09-17 02:12:53 +00:00
for ( i = 0 ; i < paliashdr - > numverts_vbo ; i + + )
2010-02-15 23:26:55 +00:00
{
2019-01-30 01:54:49 +00:00
vpos [ i ] [ 0 ] = verts2 [ i ] . v [ 0 ] ;
vpos [ i ] [ 1 ] = verts2 [ i ] . v [ 1 ] ;
vpos [ i ] [ 2 ] = verts2 [ i ] . v [ 2 ] ;
2010-02-15 23:26:55 +00:00
}
2017-09-17 02:12:53 +00:00
GL_BindBuffer ( GL_ARRAY_BUFFER , 0 ) ;
2019-01-30 01:54:49 +00:00
glVertexPointer ( 3 , GL_FLOAT , sizeof ( vpos [ 0 ] ) , vpos ) ;
2010-02-15 23:26:55 +00:00
}
2017-09-17 02:12:53 +00:00
}
2019-01-30 01:54:49 +00:00
break ;
case PV_QUAKE3 :
2017-09-17 02:12:53 +00:00
{
2019-01-30 01:54:49 +00:00
md3XyzNormal_t * verts1 = ( md3XyzNormal_t * ) ( ( byte * ) paliashdr + paliashdr - > vertexes ) + lerpdata . pose1 * paliashdr - > numverts_vbo ;
md3XyzNormal_t * verts2 = ( md3XyzNormal_t * ) ( ( byte * ) paliashdr + paliashdr - > vertexes ) + lerpdata . pose2 * paliashdr - > numverts_vbo ;
2017-09-17 02:12:53 +00:00
2019-01-30 01:54:49 +00:00
if ( iblend )
2017-09-17 02:12:53 +00:00
{
for ( i = 0 ; i < paliashdr - > numverts_vbo ; i + + )
{
2019-01-30 01:54:49 +00:00
vpos [ i ] [ 0 ] = verts1 [ i ] . xyz [ 0 ] * iblend + blend * verts2 [ i ] . xyz [ 0 ] ;
vpos [ i ] [ 1 ] = verts1 [ i ] . xyz [ 1 ] * iblend + blend * verts2 [ i ] . xyz [ 1 ] ;
vpos [ i ] [ 2 ] = verts1 [ i ] . xyz [ 2 ] * iblend + blend * verts2 [ i ] . xyz [ 2 ] ;
}
GL_BindBuffer ( GL_ARRAY_BUFFER , 0 ) ;
glVertexPointer ( 3 , GL_FLOAT , sizeof ( vpos [ 0 ] ) , vpos ) ;
if ( shading )
{
for ( i = 0 ; i < paliashdr - > numverts_vbo ; i + + )
{
vec3_t n ;
float dot ;
// map the normal coordinates in [-1..1] to [-127..127] and store in an unsigned char.
// this introduces some error (less than 0.004), but the normals were very coarse
// to begin with
//this should be a table.
float lat = ( float ) verts2 [ i ] . latlong [ 0 ] * ( 2 * M_PI ) * ( 1.0 / 255.0 ) ;
float lng = ( float ) verts2 [ i ] . latlong [ 1 ] * ( 2 * M_PI ) * ( 1.0 / 255.0 ) ;
n [ 0 ] = blend * cos ( lng ) * sin ( lat ) ;
n [ 1 ] = blend * sin ( lng ) * sin ( lat ) ;
n [ 2 ] = blend * cos ( lat ) ;
lat = ( float ) verts1 [ i ] . latlong [ 0 ] * ( 2 * M_PI ) * ( 1.0 / 255.0 ) ;
lng = ( float ) verts1 [ i ] . latlong [ 1 ] * ( 2 * M_PI ) * ( 1.0 / 255.0 ) ;
n [ 0 ] + = iblend * cos ( lng ) * sin ( lat ) ;
n [ 1 ] + = iblend * sin ( lng ) * sin ( lat ) ;
n [ 2 ] + = iblend * cos ( lat ) ;
dot = DotProduct ( n , shadevector ) ;
if ( dot < 0.0 ) //bizzare maths guessed by mh
dot = 1.0 + dot * ( 13.0 / 44.0 ) ;
else
dot = 1.0 + dot ;
vc [ i ] [ 0 ] = dot * lightcolor [ 0 ] ;
vc [ i ] [ 1 ] = dot * lightcolor [ 1 ] ;
vc [ i ] [ 2 ] = dot * lightcolor [ 2 ] ;
vc [ i ] [ 3 ] = entalpha ;
}
glEnableClientState ( GL_COLOR_ARRAY ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , vc ) ;
2017-09-17 02:12:53 +00:00
}
}
2019-01-30 01:54:49 +00:00
else
2010-02-15 23:26:55 +00:00
{
2019-01-30 01:54:49 +00:00
if ( shading )
2017-09-17 02:12:53 +00:00
{
2019-01-30 01:54:49 +00:00
for ( i = 0 ; i < paliashdr - > numverts_vbo ; i + + )
{
vec3_t n ;
float dot ;
// map the normal coordinates in [-1..1] to [-127..127] and store in an unsigned char.
// this introduces some error (less than 0.004), but the normals were very coarse
// to begin with
//this should be a table.
float lat = ( float ) verts2 [ i ] . latlong [ 0 ] * ( 2 * M_PI ) * ( 1.0 / 255.0 ) ;
float lng = ( float ) verts2 [ i ] . latlong [ 1 ] * ( 2 * M_PI ) * ( 1.0 / 255.0 ) ;
n [ 0 ] = cos ( lng ) * sin ( lat ) ;
n [ 1 ] = sin ( lng ) * sin ( lat ) ;
n [ 2 ] = cos ( lat ) ;
dot = DotProduct ( n , shadevector ) ;
if ( dot < 0.0 ) //bizzare maths guessed by mh
dot = 1.0 + dot * ( 13.0 / 44.0 ) ;
else
dot = 1.0 + dot ;
vc [ i ] [ 0 ] = dot * lightcolor [ 0 ] ;
vc [ i ] [ 1 ] = dot * lightcolor [ 1 ] ;
vc [ i ] [ 2 ] = dot * lightcolor [ 2 ] ;
vc [ i ] [ 3 ] = entalpha ;
}
glEnableClientState ( GL_COLOR_ARRAY ) ;
GL_BindBuffer ( GL_ARRAY_BUFFER , 0 ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , vc ) ;
2017-09-17 02:12:53 +00:00
}
2019-01-30 01:54:49 +00:00
GL_BindBuffer ( GL_ARRAY_BUFFER , currententity - > model - > meshvbo ) ;
glVertexPointer ( 3 , GL_SHORT , sizeof ( meshxyz_md3_t ) , GLARB_GetXYZOffset_MD3 ( paliashdr , lerpdata . pose2 ) ) ;
2010-02-15 23:26:55 +00:00
}
2017-09-17 02:12:53 +00:00
}
2019-01-30 01:54:49 +00:00
break ;
2019-11-02 15:50:53 +00:00
case PV_IQM :
{ //iqm does its blending using bones instead of verts, so we only have to care about one pose here
int morphpose = 0 ;
const iqmvert_t * verts2 = ( const iqmvert_t * ) ( ( byte * ) paliashdr + paliashdr - > vertexes ) + morphpose * paliashdr - > numverts_vbo ;
const iqmvert_t * vboverts2 = ( const iqmvert_t * ) ( currententity - > model - > meshvboptr + paliashdr - > vbovertofs ) + ( paliashdr - > numverts_vbo * morphpose ) ;
if ( shading )
{
for ( i = 0 ; i < paliashdr - > numverts_vbo ; i + + )
{
float dot ;
dot = DotProduct ( verts2 [ i ] . norm , shadevector ) ; //NOTE: ignores animated normals
if ( dot < 0.0 ) //bizzare maths guessed by mh
dot = 1.0 + dot * ( 13.0 / 44.0 ) ;
else
dot = 1.0 + dot ;
vc [ i ] [ 0 ] = dot * lightcolor [ 0 ] * verts2 [ i ] . rgba [ 0 ] ;
vc [ i ] [ 1 ] = dot * lightcolor [ 1 ] * verts2 [ i ] . rgba [ 1 ] ;
vc [ i ] [ 2 ] = dot * lightcolor [ 2 ] * verts2 [ i ] . rgba [ 2 ] ;
vc [ i ] [ 3 ] = entalpha * verts2 [ i ] . rgba [ 3 ] ;
}
glEnableClientState ( GL_COLOR_ARRAY ) ;
GL_BindBuffer ( GL_ARRAY_BUFFER , 0 ) ;
glColorPointer ( 4 , GL_FLOAT , 0 , vc ) ;
}
if ( lerpdata . bonestate )
{ //oh dear. its animated. and we don't have any glsl to animate it for us.
bonepose_t pose ;
const bonepose_t * in ;
const float * xyz ;
float w ;
int j , k ;
for ( i = 0 ; i < paliashdr - > numverts_vbo ; i + + )
{
//lerp the matrix... this is less of a nightmare in glsl...
in = lerpdata . bonestate + verts2 [ i ] . idx [ 0 ] ;
w = verts2 [ i ] . weight [ 0 ] ;
for ( j = 0 ; j < 12 ; j + + )
pose . mat [ j ] = in - > mat [ j ] * w ;
for ( k = 1 ; k < 3 ; k + + )
{
w = verts2 [ i ] . weight [ k ] ;
if ( ! w )
continue ;
in = lerpdata . bonestate + verts2 [ i ] . idx [ k ] ;
for ( j = 0 ; j < 12 ; j + + )
pose . mat [ j ] + = in - > mat [ j ] * w ;
}
xyz = verts2 [ i ] . xyz ;
vpos [ i ] [ 0 ] = xyz [ 0 ] * pose . mat [ 0 ] + xyz [ 1 ] * pose . mat [ 1 ] + xyz [ 2 ] * pose . mat [ 2 ] + pose . mat [ 3 ] ;
vpos [ i ] [ 1 ] = xyz [ 0 ] * pose . mat [ 4 ] + xyz [ 1 ] * pose . mat [ 5 ] + xyz [ 2 ] * pose . mat [ 6 ] + pose . mat [ 7 ] ;
vpos [ i ] [ 2 ] = xyz [ 0 ] * pose . mat [ 8 ] + xyz [ 1 ] * pose . mat [ 9 ] + xyz [ 2 ] * pose . mat [ 10 ] + pose . mat [ 11 ] ;
}
GL_BindBuffer ( GL_ARRAY_BUFFER , 0 ) ;
glVertexPointer ( 3 , GL_FLOAT , 0 , vpos ) ;
}
else
{
GL_BindBuffer ( GL_ARRAY_BUFFER , currententity - > model - > meshvbo ) ;
glVertexPointer ( 3 , GL_FLOAT , sizeof ( iqmvert_t ) , vboverts2 - > xyz ) ;
}
texcoordstride = sizeof ( iqmvert_t ) ;
texcoords = vboverts2 - > st ;
}
break ;
2017-09-17 02:12:53 +00:00
}
// set textures
GL_BindBuffer ( GL_ARRAY_BUFFER , currententity - > model - > meshvbo ) ;
if ( mtexenabled )
{
GL_ClientActiveTextureFunc ( GL_TEXTURE0 ) ;
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2019-11-02 15:50:53 +00:00
glTexCoordPointer ( 2 , GL_FLOAT , texcoordstride , texcoords ) ;
2010-02-15 23:26:55 +00:00
2017-09-17 02:12:53 +00:00
GL_ClientActiveTextureFunc ( GL_TEXTURE1 ) ;
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2019-11-02 15:50:53 +00:00
glTexCoordPointer ( 2 , GL_FLOAT , texcoordstride , texcoords ) ;
2010-02-15 23:26:55 +00:00
}
2017-09-17 02:12:53 +00:00
else
{
glEnableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
2019-11-02 15:50:53 +00:00
glTexCoordPointer ( 2 , GL_FLOAT , texcoordstride , texcoords ) ;
2017-09-17 02:12:53 +00:00
}
// draw
GL_BindBuffer ( GL_ELEMENT_ARRAY_BUFFER , currententity - > model - > meshindexesvbo ) ;
glDrawElements ( GL_TRIANGLES , paliashdr - > numindexes , GL_UNSIGNED_SHORT , currententity - > model - > meshindexesvboptr + paliashdr - > eboofs ) ;
GL_BindBuffer ( GL_ELEMENT_ARRAY_BUFFER , 0 ) ;
GL_BindBuffer ( GL_ARRAY_BUFFER , 0 ) ;
// clean up
if ( mtexenabled )
{
glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
GL_ClientActiveTextureFunc ( GL_TEXTURE0 ) ;
}
glDisableClientState ( GL_TEXTURE_COORD_ARRAY ) ;
glDisableClientState ( GL_VERTEX_ARRAY ) ;
glDisableClientState ( GL_COLOR_ARRAY ) ;
2010-02-15 23:26:55 +00:00
rs_aliaspasses + = paliashdr - > numtris ;
}
/*
= = = = = = = = = = = = = = = = =
R_SetupAliasFrame - - johnfitz - - rewritten to support lerping
= = = = = = = = = = = = = = = = =
*/
2020-07-23 19:28:19 +00:00
void R_SetupAliasFrame ( aliashdr_t * paliashdr , entity_t * e , lerpdata_t * lerpdata )
2010-02-15 23:26:55 +00:00
{
2020-07-23 19:28:19 +00:00
int frame = e - > frame ;
2010-02-15 23:26:55 +00:00
int posenum , numposes ;
if ( ( frame > = paliashdr - > numframes ) | | ( frame < 0 ) )
{
2015-08-02 18:21:57 +00:00
Con_DPrintf ( " R_AliasSetupFrame: no such frame %d for '%s' \n " , frame , e - > model - > name ) ;
2010-02-15 23:26:55 +00:00
frame = 0 ;
}
2020-07-23 19:28:19 +00:00
if ( e - > lerpflags & LERP_EXPLICIT )
2010-02-15 23:26:55 +00:00
{
2020-07-23 19:28:19 +00:00
int frame2 = e - > lerp . snap . frame2 ;
float frac = e - > lerp . snap . lerpfrac ;
float time = cl . time ;
2010-02-15 23:26:55 +00:00
2020-07-23 19:28:19 +00:00
if ( ( frame2 > = paliashdr - > numframes ) | | ( frame2 < 0 ) )
frame2 = 0 ;
if ( paliashdr - > frames [ ( frac > 0.5 ) ? frame2 : frame ] . numposes > 1 )
{ //our stronger sequence is a framegroup, but we can only do two-way blends.
if ( frac > 0.5 )
{
frame = frame2 ;
time = e - > lerp . snap . time [ 1 ] ;
}
else
time = e - > lerp . snap . time [ 0 ] ;
if ( time < 0 )
time = 0 ; //just in case...
frac = ( time / paliashdr - > frames [ frame ] . interval ) ;
posenum = ( int ) frac ;
lerpdata - > blend = ( frac - posenum ) ;
posenum + = paliashdr - > frames [ frame ] . firstpose ;
numposes = paliashdr - > frames [ frame ] . numposes ;
lerpdata - > pose1 = ( posenum ) % numposes ;
lerpdata - > pose2 = ( posenum + 1 ) % numposes ;
}
else
{
lerpdata - > blend = frac ;
lerpdata - > pose1 = paliashdr - > frames [ frame ] . firstpose ;
lerpdata - > pose1 + = ( unsigned int ) ( e - > lerp . snap . time [ 0 ] / paliashdr - > frames [ frame ] . interval ) % paliashdr - > frames [ frame ] . numposes ;
lerpdata - > pose2 = paliashdr - > frames [ frame2 ] . firstpose ;
lerpdata - > pose2 + = ( unsigned int ) ( e - > lerp . snap . time [ 1 ] / paliashdr - > frames [ frame2 ] . interval ) % paliashdr - > frames [ frame ] . numposes ;
}
2010-02-15 23:26:55 +00:00
}
2020-07-23 19:28:19 +00:00
else
2010-02-15 23:26:55 +00:00
{
2020-07-23 19:28:19 +00:00
posenum = paliashdr - > frames [ frame ] . firstpose ;
numposes = paliashdr - > frames [ frame ] . numposes ;
if ( numposes > 1 )
2010-02-15 23:26:55 +00:00
{
2020-07-23 19:28:19 +00:00
float time = cl . time + e - > syncbase ; //Spike: Readded syncbase
if ( time < 0 )
time = 0 ; //just in case...
e - > lerp . state . lerptime = paliashdr - > frames [ frame ] . interval ; //FIXME: no per-frame intervals
posenum + = ( int ) ( time / e - > lerp . state . lerptime ) % numposes ;
2010-02-15 23:26:55 +00:00
}
else
2020-07-23 19:28:19 +00:00
e - > lerp . state . lerptime = 0.1 ;
if ( e - > lerpflags & LERP_RESETANIM ) //kill any lerp in progress
2010-02-15 23:26:55 +00:00
{
2020-07-23 19:28:19 +00:00
e - > lerp . state . lerpstart = 0 ;
e - > lerp . state . previouspose = posenum ;
e - > lerp . state . currentpose = posenum ;
e - > lerpflags - = LERP_RESETANIM ;
}
else if ( e - > lerp . state . currentpose ! = posenum ) // pose changed, start new lerp
{
if ( e - > lerpflags & LERP_RESETANIM2 ) //defer lerping one more time
{
e - > lerp . state . lerpstart = 0 ;
e - > lerp . state . previouspose = posenum ;
e - > lerp . state . currentpose = posenum ;
e - > lerpflags - = LERP_RESETANIM2 ;
}
else
{
e - > lerp . state . lerpstart = cl . time ;
e - > lerp . state . previouspose = e - > lerp . state . currentpose ;
e - > lerp . state . currentpose = posenum ;
}
2010-02-15 23:26:55 +00:00
}
2020-07-23 19:28:19 +00:00
//set up values
if ( r_lerpmodels . value & & ! ( e - > model - > flags & MOD_NOLERP & & r_lerpmodels . value ! = 2 ) )
{
if ( e - > lerpflags & LERP_FINISH & & numposes = = 1 )
2022-07-15 13:11:03 +00:00
lerpdata - > blend = CLAMP ( 0.0f , ( float ) ( cl . time - e - > lerp . state . lerpstart ) / ( e - > lerpfinish - e - > lerp . state . lerpstart ) , 1.0f ) ;
2020-07-23 19:28:19 +00:00
else
2022-07-15 13:11:03 +00:00
lerpdata - > blend = CLAMP ( 0.0f , ( float ) ( cl . time - e - > lerp . state . lerpstart ) / e - > lerp . state . lerptime , 1.0f ) ;
2020-07-23 19:28:19 +00:00
lerpdata - > pose1 = e - > lerp . state . previouspose ;
lerpdata - > pose2 = e - > lerp . state . currentpose ;
}
else //don't lerp
{
lerpdata - > blend = 1 ;
lerpdata - > pose1 = posenum ;
lerpdata - > pose2 = posenum ;
}
2010-02-15 23:26:55 +00:00
}
2019-11-02 15:50:53 +00:00
if ( paliashdr - > numboneposes )
{
static bonepose_t inverted [ 256 ] ;
bonepose_t lerpbones [ 256 ] , l ;
int b , j ;
const boneinfo_t * bi = ( const boneinfo_t * ) ( ( byte * ) paliashdr + paliashdr - > boneinfo ) ;
const bonepose_t * p1 = ( const bonepose_t * ) ( ( byte * ) paliashdr + paliashdr - > boneposedata ) + lerpdata - > pose1 * paliashdr - > numbones ;
const bonepose_t * p2 = ( const bonepose_t * ) ( ( byte * ) paliashdr + paliashdr - > boneposedata ) + lerpdata - > pose2 * paliashdr - > numbones ;
float w2 = lerpdata - > blend ;
float w1 = 1 - w2 ;
for ( b = 0 ; b < paliashdr - > numbones ; b + + , p1 + + , p2 + + )
{
//interpolate it
for ( j = 0 ; j < 12 ; j + + )
l . mat [ j ] = p1 - > mat [ j ] * w1 + p2 - > mat [ j ] * w2 ;
//concat it onto the parent (relative->abs)
if ( bi [ b ] . parent < 0 )
memcpy ( lerpbones [ b ] . mat , l . mat , sizeof ( l . mat ) ) ;
else
R_ConcatTransforms ( ( void * ) lerpbones [ bi [ b ] . parent ] . mat , ( void * ) l . mat , ( void * ) lerpbones [ b ] . mat ) ;
//and finally invert it
R_ConcatTransforms ( ( void * ) lerpbones [ b ] . mat , ( void * ) bi [ b ] . inverse . mat , ( void * ) inverted [ b ] . mat ) ;
}
lerpdata - > bonestate = inverted ; //and now we can use it.
}
else
lerpdata - > bonestate = NULL ;
2010-02-15 23:26:55 +00:00
}
/*
= = = = = = = = = = = = = = = = =
R_SetupEntityTransform - - johnfitz - - set up transform part of lerpdata
= = = = = = = = = = = = = = = = =
*/
void R_SetupEntityTransform ( entity_t * e , lerpdata_t * lerpdata )
{
float blend ;
vec3_t d ;
int i ;
// if LERP_RESETMOVE, kill any lerps in progress
if ( e - > lerpflags & LERP_RESETMOVE )
{
e - > movelerpstart = 0 ;
VectorCopy ( e - > origin , e - > previousorigin ) ;
VectorCopy ( e - > origin , e - > currentorigin ) ;
VectorCopy ( e - > angles , e - > previousangles ) ;
VectorCopy ( e - > angles , e - > currentangles ) ;
e - > lerpflags - = LERP_RESETMOVE ;
}
else if ( ! VectorCompare ( e - > origin , e - > currentorigin ) | | ! VectorCompare ( e - > angles , e - > currentangles ) ) // origin/angles changed, start new lerp
{
e - > movelerpstart = cl . time ;
VectorCopy ( e - > currentorigin , e - > previousorigin ) ;
VectorCopy ( e - > origin , e - > currentorigin ) ;
VectorCopy ( e - > currentangles , e - > previousangles ) ;
VectorCopy ( e - > angles , e - > currentangles ) ;
}
//set up values
if ( r_lerpmove . value & & e ! = & cl . viewent & & e - > lerpflags & LERP_MOVESTEP )
{
if ( e - > lerpflags & LERP_FINISH )
2022-06-12 11:32:28 +00:00
blend = CLAMP ( 0.0f , ( float ) ( cl . time - e - > movelerpstart ) / ( e - > lerpfinish - e - > movelerpstart ) , 1.0f ) ;
2010-02-15 23:26:55 +00:00
else
2022-06-12 11:32:28 +00:00
blend = CLAMP ( 0.0f , ( float ) ( cl . time - e - > movelerpstart ) / 0.1f , 1.0f ) ;
2010-02-15 23:26:55 +00:00
//translation
VectorSubtract ( e - > currentorigin , e - > previousorigin , d ) ;
lerpdata - > origin [ 0 ] = e - > previousorigin [ 0 ] + d [ 0 ] * blend ;
lerpdata - > origin [ 1 ] = e - > previousorigin [ 1 ] + d [ 1 ] * blend ;
lerpdata - > origin [ 2 ] = e - > previousorigin [ 2 ] + d [ 2 ] * blend ;
//rotation
VectorSubtract ( e - > currentangles , e - > previousangles , d ) ;
for ( i = 0 ; i < 3 ; i + + )
{
if ( d [ i ] > 180 ) d [ i ] - = 360 ;
if ( d [ i ] < - 180 ) d [ i ] + = 360 ;
}
lerpdata - > angles [ 0 ] = e - > previousangles [ 0 ] + d [ 0 ] * blend ;
lerpdata - > angles [ 1 ] = e - > previousangles [ 1 ] + d [ 1 ] * blend ;
lerpdata - > angles [ 2 ] = e - > previousangles [ 2 ] + d [ 2 ] * blend ;
}
else //don't lerp
{
VectorCopy ( e - > origin , lerpdata - > origin ) ;
VectorCopy ( e - > angles , lerpdata - > angles ) ;
}
}
/*
= = = = = = = = = = = = = = = = =
R_SetupAliasLighting - - johnfitz - - broken out from R_DrawAliasModel and rewritten
= = = = = = = = = = = = = = = = =
*/
void R_SetupAliasLighting ( entity_t * e )
{
vec3_t dist ;
float add ;
int i ;
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
int quantizedangle ;
float radiansangle ;
2021-10-14 05:49:15 +00:00
float * origin ;
2010-02-15 23:26:55 +00:00
2020-07-02 19:05:51 +00:00
if ( ! r_refdef . drawworld )
lightcolor [ 0 ] = lightcolor [ 1 ] = lightcolor [ 2 ] = 255 ;
else
2010-02-15 23:26:55 +00:00
{
2020-07-02 19:05:51 +00:00
if ( e - > eflags & EFLAGS_VIEWMODEL )
2010-02-15 23:26:55 +00:00
{
2020-07-02 19:05:51 +00:00
origin = r_refdef . vieworg ;
2021-10-14 05:49:15 +00:00
R_LightPoint ( origin ) ;
}
else
{
origin = e - > origin ;
2023-03-18 11:14:40 +00:00
// if the initial trace is completely black, try again from above
// this helps with models whose origin is slightly below ground level
// (e.g. some of the candles in the DOTM start map)
if ( ! R_LightPoint ( origin ) )
{
vec3_t lpos ;
VectorCopy ( origin , lpos ) ;
2021-10-14 05:49:15 +00:00
lpos [ 2 ] + = e - > model - > maxs [ 2 ] * 0.5f ;
2023-03-18 11:14:40 +00:00
R_LightPoint ( lpos ) ;
}
2010-02-15 23:26:55 +00:00
}
2020-07-02 19:05:51 +00:00
//add dlights
for ( i = 0 ; i < MAX_DLIGHTS ; i + + )
2010-02-15 23:26:55 +00:00
{
2020-07-02 19:05:51 +00:00
if ( cl_dlights [ i ] . die > = cl . time )
{
VectorSubtract ( origin , cl_dlights [ i ] . origin , dist ) ;
add = cl_dlights [ i ] . radius - VectorLength ( dist ) ;
if ( add > 0 )
VectorMA ( lightcolor , add , cl_dlights [ i ] . color , lightcolor ) ;
}
2010-02-15 23:26:55 +00:00
}
2020-07-02 19:05:51 +00:00
// minimum light value on gun (24)
2023-07-24 07:08:14 +00:00
if ( e - > eflags & EFLAGS_VIEWMODEL )
2010-02-15 23:26:55 +00:00
{
2020-07-02 19:05:51 +00:00
add = 72.0f - ( lightcolor [ 0 ] + lightcolor [ 1 ] + lightcolor [ 2 ] ) ;
if ( add > 0.0f )
{
lightcolor [ 0 ] + = add / 3.0f ;
lightcolor [ 1 ] + = add / 3.0f ;
lightcolor [ 2 ] + = add / 3.0f ;
}
2010-02-15 23:26:55 +00:00
}
2020-07-02 19:05:51 +00:00
// minimum light value on players (8)
if ( e > cl . entities & & e < = cl . entities + cl . maxclients )
2010-02-15 23:26:55 +00:00
{
2020-07-02 19:05:51 +00:00
add = 24.0f - ( lightcolor [ 0 ] + lightcolor [ 1 ] + lightcolor [ 2 ] ) ;
if ( add > 0.0f )
{
lightcolor [ 0 ] + = add / 3.0f ;
lightcolor [ 1 ] + = add / 3.0f ;
lightcolor [ 2 ] + = add / 3.0f ;
}
2010-02-15 23:26:55 +00:00
}
}
// clamp lighting so it doesn't overbright as much (96)
if ( overbright )
{
add = 288.0f / ( lightcolor [ 0 ] + lightcolor [ 1 ] + lightcolor [ 2 ] ) ;
if ( add < 1.0f )
VectorScale ( lightcolor , add , lightcolor ) ;
}
//hack up the brightness when fullbrights but no overbrights (256)
if ( gl_fullbrights . value & & ! gl_overbright_models . value )
if ( e - > model - > flags & MOD_FBRIGHTHACK )
{
lightcolor [ 0 ] = 256.0f ;
lightcolor [ 1 ] = 256.0f ;
lightcolor [ 2 ] = 256.0f ;
}
Alias model rendering fast-path using OpenGL 2.
In GL_MakeAliasModelDisplayLists, after saving the standerd triangle strips and fans onto the hunk, if the system is GL2 capable, we also save a second version of the mdl on the hunk designed to be loaded into a VBO (GL_MakeAliasModelDisplayLists_VBO). In R_NewMap, and on video mode changes, we call GLMesh_LoadVertexBuffers which loops over all precached mdl's and loads the data into a pair of VBO's (vertices and vertex indices).
Finally, in R_DrawAliasModel, assuming no rendering options are disabling the fast-path (r_drawflat 1, r_lightmap 1, or r_fullbright 1 would disable it), we call GL_DrawAliasFrame_GLSL, which sets up all of the bindings and draws the (possibly lerped) mdl in one glDrawElements call.
Special thanks to MH for some of the code from RMQEngine and the general concept.
git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@1151 af15c1b1-3010-417e-b628-4374ebc0bcbd
2015-01-20 18:59:15 +00:00
quantizedangle = ( ( int ) ( e - > angles [ 1 ] * ( SHADEDOT_QUANT / 360.0 ) ) ) & ( SHADEDOT_QUANT - 1 ) ;
//ericw -- shadevector is passed to the shader to compute shadedots inside the
//shader, see GLAlias_CreateShaders()
radiansangle = ( quantizedangle / 16.0 ) * 2.0 * 3.14159 ;
shadevector [ 0 ] = cos ( - radiansangle ) ;
shadevector [ 1 ] = sin ( - radiansangle ) ;
shadevector [ 2 ] = 1 ;
VectorNormalize ( shadevector ) ;
//ericw --
shadedots = r_avertexnormal_dots [ quantizedangle ] ;
VectorScale ( lightcolor , 1.0f / 200.0f , lightcolor ) ;
2017-09-17 02:12:53 +00:00
lightcolor [ 0 ] * = e - > netstate . colormod [ 0 ] / 32.0 ;
lightcolor [ 1 ] * = e - > netstate . colormod [ 1 ] / 32.0 ;
lightcolor [ 2 ] * = e - > netstate . colormod [ 2 ] / 32.0 ;
2010-02-15 23:26:55 +00:00
}
/*
= = = = = = = = = = = = = = = = =
R_DrawAliasModel - - johnfitz - - almost completely rewritten
= = = = = = = = = = = = = = = = =
*/
void R_DrawAliasModel ( entity_t * e )
{
2019-11-02 15:50:53 +00:00
aliasglsl_t * glsl ;
2010-02-15 23:26:55 +00:00
aliashdr_t * paliashdr ;
2022-06-01 11:15:00 +00:00
int anim , skinnum ;
2023-07-07 09:57:40 +00:00
struct skintextures_s tex ;
2010-02-15 23:26:55 +00:00
lerpdata_t lerpdata ;
2017-08-04 19:45:11 +00:00
qboolean alphatest = ! ! ( e - > model - > flags & MF_HOLEY ) ;
2017-09-17 02:12:53 +00:00
int surf ;
2021-09-02 17:50:50 +00:00
float fovscale = 1.0f ;
2010-02-15 23:26:55 +00:00
//
// setup pose/lerp data -- do it first so we don't miss updates due to culling
//
paliashdr = ( aliashdr_t * ) Mod_Extradata ( e - > model ) ;
2020-07-23 19:28:19 +00:00
R_SetupAliasFrame ( paliashdr , e , & lerpdata ) ;
2010-02-15 23:26:55 +00:00
R_SetupEntityTransform ( e , & lerpdata ) ;
2021-09-05 15:41:35 +00:00
glsl = & r_alias_glsl [ ( paliashdr - > poseverttype = = PV_IQM & & lerpdata . bonestate ) ? ALIAS_GLSL_SKELETAL : ALIAS_GLSL_BASIC ] ;
2019-11-02 15:50:53 +00:00
2019-01-30 01:53:15 +00:00
if ( e - > eflags & EFLAGS_VIEWMODEL )
2017-09-17 02:12:53 +00:00
{
2023-07-24 07:08:14 +00:00
if ( skyroom_drawing )
return ; //no viewmodels inside skyrooms!
2017-09-17 02:12:53 +00:00
//transform it relative to the view, by rebuilding the modelview matrix without the view position.
glPushMatrix ( ) ;
glLoadIdentity ( ) ;
glRotatef ( - 90 , 1 , 0 , 0 ) ; // put Z going up
glRotatef ( 90 , 0 , 0 , 1 ) ; // put Z going up
2010-02-15 23:26:55 +00:00
2017-09-17 02:12:53 +00:00
glDepthRange ( 0 , 0.3 ) ;
2023-07-24 07:08:14 +00:00
//FIXME: this needs to go. combine with depthrange and explicit viewmodel-only fov into a different projection matrix..
if ( scr_fov . value > 90.f & & cl_gun_fovscale . value )
fovscale = tan ( scr_fov . value * ( 0.5f * M_PI / 180.f ) ) ;
2017-09-17 02:12:53 +00:00
}
else
{
//
// cull it
//
if ( R_CullModelForEntity ( e ) )
return ;
//
// transform it
//
glPushMatrix ( ) ;
}
2021-09-03 19:19:12 +00:00
2017-09-17 02:12:53 +00:00
R_RotateForEntity ( lerpdata . origin , lerpdata . angles , e - > netstate . scale ) ;
2021-09-02 17:50:50 +00:00
glTranslatef ( paliashdr - > scale_origin [ 0 ] , paliashdr - > scale_origin [ 1 ] * fovscale , paliashdr - > scale_origin [ 2 ] * fovscale ) ;
glScalef ( paliashdr - > scale [ 0 ] , paliashdr - > scale [ 1 ] * fovscale , paliashdr - > scale [ 2 ] * fovscale ) ;
2010-02-15 23:26:55 +00:00
//
// random stuff
//
if ( gl_smoothmodels . value & & ! r_drawflat_cheatsafe )
glShadeModel ( GL_SMOOTH ) ;
if ( gl_affinemodels . value )
glHint ( GL_PERSPECTIVE_CORRECTION_HINT , GL_FASTEST ) ;
overbright = gl_overbright_models . value ;
shading = true ;
//
// set up for alpha blending
//
if ( r_drawflat_cheatsafe | | r_lightmap_cheatsafe ) //no alpha in drawflat or lightmap mode
entalpha = 1 ;
else
entalpha = ENTALPHA_DECODE ( e - > alpha ) ;
if ( entalpha = = 0 )
goto cleanup ;
if ( entalpha < 1 )
{
if ( ! gl_texture_env_combine ) overbright = false ; //overbright can't be done in a single pass without combiners
glDepthMask ( GL_FALSE ) ;
glEnable ( GL_BLEND ) ;
}
2017-08-04 19:45:11 +00:00
else if ( alphatest )
glEnable ( GL_ALPHA_TEST ) ;
2023-11-02 23:45:50 +00:00
if ( e - > effects & EF_ADDITIVE )
{
glBlendFunc ( GL_SRC_ALPHA , GL_ONE ) ;
glEnable ( GL_BLEND ) ;
}
2010-02-15 23:26:55 +00:00
//
// set up lighting
//
R_SetupAliasLighting ( e ) ;
2017-09-17 02:12:53 +00:00
for ( surf = 0 ; ; surf + + )
2010-02-15 23:26:55 +00:00
{
2017-09-17 02:12:53 +00:00
rs_aliaspolys + = paliashdr - > numtris ;
//
// set up textures
//
GL_DisableMultitexture ( ) ;
anim = ( int ) ( cl . time * 10 ) & 3 ;
skinnum = e - > skinnum ;
if ( ( skinnum > = paliashdr - > numskins ) | | ( skinnum < 0 ) )
2010-02-15 23:26:55 +00:00
{
2017-09-17 02:12:53 +00:00
Con_DPrintf ( " R_DrawAliasModel: no such skin # %d for '%s' \n " , skinnum , e - > model - > name ) ;
// ericw -- display skin 0 for winquake compatibility
skinnum = 0 ;
2010-02-15 23:26:55 +00:00
}
2017-09-17 02:12:53 +00:00
if ( paliashdr - > numskins < = 0 )
2010-02-15 23:26:55 +00:00
{
2023-07-07 09:57:40 +00:00
tex . base = tex . luma = tex . lower = tex . upper = NULL ; // NULL will give the checkerboard texture
2017-09-17 02:12:53 +00:00
}
else
2023-07-07 09:57:40 +00:00
tex = paliashdr - > textures [ skinnum ] [ anim ] ;
if ( ! gl_nocolors . value )
2017-09-17 02:12:53 +00:00
{
2023-07-07 09:57:40 +00:00
if ( e - > eflags & EFLAGS_COLOURMAPPED )
{ //support for dp's self.colormap = 4096 | top*16 | bottom; thing (solves corpses changing colours, can't handle rich colours though)
if ( tex . base & & tex . base - > source_format = = SRC_INDEXED & & ! tex . upper & & ! tex . lower )
{
struct gltexture_s * t = TexMgr_ColormapTexture ( tex . base , CL_PLColours_FromLegacy ( e - > netstate . colormap & 15 ) , CL_PLColours_FromLegacy ( e - > netstate . colormap > > 4 ) ) ;
if ( t )
tex . base = t ;
}
}
else if ( e - > netstate . colormap > = 1 & & e - > netstate . colormap < = cl . maxclients )
{ //despite being able to handle _shirt+_pants textures in our glsl, we still prefer to generate per-player textures.
//1) works with non-glsl.
//2) preserves the weird non-linear ranges.
//3) ... and without breaking those ranges on models that are NOT colourmapped (the lower's remapped range is the worst of the non-linear ranges, so would make too many models ugly).
//so we only use the shirt+pans stuff when using external textures
//on the plus side, we do use a lookup so we don't break quakerally. csqc also benefits from not needing to worry about edict numbers.
if ( tex . base & & tex . base - > source_format = = SRC_INDEXED & & ! tex . upper & & ! tex . lower )
{
scoreboard_t * sb = & cl . scores [ e - > netstate . colormap - 1 ] ;
struct gltexture_s * t = TexMgr_ColormapTexture ( tex . base , sb - > pants , sb - > shirt ) ;
if ( t )
tex . base = t ;
}
}
2017-09-17 02:12:53 +00:00
}
if ( ! gl_fullbrights . value )
2023-07-07 09:57:40 +00:00
tex . luma = NULL ;
2017-09-17 02:12:53 +00:00
//
// draw it
//
if ( r_drawflat_cheatsafe )
{
glDisable ( GL_TEXTURE_2D ) ;
2010-02-15 23:26:55 +00:00
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
2017-09-17 02:12:53 +00:00
glEnable ( GL_TEXTURE_2D ) ;
srand ( ( int ) ( cl . time * 1000 ) ) ; //restore randomness
2010-02-15 23:26:55 +00:00
}
2017-09-17 02:12:53 +00:00
else if ( r_fullbright_cheatsafe )
2010-02-15 23:26:55 +00:00
{
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . base ) ;
2017-09-17 02:12:53 +00:00
shading = false ;
glColor4f ( 1 , 1 , 1 , entalpha ) ;
2010-02-15 23:26:55 +00:00
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
2023-07-07 09:57:40 +00:00
if ( tex . luma )
2010-02-15 23:26:55 +00:00
{
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . luma ) ;
2010-02-15 23:26:55 +00:00
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_ONE , GL_ONE ) ;
glDepthMask ( GL_FALSE ) ;
glColor3f ( entalpha , entalpha , entalpha ) ;
Fog_StartAdditive ( ) ;
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
Fog_StopAdditive ( ) ;
glDepthMask ( GL_TRUE ) ;
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glDisable ( GL_BLEND ) ;
}
}
2017-09-17 02:12:53 +00:00
else if ( r_lightmap_cheatsafe )
2010-02-15 23:26:55 +00:00
{
2017-09-17 02:12:53 +00:00
glDisable ( GL_TEXTURE_2D ) ;
shading = false ;
glColor3f ( 1 , 1 , 1 ) ;
2010-02-15 23:26:55 +00:00
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
2017-09-17 02:12:53 +00:00
glEnable ( GL_TEXTURE_2D ) ;
}
// call fast path if possible. if the shader compliation failed for some reason,
// r_alias_program will be 0.
2021-09-05 15:41:35 +00:00
else if ( glsl - > program ! = 0 & & ( paliashdr - > numbones < = glsl - > maxbones | | ! lerpdata . bonestate ) )
2017-09-17 02:12:53 +00:00
{
2023-07-07 09:57:40 +00:00
GL_DrawAliasFrame_GLSL ( glsl , paliashdr , lerpdata , tex , e ) ;
2017-09-17 02:12:53 +00:00
}
else if ( overbright )
{
2023-07-07 09:57:40 +00:00
if ( gl_texture_env_combine & & gl_mtexable & & gl_texture_env_add & & tex . luma ) //case 1: everything in one pass
2017-09-17 02:12:53 +00:00
{
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . base ) ;
2017-09-17 02:12:53 +00:00
glTexEnvi ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_COMBINE_EXT ) ;
glTexEnvi ( GL_TEXTURE_ENV , GL_COMBINE_RGB_EXT , GL_MODULATE ) ;
glTexEnvi ( GL_TEXTURE_ENV , GL_SOURCE0_RGB_EXT , GL_TEXTURE ) ;
glTexEnvi ( GL_TEXTURE_ENV , GL_SOURCE1_RGB_EXT , GL_PRIMARY_COLOR_EXT ) ;
glTexEnvf ( GL_TEXTURE_ENV , GL_RGB_SCALE_EXT , 2.0f ) ;
GL_EnableMultitexture ( ) ; // selects TEXTURE1
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . luma ) ;
2017-09-17 02:12:53 +00:00
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_ADD ) ;
// glEnable(GL_BLEND);
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
// glDisable(GL_BLEND);
GL_DisableMultitexture ( ) ;
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_REPLACE ) ;
}
else if ( gl_texture_env_combine ) //case 2: overbright in one pass, then fullbright pass
{
// first pass
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . base ) ;
2017-09-17 02:12:53 +00:00
glTexEnvi ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_COMBINE_EXT ) ;
glTexEnvi ( GL_TEXTURE_ENV , GL_COMBINE_RGB_EXT , GL_MODULATE ) ;
glTexEnvi ( GL_TEXTURE_ENV , GL_SOURCE0_RGB_EXT , GL_TEXTURE ) ;
glTexEnvi ( GL_TEXTURE_ENV , GL_SOURCE1_RGB_EXT , GL_PRIMARY_COLOR_EXT ) ;
glTexEnvf ( GL_TEXTURE_ENV , GL_RGB_SCALE_EXT , 2.0f ) ;
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
glTexEnvf ( GL_TEXTURE_ENV , GL_RGB_SCALE_EXT , 1.0f ) ;
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_REPLACE ) ;
// second pass
2023-07-07 09:57:40 +00:00
if ( tex . luma )
2017-09-17 02:12:53 +00:00
{
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . luma ) ;
2017-09-17 02:12:53 +00:00
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_ONE , GL_ONE ) ;
glDepthMask ( GL_FALSE ) ;
shading = false ;
glColor3f ( entalpha , entalpha , entalpha ) ;
Fog_StartAdditive ( ) ;
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
Fog_StopAdditive ( ) ;
glDepthMask ( GL_TRUE ) ;
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glDisable ( GL_BLEND ) ;
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_REPLACE ) ;
}
}
else //case 3: overbright in two passes, then fullbright pass
2010-02-15 23:26:55 +00:00
{
2017-09-17 02:12:53 +00:00
// first pass
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . base ) ;
2010-02-15 23:26:55 +00:00
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
2017-09-17 02:12:53 +00:00
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
// second pass -- additive with black fog, to double the object colors but not the fog color
2010-02-15 23:26:55 +00:00
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_ONE , GL_ONE ) ;
glDepthMask ( GL_FALSE ) ;
Fog_StartAdditive ( ) ;
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
Fog_StopAdditive ( ) ;
glDepthMask ( GL_TRUE ) ;
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_REPLACE ) ;
2017-09-17 02:12:53 +00:00
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glDisable ( GL_BLEND ) ;
// third pass
2023-07-07 09:57:40 +00:00
if ( tex . luma )
2017-09-17 02:12:53 +00:00
{
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . luma ) ;
2017-09-17 02:12:53 +00:00
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_ONE , GL_ONE ) ;
glDepthMask ( GL_FALSE ) ;
shading = false ;
glColor3f ( entalpha , entalpha , entalpha ) ;
Fog_StartAdditive ( ) ;
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
Fog_StopAdditive ( ) ;
glDepthMask ( GL_TRUE ) ;
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glDisable ( GL_BLEND ) ;
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_REPLACE ) ;
}
2010-02-15 23:26:55 +00:00
}
}
2017-09-17 02:12:53 +00:00
else
2010-02-15 23:26:55 +00:00
{
2023-07-07 09:57:40 +00:00
if ( gl_mtexable & & gl_texture_env_add & & tex . luma ) //case 4: fullbright mask using multitexture
2010-02-15 23:26:55 +00:00
{
2017-09-17 02:12:53 +00:00
GL_DisableMultitexture ( ) ; // selects TEXTURE0
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . base ) ;
2017-09-17 02:12:53 +00:00
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
GL_EnableMultitexture ( ) ; // selects TEXTURE1
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . luma ) ;
2017-09-17 02:12:53 +00:00
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_ADD ) ;
2010-02-15 23:26:55 +00:00
glEnable ( GL_BLEND ) ;
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
glDisable ( GL_BLEND ) ;
2017-09-17 02:12:53 +00:00
GL_DisableMultitexture ( ) ;
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_REPLACE ) ;
}
else //case 5: fullbright mask without multitexture
{
// first pass
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . base ) ;
2017-09-17 02:12:53 +00:00
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_MODULATE ) ;
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
// second pass
2023-07-07 09:57:40 +00:00
if ( tex . luma )
2017-09-17 02:12:53 +00:00
{
2023-07-07 09:57:40 +00:00
GL_Bind ( tex . luma ) ;
2017-09-17 02:12:53 +00:00
glEnable ( GL_BLEND ) ;
glBlendFunc ( GL_ONE , GL_ONE ) ;
glDepthMask ( GL_FALSE ) ;
shading = false ;
glColor3f ( entalpha , entalpha , entalpha ) ;
Fog_StartAdditive ( ) ;
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
Fog_StopAdditive ( ) ;
glDepthMask ( GL_TRUE ) ;
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
glDisable ( GL_BLEND ) ;
}
2010-02-15 23:26:55 +00:00
}
}
2017-09-17 02:12:53 +00:00
if ( ! paliashdr - > nextsurface )
break ;
paliashdr = ( aliashdr_t * ) ( ( byte * ) paliashdr + paliashdr - > nextsurface ) ;
2010-02-15 23:26:55 +00:00
}
cleanup :
glTexEnvf ( GL_TEXTURE_ENV , GL_TEXTURE_ENV_MODE , GL_REPLACE ) ;
glHint ( GL_PERSPECTIVE_CORRECTION_HINT , GL_NICEST ) ;
glShadeModel ( GL_FLAT ) ;
glDepthMask ( GL_TRUE ) ;
glDisable ( GL_BLEND ) ;
2017-08-04 19:45:11 +00:00
if ( alphatest )
glDisable ( GL_ALPHA_TEST ) ;
2010-02-15 23:26:55 +00:00
glColor3f ( 1 , 1 , 1 ) ;
2019-01-30 01:53:15 +00:00
if ( e - > eflags & EFLAGS_VIEWMODEL )
2017-09-17 02:12:53 +00:00
glDepthRange ( 0 , 1 ) ;
2023-11-02 23:45:50 +00:00
if ( e - > effects & EF_ADDITIVE )
glBlendFunc ( GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA ) ;
2010-02-15 23:26:55 +00:00
glPopMatrix ( ) ;
}
//johnfitz -- values for shadow matrix
# define SHADOW_SKEW_X -0.7 //skew along x axis. -0.7 to mimic glquake shadows
# define SHADOW_SKEW_Y 0 //skew along y axis. 0 to mimic glquake shadows
# define SHADOW_VSCALE 0 //0=completely flat
# define SHADOW_HEIGHT 0.1 //how far above the floor to render the shadow
//johnfitz
/*
= = = = = = = = = = = = =
GL_DrawAliasShadow - - johnfitz - - rewritten
TODO : orient shadow onto " lightplane " ( a global mplane_t * )
= = = = = = = = = = = = =
*/
void GL_DrawAliasShadow ( entity_t * e )
{
float shadowmatrix [ 16 ] = { 1 , 0 , 0 , 0 ,
0 , 1 , 0 , 0 ,
SHADOW_SKEW_X , SHADOW_SKEW_Y , SHADOW_VSCALE , 0 ,
0 , 0 , SHADOW_HEIGHT , 1 } ;
float lheight ;
aliashdr_t * paliashdr ;
lerpdata_t lerpdata ;
if ( R_CullModelForEntity ( e ) )
return ;
2017-09-17 02:12:53 +00:00
if ( e = = & cl . viewent | | e - > effects & EF_NOSHADOW | | e - > model - > flags & MOD_NOSHADOW )
2010-02-15 23:26:55 +00:00
return ;
entalpha = ENTALPHA_DECODE ( e - > alpha ) ;
if ( entalpha = = 0 ) return ;
paliashdr = ( aliashdr_t * ) Mod_Extradata ( e - > model ) ;
2020-07-23 19:28:19 +00:00
R_SetupAliasFrame ( paliashdr , e , & lerpdata ) ;
2010-02-15 23:26:55 +00:00
R_SetupEntityTransform ( e , & lerpdata ) ;
R_LightPoint ( e - > origin ) ;
lheight = currententity - > origin [ 2 ] - lightspot [ 2 ] ;
// set up matrix
2014-08-30 08:00:34 +00:00
glPushMatrix ( ) ;
2010-02-15 23:26:55 +00:00
glTranslatef ( lerpdata . origin [ 0 ] , lerpdata . origin [ 1 ] , lerpdata . origin [ 2 ] ) ;
glTranslatef ( 0 , 0 , - lheight ) ;
glMultMatrixf ( shadowmatrix ) ;
glTranslatef ( 0 , 0 , lheight ) ;
glRotatef ( lerpdata . angles [ 1 ] , 0 , 0 , 1 ) ;
glRotatef ( - lerpdata . angles [ 0 ] , 0 , 1 , 0 ) ;
glRotatef ( lerpdata . angles [ 2 ] , 1 , 0 , 0 ) ;
glTranslatef ( paliashdr - > scale_origin [ 0 ] , paliashdr - > scale_origin [ 1 ] , paliashdr - > scale_origin [ 2 ] ) ;
glScalef ( paliashdr - > scale [ 0 ] , paliashdr - > scale [ 1 ] , paliashdr - > scale [ 2 ] ) ;
// draw it
glDepthMask ( GL_FALSE ) ;
glEnable ( GL_BLEND ) ;
GL_DisableMultitexture ( ) ;
glDisable ( GL_TEXTURE_2D ) ;
shading = false ;
glColor4f ( 0 , 0 , 0 , entalpha * 0.5 ) ;
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
glEnable ( GL_TEXTURE_2D ) ;
glDisable ( GL_BLEND ) ;
glDepthMask ( GL_TRUE ) ;
//clean up
glPopMatrix ( ) ;
}
/*
= = = = = = = = = = = = = = = = =
R_DrawAliasModel_ShowTris - - johnfitz
= = = = = = = = = = = = = = = = =
*/
void R_DrawAliasModel_ShowTris ( entity_t * e )
{
aliashdr_t * paliashdr ;
lerpdata_t lerpdata ;
if ( R_CullModelForEntity ( e ) )
return ;
paliashdr = ( aliashdr_t * ) Mod_Extradata ( e - > model ) ;
2020-07-23 19:28:19 +00:00
R_SetupAliasFrame ( paliashdr , e , & lerpdata ) ;
2010-02-15 23:26:55 +00:00
R_SetupEntityTransform ( e , & lerpdata ) ;
2014-08-30 08:00:34 +00:00
glPushMatrix ( ) ;
2017-09-17 02:12:53 +00:00
R_RotateForEntity ( lerpdata . origin , lerpdata . angles , e - > netstate . scale ) ;
2010-02-15 23:26:55 +00:00
glTranslatef ( paliashdr - > scale_origin [ 0 ] , paliashdr - > scale_origin [ 1 ] , paliashdr - > scale_origin [ 2 ] ) ;
glScalef ( paliashdr - > scale [ 0 ] , paliashdr - > scale [ 1 ] , paliashdr - > scale [ 2 ] ) ;
shading = false ;
glColor3f ( 1 , 1 , 1 ) ;
GL_DrawAliasFrame ( paliashdr , lerpdata ) ;
glPopMatrix ( ) ;
2010-02-16 12:24:38 +00:00
}