X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=r_shadow.c;h=c7f2d72fd1db66dc561d8be89af9e451f0be068a;hp=7c219b686528d812f984052fd4c2f5d79c4c861b;hb=302711d37e168e57a9e2c8003084a22a3285c555;hpb=e7a4387fae640a8677005bcb70f8ec311c171fc6 diff --git a/r_shadow.c b/r_shadow.c index 7c219b68..c7f2d72f 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -228,7 +228,6 @@ cvar_t r_shadow_realtime_dlight_shadows = {CVAR_SAVE, "r_shadow_realtime_dlight_ cvar_t r_shadow_realtime_dlight_svbspculling = {0, "r_shadow_realtime_dlight_svbspculling", "0", "enables svbsp optimization on dynamic lights (very slow!)"}; cvar_t r_shadow_realtime_dlight_portalculling = {0, "r_shadow_realtime_dlight_portalculling", "0", "enables portal optimization on dynamic lights (slow!)"}; cvar_t r_shadow_realtime_world = {CVAR_SAVE, "r_shadow_realtime_world", "0", "enables rendering of full world lighting (whether loaded from the map, or a .rtlights file, or a .ent file, or a .lights file produced by hlight)"}; -cvar_t r_shadow_realtime_world_dlightshadows = {CVAR_SAVE, "r_shadow_realtime_world_dlightshadows", "1", "enables shadows from dynamic lights when using full world lighting"}; cvar_t r_shadow_realtime_world_lightmaps = {CVAR_SAVE, "r_shadow_realtime_world_lightmaps", "0", "brightness to render lightmaps when using full world lighting, try 0.5 for a tenebrae-like appearance"}; cvar_t r_shadow_realtime_world_shadows = {CVAR_SAVE, "r_shadow_realtime_world_shadows", "1", "enables rendering of shadows from world lights"}; cvar_t r_shadow_realtime_world_compile = {0, "r_shadow_realtime_world_compile", "1", "enables compilation of world lights for higher performance rendering"}; @@ -237,8 +236,8 @@ cvar_t r_shadow_realtime_world_compilesvbsp = {0, "r_shadow_realtime_world_compi cvar_t r_shadow_realtime_world_compileportalculling = {0, "r_shadow_realtime_world_compileportalculling", "1", "enables portal-based culling optimization during compilation"}; cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1", "use scissor optimization of light rendering (restricts rendering to the portion of the screen affected by the light)"}; cvar_t r_shadow_culltriangles = {0, "r_shadow_culltriangles", "1", "performs more expensive tests to remove unnecessary triangles of lit surfaces"}; -cvar_t r_shadow_shadow_polygonfactor = {0, "r_shadow_shadow_polygonfactor", "0", "how much to enlarge shadow volume polygons when rendering (should be 0!)"}; -cvar_t r_shadow_shadow_polygonoffset = {0, "r_shadow_shadow_polygonoffset", "1", "how much to push shadow volumes into the distance when rendering, to reduce chances of zfighting artifacts (should not be less than 0)"}; +cvar_t r_shadow_polygonfactor = {0, "r_shadow_polygonfactor", "0", "how much to enlarge shadow volume polygons when rendering (should be 0!)"}; +cvar_t r_shadow_polygonoffset = {0, "r_shadow_polygonoffset", "1", "how much to push shadow volumes into the distance when rendering, to reduce chances of zfighting artifacts (should not be less than 0)"}; cvar_t r_shadow_texture3d = {0, "r_shadow_texture3d", "1", "use 3D voxel textures for spherical attenuation rather than cylindrical (does not affect r_glsl lighting)"}; cvar_t gl_ext_separatestencil = {0, "gl_ext_separatestencil", "1", "make use of OpenGL 2.0 glStencilOpSeparate or GL_ATI_separate_stencil extension"}; cvar_t gl_ext_stenciltwoside = {0, "gl_ext_stenciltwoside", "1", "make use of GL_EXT_stenciltwoside extension (NVIDIA only)"}; @@ -404,14 +403,13 @@ void R_Shadow_Help_f(void) "r_shadow_realtime_dlight : use high quality dynamic lights in normal mode\n" "r_shadow_realtime_dlight_shadows : cast shadows from dlights\n" "r_shadow_realtime_world : use high quality world lighting mode\n" -"r_shadow_realtime_world_dlightshadows : cast shadows from dlights\n" "r_shadow_realtime_world_lightmaps : use lightmaps in addition to lights\n" "r_shadow_realtime_world_shadows : cast shadows from world lights\n" "r_shadow_realtime_world_compile : compile surface/visibility information\n" "r_shadow_realtime_world_compileshadow : compile shadow geometry\n" "r_shadow_scissor : use scissor optimization\n" -"r_shadow_shadow_polygonfactor : nudge shadow volumes closer/further\n" -"r_shadow_shadow_polygonoffset : nudge shadow volumes closer/further\n" +"r_shadow_polygonfactor : nudge shadow volumes closer/further\n" +"r_shadow_polygonoffset : nudge shadow volumes closer/further\n" "r_shadow_texture3d : use 3d attenuation texture (if hardware supports)\n" "r_showlighting : useful for performance testing; bright = slow!\n" "r_showshadowvolumes : useful for performance testing; bright = slow!\n" @@ -442,7 +440,6 @@ void R_Shadow_Init(void) Cvar_RegisterVariable(&r_shadow_realtime_dlight_svbspculling); Cvar_RegisterVariable(&r_shadow_realtime_dlight_portalculling); Cvar_RegisterVariable(&r_shadow_realtime_world); - Cvar_RegisterVariable(&r_shadow_realtime_world_dlightshadows); Cvar_RegisterVariable(&r_shadow_realtime_world_lightmaps); Cvar_RegisterVariable(&r_shadow_realtime_world_shadows); Cvar_RegisterVariable(&r_shadow_realtime_world_compile); @@ -451,8 +448,8 @@ void R_Shadow_Init(void) Cvar_RegisterVariable(&r_shadow_realtime_world_compileportalculling); Cvar_RegisterVariable(&r_shadow_scissor); Cvar_RegisterVariable(&r_shadow_culltriangles); - Cvar_RegisterVariable(&r_shadow_shadow_polygonfactor); - Cvar_RegisterVariable(&r_shadow_shadow_polygonoffset); + Cvar_RegisterVariable(&r_shadow_polygonfactor); + Cvar_RegisterVariable(&r_shadow_polygonoffset); Cvar_RegisterVariable(&r_shadow_texture3d); Cvar_RegisterVariable(&gl_ext_separatestencil); Cvar_RegisterVariable(&gl_ext_stenciltwoside); @@ -900,19 +897,19 @@ void R_Shadow_RenderVolume(int numvertices, int numtriangles, const float *verte } r_refdef.stats.lights_shadowtriangles += numtriangles; CHECKGLERROR - R_Mesh_VertexPointer(vertex3f); + R_Mesh_VertexPointer(vertex3f, 0, 0); GL_LockArrays(0, numvertices); if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCIL) { // decrement stencil if backface is behind depthbuffer GL_CullFace(GL_BACK); // quake is backwards, this culls front faces qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR - R_Mesh_Draw(0, numvertices, numtriangles, element3i); + R_Mesh_Draw(0, numvertices, numtriangles, element3i, 0, 0); // increment stencil if frontface is behind depthbuffer GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR } - R_Mesh_Draw(0, numvertices, numtriangles, element3i); + R_Mesh_Draw(0, numvertices, numtriangles, element3i, 0, 0); GL_LockArrays(0, 0); CHECKGLERROR } @@ -1003,9 +1000,10 @@ void R_Shadow_RenderMode_Begin(void) R_Shadow_MakeTextures(); CHECKGLERROR - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); GL_BlendFunc(GL_ONE, GL_ZERO); + GL_DepthRange(0, 1); GL_DepthTest(true); GL_DepthMask(false); GL_Color(0, 0, 0, 1); @@ -1044,8 +1042,9 @@ void R_Shadow_RenderMode_Reset(void) { qglDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);CHECKGLERROR } - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); + GL_DepthRange(0, 1); GL_DepthTest(true); GL_DepthMask(false); qglDepthFunc(GL_LEQUAL);CHECKGLERROR @@ -1060,7 +1059,7 @@ void R_Shadow_RenderMode_Reset(void) GL_BlendFunc(GL_ONE, GL_ZERO); } -void R_Shadow_RenderMode_StencilShadowVolumes(void) +void R_Shadow_RenderMode_StencilShadowVolumes(qboolean clearstencil) { CHECKGLERROR R_Shadow_RenderMode_Reset(); @@ -1086,7 +1085,8 @@ void R_Shadow_RenderMode_StencilShadowVolumes(void) qglStencilMask(~0);CHECKGLERROR qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR } - GL_Clear(GL_STENCIL_BUFFER_BIT); + if (clearstencil) + GL_Clear(GL_STENCIL_BUFFER_BIT); r_refdef.stats.lights_clears++; } @@ -1132,6 +1132,7 @@ void R_Shadow_RenderMode_VisibleShadowVolumes(void) CHECKGLERROR R_Shadow_RenderMode_Reset(); GL_BlendFunc(GL_ONE, GL_ONE); + GL_DepthRange(0, 1); GL_DepthTest(r_showshadowvolumes.integer < 2); GL_Color(0.0, 0.0125 * r_view.colorscale, 0.1 * r_view.colorscale, 1); qglPolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR @@ -1144,6 +1145,7 @@ void R_Shadow_RenderMode_VisibleLighting(qboolean stenciltest, qboolean transpar CHECKGLERROR R_Shadow_RenderMode_Reset(); GL_BlendFunc(GL_ONE, GL_ONE); + GL_DepthRange(0, 1); GL_DepthTest(r_showlighting.integer < 2); GL_Color(0.1 * r_view.colorscale, 0.0125 * r_view.colorscale, 0, 1); if (!transparent) @@ -1261,9 +1263,9 @@ qboolean R_Shadow_ScissorForBBox(const float *mins, const float *maxs) static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int numverts, int numtriangles, const int *element3i, const float *diffusecolor, const float *ambientcolor) { - float *vertex3f = rsurface_vertex3f + 3 * firstvertex; - float *normal3f = rsurface_normal3f + 3 * firstvertex; - float *color4f = rsurface_array_color4f + 4 * firstvertex; + float *vertex3f = rsurface.vertex3f + 3 * firstvertex; + float *normal3f = rsurface.normal3f + 3 * firstvertex; + float *color4f = rsurface.array_color4f + 4 * firstvertex; float dist, dot, distintensity, shadeintensity, v[3], n[3]; if (r_textureunits.integer >= 3) { @@ -1282,7 +1284,8 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu VectorCopy(ambientcolor, color4f); if (r_refdef.fogenabled) { - float f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg)); + float f; + f = FogPoint_Model(vertex3f); VectorScale(color4f, f, color4f); } color4f[3] = 1; @@ -1297,7 +1300,7 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu { float f; Matrix4x4_Transform(&r_shadow_entitytolight, vertex3f, v); - f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg)); + f = FogPoint_Model(vertex3f); VectorScale(color4f, f, color4f); } color4f[3] = 1; @@ -1329,7 +1332,8 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu } if (r_refdef.fogenabled) { - float f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg)); + float f; + f = FogPoint_Model(vertex3f); VectorScale(color4f, f, color4f); } } @@ -1350,7 +1354,8 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu color4f[2] = ambientcolor[2] * distintensity; if (r_refdef.fogenabled) { - float f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg)); + float f; + f = FogPoint_Model(vertex3f); VectorScale(color4f, f, color4f); } } @@ -1386,7 +1391,8 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu } if (r_refdef.fogenabled) { - float f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg)); + float f; + f = FogPoint_Model(vertex3f); VectorScale(color4f, f, color4f); } } @@ -1408,7 +1414,8 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu color4f[2] = ambientcolor[2] * distintensity; if (r_refdef.fogenabled) { - float f = VERTEXFOGTABLE(VectorDistance(v, rsurface_modelorg)); + float f; + f = FogPoint_Model(vertex3f); VectorScale(color4f, f, color4f); } } @@ -1425,11 +1432,11 @@ static void R_Shadow_RenderLighting_Light_Vertex_Shading(int firstvertex, int nu static void R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(int firstvertex, int numvertices, int numtriangles, const int *element3i) { int i; - float *out3f = rsurface_array_texcoord3f + 3 * firstvertex; - const float *vertex3f = rsurface_vertex3f + 3 * firstvertex; - const float *svector3f = rsurface_svector3f + 3 * firstvertex; - const float *tvector3f = rsurface_tvector3f + 3 * firstvertex; - const float *normal3f = rsurface_normal3f + 3 * firstvertex; + float *out3f = rsurface.array_texcoord3f + 3 * firstvertex; + const float *vertex3f = rsurface.vertex3f + 3 * firstvertex; + const float *svector3f = rsurface.svector3f + 3 * firstvertex; + const float *tvector3f = rsurface.tvector3f + 3 * firstvertex; + const float *normal3f = rsurface.normal3f + 3 * firstvertex; float lightdir[3]; for (i = 0;i < numvertices;i++, vertex3f += 3, svector3f += 3, tvector3f += 3, normal3f += 3, out3f += 3) { @@ -1444,17 +1451,17 @@ static void R_Shadow_GenTexCoords_Diffuse_NormalCubeMap(int firstvertex, int num static void R_Shadow_GenTexCoords_Specular_NormalCubeMap(int firstvertex, int numvertices, int numtriangles, const int *element3i) { int i; - float *out3f = rsurface_array_texcoord3f + 3 * firstvertex; - const float *vertex3f = rsurface_vertex3f + 3 * firstvertex; - const float *svector3f = rsurface_svector3f + 3 * firstvertex; - const float *tvector3f = rsurface_tvector3f + 3 * firstvertex; - const float *normal3f = rsurface_normal3f + 3 * firstvertex; + float *out3f = rsurface.array_texcoord3f + 3 * firstvertex; + const float *vertex3f = rsurface.vertex3f + 3 * firstvertex; + const float *svector3f = rsurface.svector3f + 3 * firstvertex; + const float *tvector3f = rsurface.tvector3f + 3 * firstvertex; + const float *normal3f = rsurface.normal3f + 3 * firstvertex; float lightdir[3], eyedir[3], halfdir[3]; for (i = 0;i < numvertices;i++, vertex3f += 3, svector3f += 3, tvector3f += 3, normal3f += 3, out3f += 3) { VectorSubtract(r_shadow_entitylightorigin, vertex3f, lightdir); VectorNormalize(lightdir); - VectorSubtract(rsurface_modelorg, vertex3f, eyedir); + VectorSubtract(rsurface.modelorg, vertex3f, eyedir); VectorNormalize(eyedir); VectorAdd(lightdir, eyedir, halfdir); // the cubemap normalizes this for us @@ -1464,35 +1471,35 @@ static void R_Shadow_GenTexCoords_Specular_NormalCubeMap(int firstvertex, int nu } } -static void R_Shadow_RenderLighting_VisibleLighting(int firstvertex, int numvertices, int numtriangles, const int *element3i, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt) +static void R_Shadow_RenderLighting_VisibleLighting(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt) { // used to display how many times a surface is lit for level design purposes GL_Color(0.1 * r_view.colorscale, 0.025 * r_view.colorscale, 0, 1); - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); } -static void R_Shadow_RenderLighting_Light_GLSL(int firstvertex, int numvertices, int numtriangles, const int *element3i, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt) +static void R_Shadow_RenderLighting_Light_GLSL(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt) { // ARB2 GLSL shader path (GFFX5200, Radeon 9500) R_SetupSurfaceShader(lightcolorbase, false, ambientscale, diffusescale, specularscale); - R_Mesh_TexCoordPointer(0, 2, rsurface_model->surfmesh.data_texcoordtexture2f); - R_Mesh_TexCoordPointer(1, 3, rsurface_svector3f); - R_Mesh_TexCoordPointer(2, 3, rsurface_tvector3f); - R_Mesh_TexCoordPointer(3, 3, rsurface_normal3f); - if (rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) + R_Mesh_TexCoordPointer(0, 2, rsurface.model->surfmesh.data_texcoordtexture2f, rsurface.model->surfmesh.vbo, rsurface.model->surfmesh.vbooffset_texcoordtexture2f); + R_Mesh_TexCoordPointer(1, 3, rsurface.svector3f, rsurface.svector3f_bufferobject, rsurface.svector3f_bufferoffset); + R_Mesh_TexCoordPointer(2, 3, rsurface.tvector3f, rsurface.tvector3f_bufferobject, rsurface.tvector3f_bufferoffset); + R_Mesh_TexCoordPointer(3, 3, rsurface.normal3f, rsurface.normal3f_bufferobject, rsurface.normal3f_bufferoffset); + if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) { qglDepthFunc(GL_EQUAL);CHECKGLERROR } - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); - if (rsurface_texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); + if (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) { qglDepthFunc(GL_LEQUAL);CHECKGLERROR } } -static void R_Shadow_RenderLighting_Light_Dot3_Finalize(int firstvertex, int numvertices, int numtriangles, const int *element3i, float r, float g, float b) +static void R_Shadow_RenderLighting_Light_Dot3_Finalize(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, float r, float g, float b) { // shared final code for all the dot3 layers int renders; @@ -1500,11 +1507,11 @@ static void R_Shadow_RenderLighting_Light_Dot3_Finalize(int firstvertex, int num for (renders = 0;renders < 64 && (r > 0 || g > 0 || b > 0);renders++, r--, g--, b--) { GL_Color(bound(0, r, 1), bound(0, g, 1), bound(0, b, 1), 1); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); } } -static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int numvertices, int numtriangles, const int *element3i, const vec3_t lightcolorbase, rtexture_t *basetexture, float colorscale) +static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, rtexture_t *basetexture, float colorscale) { rmeshstate_t m; // colorscale accounts for how much we multiply the brightness @@ -1520,13 +1527,19 @@ static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int // 3 3D combine path (Geforce3, Radeon 8500) memset(&m, 0, sizeof(m)); m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture); - m.pointer_texcoord3f[0] = rsurface_vertex3f; + m.pointer_texcoord3f[0] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[0] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[0] = rsurface.vertex3f_bufferoffset; m.texmatrix[0] = r_shadow_entitytoattenuationxyz; m.tex[1] = R_GetTexture(basetexture); - m.pointer_texcoord[1] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[1] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[1] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[1] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[1] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[1] = rsurface.texture->currenttexmatrix; m.texcubemap[2] = R_GetTexture(r_shadow_rtlight->currentcubemap); - m.pointer_texcoord3f[2] = rsurface_vertex3f; + m.pointer_texcoord3f[2] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[2] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[2] = rsurface.vertex3f_bufferoffset; m.texmatrix[2] = r_shadow_entitytolight; GL_BlendFunc(GL_ONE, GL_ONE); } @@ -1535,11 +1548,15 @@ static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int // 2 3D combine path (Geforce3, original Radeon) memset(&m, 0, sizeof(m)); m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture); - m.pointer_texcoord3f[0] = rsurface_vertex3f; + m.pointer_texcoord3f[0] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[0] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[0] = rsurface.vertex3f_bufferoffset; m.texmatrix[0] = r_shadow_entitytoattenuationxyz; m.tex[1] = R_GetTexture(basetexture); - m.pointer_texcoord[1] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[1] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[1] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[1] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[1] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[1] = rsurface.texture->currenttexmatrix; GL_BlendFunc(GL_ONE, GL_ONE); } else if (r_textureunits.integer >= 4 && r_shadow_rtlight->currentcubemap != r_texture_whitecube) @@ -1547,18 +1564,26 @@ static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int // 4 2D combine path (Geforce3, Radeon 8500) memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[0] = rsurface_vertex3f; + m.pointer_texcoord3f[0] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[0] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[0] = rsurface.vertex3f_bufferoffset; m.texmatrix[0] = r_shadow_entitytoattenuationxyz; m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytoattenuationz; m.tex[2] = R_GetTexture(basetexture); - m.pointer_texcoord[2] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[2] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[2] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[2] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[2] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[2] = rsurface.texture->currenttexmatrix; if (r_shadow_rtlight->currentcubemap != r_texture_whitecube) { m.texcubemap[3] = R_GetTexture(r_shadow_rtlight->currentcubemap); - m.pointer_texcoord3f[3] = rsurface_vertex3f; + m.pointer_texcoord3f[3] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[3] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[3] = rsurface.vertex3f_bufferoffset; m.texmatrix[3] = r_shadow_entitytolight; } GL_BlendFunc(GL_ONE, GL_ONE); @@ -1568,14 +1593,20 @@ static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int // 3 2D combine path (Geforce3, original Radeon) memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[0] = rsurface_vertex3f; + m.pointer_texcoord3f[0] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[0] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[0] = rsurface.vertex3f_bufferoffset; m.texmatrix[0] = r_shadow_entitytoattenuationxyz; m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytoattenuationz; m.tex[2] = R_GetTexture(basetexture); - m.pointer_texcoord[2] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[2] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[2] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[2] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[2] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[2] = rsurface.texture->currenttexmatrix; GL_BlendFunc(GL_ONE, GL_ONE); } else @@ -1583,35 +1614,43 @@ static void R_Shadow_RenderLighting_Light_Dot3_AmbientPass(int firstvertex, int // 2/2/2 2D combine path (any dot3 card) memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[0] = rsurface_vertex3f; + m.pointer_texcoord3f[0] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[0] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[0] = rsurface.vertex3f_bufferoffset; m.texmatrix[0] = r_shadow_entitytoattenuationxyz; m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytoattenuationz; R_Mesh_TextureState(&m); GL_ColorMask(0,0,0,1); GL_BlendFunc(GL_ONE, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // second pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(basetexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; if (r_shadow_rtlight->currentcubemap != r_texture_whitecube) { m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytolight; } GL_BlendFunc(GL_DST_ALPHA, GL_ONE); } // this final code is shared R_Mesh_TextureState(&m); - R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale); + R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale); } -static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int numvertices, int numtriangles, const int *element3i, const vec3_t lightcolorbase, rtexture_t *basetexture, rtexture_t *normalmaptexture, float colorscale) +static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, rtexture_t *basetexture, rtexture_t *normalmaptexture, float colorscale) { rmeshstate_t m; // colorscale accounts for how much we multiply the brightness @@ -1630,28 +1669,38 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(normalmaptexture); m.texcombinergb[0] = GL_REPLACE; - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube); m.texcombinergb[1] = GL_DOT3_RGBA_ARB; - m.pointer_texcoord3f[1] = rsurface_array_texcoord3f; + m.pointer_texcoord3f[1] = rsurface.array_texcoord3f; + m.pointer_texcoord_bufferobject[1] = 0; + m.pointer_texcoord_bufferoffset[1] = 0; m.tex3d[2] = R_GetTexture(r_shadow_attenuation3dtexture); - m.pointer_texcoord3f[2] = rsurface_vertex3f; + m.pointer_texcoord3f[2] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[2] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[2] = rsurface.vertex3f_bufferoffset; m.texmatrix[2] = r_shadow_entitytoattenuationxyz; R_Mesh_TextureState(&m); GL_ColorMask(0,0,0,1); GL_BlendFunc(GL_ONE, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // second pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(basetexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; if (r_shadow_rtlight->currentcubemap != r_texture_whitecube) { m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytolight; } GL_BlendFunc(GL_DST_ALPHA, GL_ONE); @@ -1661,35 +1710,45 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int // 1/2/2 3D combine path (original Radeon) memset(&m, 0, sizeof(m)); m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture); - m.pointer_texcoord3f[0] = rsurface_vertex3f; + m.pointer_texcoord3f[0] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[0] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[0] = rsurface.vertex3f_bufferoffset; m.texmatrix[0] = r_shadow_entitytoattenuationxyz; R_Mesh_TextureState(&m); GL_ColorMask(0,0,0,1); GL_BlendFunc(GL_ONE, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // second pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(normalmaptexture); m.texcombinergb[0] = GL_REPLACE; - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube); m.texcombinergb[1] = GL_DOT3_RGBA_ARB; - m.pointer_texcoord3f[1] = rsurface_array_texcoord3f; + m.pointer_texcoord3f[1] = rsurface.array_texcoord3f; + m.pointer_texcoord_bufferobject[1] = 0; + m.pointer_texcoord_bufferoffset[1] = 0; R_Mesh_TextureState(&m); GL_BlendFunc(GL_DST_ALPHA, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // second pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(basetexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; if (r_shadow_rtlight->currentcubemap != r_texture_whitecube) { m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytolight; } GL_BlendFunc(GL_DST_ALPHA, GL_ONE); @@ -1700,23 +1759,31 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(normalmaptexture); m.texcombinergb[0] = GL_REPLACE; - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube); m.texcombinergb[1] = GL_DOT3_RGBA_ARB; - m.pointer_texcoord3f[1] = rsurface_array_texcoord3f; + m.pointer_texcoord3f[1] = rsurface.array_texcoord3f; + m.pointer_texcoord_bufferobject[1] = 0; + m.pointer_texcoord_bufferoffset[1] = 0; R_Mesh_TextureState(&m); GL_ColorMask(0,0,0,1); GL_BlendFunc(GL_ONE, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // second pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(basetexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; m.tex3d[1] = R_GetTexture(r_shadow_attenuation3dtexture); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytoattenuationxyz; GL_BlendFunc(GL_DST_ALPHA, GL_ONE); } @@ -1726,31 +1793,43 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(normalmaptexture); m.texcombinergb[0] = GL_REPLACE; - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube); m.texcombinergb[1] = GL_DOT3_RGBA_ARB; - m.pointer_texcoord3f[1] = rsurface_array_texcoord3f; + m.pointer_texcoord3f[1] = rsurface.array_texcoord3f; + m.pointer_texcoord_bufferobject[1] = 0; + m.pointer_texcoord_bufferoffset[1] = 0; m.tex[2] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[2] = rsurface_vertex3f; + m.pointer_texcoord3f[2] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[2] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[2] = rsurface.vertex3f_bufferoffset; m.texmatrix[2] = r_shadow_entitytoattenuationxyz; m.tex[3] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[3] = rsurface_vertex3f; + m.pointer_texcoord3f[3] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[3] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[3] = rsurface.vertex3f_bufferoffset; m.texmatrix[3] = r_shadow_entitytoattenuationz; R_Mesh_TextureState(&m); GL_ColorMask(0,0,0,1); GL_BlendFunc(GL_ONE, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // second pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(basetexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; if (r_shadow_rtlight->currentcubemap != r_texture_whitecube) { m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytolight; } GL_BlendFunc(GL_DST_ALPHA, GL_ONE); @@ -1760,48 +1839,60 @@ static void R_Shadow_RenderLighting_Light_Dot3_DiffusePass(int firstvertex, int // 2/2/2 2D combine path (any dot3 card) memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[0] = rsurface_vertex3f; + m.pointer_texcoord3f[0] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[0] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[0] = rsurface.vertex3f_bufferoffset; m.texmatrix[0] = r_shadow_entitytoattenuationxyz; m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[0] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[0] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytoattenuationz; R_Mesh_TextureState(&m); GL_ColorMask(0,0,0,1); GL_BlendFunc(GL_ONE, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // second pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(normalmaptexture); m.texcombinergb[0] = GL_REPLACE; - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube); m.texcombinergb[1] = GL_DOT3_RGBA_ARB; - m.pointer_texcoord3f[1] = rsurface_array_texcoord3f; + m.pointer_texcoord3f[1] = rsurface.array_texcoord3f; + m.pointer_texcoord_bufferobject[1] = 0; + m.pointer_texcoord_bufferoffset[1] = 0; R_Mesh_TextureState(&m); GL_BlendFunc(GL_DST_ALPHA, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // second pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(basetexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; if (r_shadow_rtlight->currentcubemap != r_texture_whitecube) { m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytolight; } GL_BlendFunc(GL_DST_ALPHA, GL_ONE); } // this final code is shared R_Mesh_TextureState(&m); - R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale); + R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale); } -static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int numvertices, int numtriangles, const int *element3i, const vec3_t lightcolorbase, rtexture_t *glosstexture, rtexture_t *normalmaptexture, float colorscale) +static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, rtexture_t *glosstexture, rtexture_t *normalmaptexture, float colorscale) { float glossexponent; rmeshstate_t m; @@ -1816,42 +1907,52 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int // 2/0/0/1/2 3D combine blendsquare path memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(normalmaptexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube); m.texcombinergb[1] = GL_DOT3_RGBA_ARB; - m.pointer_texcoord3f[1] = rsurface_array_texcoord3f; + m.pointer_texcoord3f[1] = rsurface.array_texcoord3f; + m.pointer_texcoord_bufferobject[1] = 0; + m.pointer_texcoord_bufferoffset[1] = 0; R_Mesh_TextureState(&m); GL_ColorMask(0,0,0,1); // this squares the result GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // second and third pass R_Mesh_ResetTextureState(); // square alpha in framebuffer a few times to make it shiny GL_BlendFunc(GL_ZERO, GL_DST_ALPHA); for (glossexponent = 2;glossexponent * 2 <= r_shadow_glossexponent.value;glossexponent *= 2) - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // fourth pass memset(&m, 0, sizeof(m)); m.tex3d[0] = R_GetTexture(r_shadow_attenuation3dtexture); - m.pointer_texcoord3f[0] = rsurface_vertex3f; + m.pointer_texcoord3f[0] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[0] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[0] = rsurface.vertex3f_bufferoffset; m.texmatrix[0] = r_shadow_entitytoattenuationxyz; R_Mesh_TextureState(&m); GL_BlendFunc(GL_DST_ALPHA, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // fifth pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(glosstexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; if (r_shadow_rtlight->currentcubemap != r_texture_whitecube) { m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytolight; } GL_BlendFunc(GL_DST_ALPHA, GL_ONE); @@ -1861,31 +1962,39 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int // 2/0/0/2 3D combine blendsquare path memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(normalmaptexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube); m.texcombinergb[1] = GL_DOT3_RGBA_ARB; - m.pointer_texcoord3f[1] = rsurface_array_texcoord3f; + m.pointer_texcoord3f[1] = rsurface.array_texcoord3f; + m.pointer_texcoord_bufferobject[1] = 0; + m.pointer_texcoord_bufferoffset[1] = 0; R_Mesh_TextureState(&m); GL_ColorMask(0,0,0,1); // this squares the result GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // second and third pass R_Mesh_ResetTextureState(); // square alpha in framebuffer a few times to make it shiny GL_BlendFunc(GL_ZERO, GL_DST_ALPHA); for (glossexponent = 2;glossexponent * 2 <= r_shadow_glossexponent.value;glossexponent *= 2) - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // fourth pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(glosstexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; m.tex3d[1] = R_GetTexture(r_shadow_attenuation3dtexture); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytoattenuationxyz; GL_BlendFunc(GL_DST_ALPHA, GL_ONE); } @@ -1894,55 +2003,67 @@ static void R_Shadow_RenderLighting_Light_Dot3_SpecularPass(int firstvertex, int // 2/0/0/2/2 2D combine blendsquare path memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(normalmaptexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; m.texcubemap[1] = R_GetTexture(r_texture_normalizationcube); m.texcombinergb[1] = GL_DOT3_RGBA_ARB; - m.pointer_texcoord3f[1] = rsurface_array_texcoord3f; + m.pointer_texcoord3f[1] = rsurface.array_texcoord3f; + m.pointer_texcoord_bufferobject[1] = 0; + m.pointer_texcoord_bufferoffset[1] = 0; R_Mesh_TextureState(&m); GL_ColorMask(0,0,0,1); // this squares the result GL_BlendFunc(GL_SRC_ALPHA, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // second and third pass R_Mesh_ResetTextureState(); // square alpha in framebuffer a few times to make it shiny GL_BlendFunc(GL_ZERO, GL_DST_ALPHA); for (glossexponent = 2;glossexponent * 2 <= r_shadow_glossexponent.value;glossexponent *= 2) - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // fourth pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[0] = rsurface_vertex3f; + m.pointer_texcoord3f[0] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[0] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[0] = rsurface.vertex3f_bufferoffset; m.texmatrix[0] = r_shadow_entitytoattenuationxyz; m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytoattenuationz; R_Mesh_TextureState(&m); GL_BlendFunc(GL_DST_ALPHA, GL_ZERO); - R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i); + R_Mesh_Draw(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); // fifth pass memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(glosstexture); - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; - m.texmatrix[0] = rsurface_texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; if (r_shadow_rtlight->currentcubemap != r_texture_whitecube) { m.texcubemap[1] = R_GetTexture(r_shadow_rtlight->currentcubemap); - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; m.texmatrix[1] = r_shadow_entitytolight; } GL_BlendFunc(GL_DST_ALPHA, GL_ONE); } // this final code is shared R_Mesh_TextureState(&m); - R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale); + R_Shadow_RenderLighting_Light_Dot3_Finalize(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase[0] * colorscale, lightcolorbase[1] * colorscale, lightcolorbase[2] * colorscale); } -static void R_Shadow_RenderLighting_Light_Dot3(int firstvertex, int numvertices, int numtriangles, const int *element3i, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt) +static void R_Shadow_RenderLighting_Light_Dot3(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt) { // ARB path (any Geforce, any Radeon) qboolean doambient = ambientscale > 0; @@ -1950,30 +2071,30 @@ static void R_Shadow_RenderLighting_Light_Dot3(int firstvertex, int numvertices, qboolean dospecular = specularscale > 0; if (!doambient && !dodiffuse && !dospecular) return; - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); if (doambient) - R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, lightcolorbase, basetexture, ambientscale * r_view.colorscale); + R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, basetexture, ambientscale * r_view.colorscale); if (dodiffuse) - R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, lightcolorbase, basetexture, normalmaptexture, diffusescale * r_view.colorscale); + R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, basetexture, normalmaptexture, diffusescale * r_view.colorscale); if (dopants) { if (doambient) - R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, lightcolorpants, pantstexture, ambientscale * r_view.colorscale); + R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorpants, pantstexture, ambientscale * r_view.colorscale); if (dodiffuse) - R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, lightcolorpants, pantstexture, normalmaptexture, diffusescale * r_view.colorscale); + R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorpants, pantstexture, normalmaptexture, diffusescale * r_view.colorscale); } if (doshirt) { if (doambient) - R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, lightcolorshirt, shirttexture, ambientscale * r_view.colorscale); + R_Shadow_RenderLighting_Light_Dot3_AmbientPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorshirt, shirttexture, ambientscale * r_view.colorscale); if (dodiffuse) - R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, lightcolorshirt, shirttexture, normalmaptexture, diffusescale * r_view.colorscale); + R_Shadow_RenderLighting_Light_Dot3_DiffusePass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorshirt, shirttexture, normalmaptexture, diffusescale * r_view.colorscale); } if (dospecular) - R_Shadow_RenderLighting_Light_Dot3_SpecularPass(firstvertex, numvertices, numtriangles, element3i, lightcolorbase, glosstexture, normalmaptexture, specularscale * r_view.colorscale); + R_Shadow_RenderLighting_Light_Dot3_SpecularPass(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, glosstexture, normalmaptexture, specularscale * r_view.colorscale); } -void R_Shadow_RenderLighting_Light_Vertex_Pass(const model_t *model, int firstvertex, int numvertices, int numtriangles, const int *element3i, vec3_t diffusecolor2, vec3_t ambientcolor2) +void R_Shadow_RenderLighting_Light_Vertex_Pass(const model_t *model, int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, vec3_t diffusecolor2, vec3_t ambientcolor2) { int renders; int i; @@ -1984,7 +2105,7 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(const model_t *model, int firstve int *newe; const int *e; float *c; - int newelements[3072]; + int newelements[4096*3]; R_Shadow_RenderLighting_Light_Vertex_Shading(firstvertex, numvertices, numtriangles, element3i, diffusecolor2, ambientcolor2); for (renders = 0;renders < 64;renders++) { @@ -2000,7 +2121,7 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(const model_t *model, int firstve // renders them at once for (i = 0, e = element3i;i < numtriangles;i++, e += 3) { - if (VectorLength2(rsurface_array_color4f + e[0] * 4) + VectorLength2(rsurface_array_color4f + e[1] * 4) + VectorLength2(rsurface_array_color4f + e[2] * 4) >= 0.01) + if (VectorLength2(rsurface.array_color4f + e[0] * 4) + VectorLength2(rsurface.array_color4f + e[1] * 4) + VectorLength2(rsurface.array_color4f + e[2] * 4) >= 0.01) { if (newnumtriangles) { @@ -2021,9 +2142,9 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(const model_t *model, int firstve newe[2] = e[2]; newnumtriangles++; newe += 3; - if (newnumtriangles >= 1024) + if (newnumtriangles >= (int)(sizeof(newelements)/sizeof(float[3]))) { - R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, newnumtriangles, newelements); + R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, newnumtriangles, newelements, 0, 0); newnumtriangles = 0; newe = newelements; stop = false; @@ -2032,7 +2153,11 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(const model_t *model, int firstve } if (newnumtriangles >= 1) { - R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, newnumtriangles, newelements); + // if all triangles are included, use the original array to take advantage of the bufferobject if possible + if (newnumtriangles == numtriangles) + R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset); + else + R_Mesh_Draw(newfirstvertex, newlastvertex - newfirstvertex + 1, newnumtriangles, newelements, 0, 0); stop = false; } // if we couldn't find any lit triangles, exit early @@ -2043,7 +2168,7 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(const model_t *model, int firstve // handling of negative colors // (some old drivers even have improper handling of >1 color) stop = true; - for (i = 0, c = rsurface_array_color4f + 4 * firstvertex;i < numvertices;i++, c += 4) + for (i = 0, c = rsurface.array_color4f + 4 * firstvertex;i < numvertices;i++, c += 4) { if (c[0] > 1 || c[1] > 1 || c[2] > 1) { @@ -2061,10 +2186,10 @@ void R_Shadow_RenderLighting_Light_Vertex_Pass(const model_t *model, int firstve } } -static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertices, int numtriangles, const int *element3i, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt) +static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset, const vec3_t lightcolorbase, const vec3_t lightcolorpants, const vec3_t lightcolorshirt, rtexture_t *basetexture, rtexture_t *pantstexture, rtexture_t *shirttexture, rtexture_t *normalmaptexture, rtexture_t *glosstexture, float ambientscale, float diffusescale, float specularscale, qboolean dopants, qboolean doshirt) { // OpenGL 1.1 path (anything) - model_t *model = rsurface_entity->model; + const model_t *model = rsurface.model; float ambientcolorbase[3], diffusecolorbase[3]; float ambientcolorpants[3], diffusecolorpants[3]; float ambientcolorshirt[3], diffusecolorshirt[3]; @@ -2076,52 +2201,57 @@ static void R_Shadow_RenderLighting_Light_Vertex(int firstvertex, int numvertice VectorScale(lightcolorshirt, ambientscale * 2 * r_view.colorscale, ambientcolorshirt); VectorScale(lightcolorshirt, diffusescale * 2 * r_view.colorscale, diffusecolorshirt); GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); - R_Mesh_ColorPointer(rsurface_array_color4f); + R_Mesh_ColorPointer(rsurface.array_color4f, 0, 0); memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(basetexture); - m.texmatrix[0] = rsurface_texture->currenttexmatrix; - m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordtexture2f; + m.texmatrix[0] = rsurface.texture->currenttexmatrix; + m.pointer_texcoord[0] = rsurface.model->surfmesh.data_texcoordtexture2f; + m.pointer_texcoord_bufferobject[0] = rsurface.model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface.model->surfmesh.vbooffset_texcoordtexture2f; if (r_textureunits.integer >= 2) { // voodoo2 or TNT m.tex[1] = R_GetTexture(r_shadow_attenuation2dtexture); m.texmatrix[1] = r_shadow_entitytoattenuationxyz; - m.pointer_texcoord3f[1] = rsurface_vertex3f; + m.pointer_texcoord3f[1] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[1] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[1] = rsurface.vertex3f_bufferoffset; if (r_textureunits.integer >= 3) { // Voodoo4 or Kyro (or Geforce3/Radeon with gl_combine off) m.tex[2] = R_GetTexture(r_shadow_attenuation2dtexture); m.texmatrix[2] = r_shadow_entitytoattenuationz; - m.pointer_texcoord3f[2] = rsurface_vertex3f; + m.pointer_texcoord3f[2] = rsurface.vertex3f; + m.pointer_texcoord_bufferobject[2] = rsurface.vertex3f_bufferobject; + m.pointer_texcoord_bufferoffset[2] = rsurface.vertex3f_bufferoffset; } } R_Mesh_TextureState(&m); //R_Mesh_TexBind(0, R_GetTexture(basetexture)); - R_Shadow_RenderLighting_Light_Vertex_Pass(model, firstvertex, numvertices, numtriangles, element3i, diffusecolorbase, ambientcolorbase); + R_Shadow_RenderLighting_Light_Vertex_Pass(model, firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, diffusecolorbase, ambientcolorbase); if (dopants) { R_Mesh_TexBind(0, R_GetTexture(pantstexture)); - R_Shadow_RenderLighting_Light_Vertex_Pass(model, firstvertex, numvertices, numtriangles, element3i, diffusecolorpants, ambientcolorpants); + R_Shadow_RenderLighting_Light_Vertex_Pass(model, firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, diffusecolorpants, ambientcolorpants); } if (doshirt) { R_Mesh_TexBind(0, R_GetTexture(shirttexture)); - R_Shadow_RenderLighting_Light_Vertex_Pass(model, firstvertex, numvertices, numtriangles, element3i, diffusecolorshirt, ambientcolorshirt); + R_Shadow_RenderLighting_Light_Vertex_Pass(model, firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, diffusecolorshirt, ambientcolorshirt); } } -void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles, const int *element3i) +void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles, const int *element3i, int element3i_bufferobject, size_t element3i_bufferoffset) { float ambientscale, diffusescale, specularscale; - // FIXME: support MATERIALFLAG_NODEPTHTEST vec3_t lightcolorbase, lightcolorpants, lightcolorshirt; // calculate colors to render this texture with - lightcolorbase[0] = r_shadow_rtlight->currentcolor[0] * rsurface_entity->colormod[0] * rsurface_texture->currentalpha; - lightcolorbase[1] = r_shadow_rtlight->currentcolor[1] * rsurface_entity->colormod[1] * rsurface_texture->currentalpha; - lightcolorbase[2] = r_shadow_rtlight->currentcolor[2] * rsurface_entity->colormod[2] * rsurface_texture->currentalpha; + lightcolorbase[0] = r_shadow_rtlight->currentcolor[0] * rsurface.texture->currentlayers[0].color[0] * rsurface.texture->currentlayers[0].color[3]; + lightcolorbase[1] = r_shadow_rtlight->currentcolor[1] * rsurface.texture->currentlayers[0].color[1] * rsurface.texture->currentlayers[0].color[3]; + lightcolorbase[2] = r_shadow_rtlight->currentcolor[2] * rsurface.texture->currentlayers[0].color[2] * rsurface.texture->currentlayers[0].color[3]; ambientscale = r_shadow_rtlight->ambientscale; diffusescale = r_shadow_rtlight->diffusescale; - specularscale = specularscale; + specularscale = r_shadow_rtlight->specularscale * rsurface.texture->specularscale; if (!r_shadow_usenormalmap.integer) { ambientscale += 1.0f * diffusescale; @@ -2130,42 +2260,43 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles, } if ((ambientscale + diffusescale) * VectorLength2(lightcolorbase) + specularscale * VectorLength2(lightcolorbase) < (1.0f / 1048576.0f)) return; - GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST)); - GL_CullFace((rsurface_texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces - if (rsurface_texture->colormapping) + GL_DepthRange(0, (rsurface.texture->currentmaterialflags & MATERIALFLAG_SHORTDEPTHRANGE) ? 0.0625 : 1); + GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST)); + GL_CullFace((rsurface.texture->currentmaterialflags & MATERIALFLAG_NOCULLFACE) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces + if (rsurface.texture->colormapping) { - qboolean dopants = rsurface_texture->currentskinframe->pants != NULL && VectorLength2(rsurface_entity->colormap_pantscolor) >= (1.0f / 1048576.0f); - qboolean doshirt = rsurface_texture->currentskinframe->shirt != NULL && VectorLength2(rsurface_entity->colormap_shirtcolor) >= (1.0f / 1048576.0f); + qboolean dopants = rsurface.texture->currentskinframe->pants != NULL && VectorLength2(rsurface.colormap_pantscolor) >= (1.0f / 1048576.0f); + qboolean doshirt = rsurface.texture->currentskinframe->shirt != NULL && VectorLength2(rsurface.colormap_shirtcolor) >= (1.0f / 1048576.0f); if (dopants) { - lightcolorpants[0] = lightcolorbase[0] * rsurface_entity->colormap_pantscolor[0]; - lightcolorpants[1] = lightcolorbase[1] * rsurface_entity->colormap_pantscolor[1]; - lightcolorpants[2] = lightcolorbase[2] * rsurface_entity->colormap_pantscolor[2]; + lightcolorpants[0] = lightcolorbase[0] * rsurface.colormap_pantscolor[0]; + lightcolorpants[1] = lightcolorbase[1] * rsurface.colormap_pantscolor[1]; + lightcolorpants[2] = lightcolorbase[2] * rsurface.colormap_pantscolor[2]; } else VectorClear(lightcolorpants); if (doshirt) { - lightcolorshirt[0] = lightcolorbase[0] * rsurface_entity->colormap_shirtcolor[0]; - lightcolorshirt[1] = lightcolorbase[1] * rsurface_entity->colormap_shirtcolor[1]; - lightcolorshirt[2] = lightcolorbase[2] * rsurface_entity->colormap_shirtcolor[2]; + lightcolorshirt[0] = lightcolorbase[0] * rsurface.colormap_shirtcolor[0]; + lightcolorshirt[1] = lightcolorbase[1] * rsurface.colormap_shirtcolor[1]; + lightcolorshirt[2] = lightcolorbase[2] * rsurface.colormap_shirtcolor[2]; } else VectorClear(lightcolorshirt); switch (r_shadow_rendermode) { case R_SHADOW_RENDERMODE_VISIBLELIGHTING: - GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) && !r_showdisabledepthtest.integer); - R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, numtriangles, element3i, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface_texture->basetexture, rsurface_texture->currentskinframe->pants, rsurface_texture->currentskinframe->shirt, rsurface_texture->currentskinframe->nmap, rsurface_texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt); + GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) && !r_showdisabledepthtest.integer); + R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, rsurface.texture->currentskinframe->nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt); break; case R_SHADOW_RENDERMODE_LIGHT_GLSL: - R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, numtriangles, element3i, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface_texture->basetexture, rsurface_texture->currentskinframe->pants, rsurface_texture->currentskinframe->shirt, rsurface_texture->currentskinframe->nmap, rsurface_texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt); + R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, rsurface.texture->currentskinframe->nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt); break; case R_SHADOW_RENDERMODE_LIGHT_DOT3: - R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, numtriangles, element3i, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface_texture->basetexture, rsurface_texture->currentskinframe->pants, rsurface_texture->currentskinframe->shirt, rsurface_texture->currentskinframe->nmap, rsurface_texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt); + R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, rsurface.texture->currentskinframe->nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt); break; case R_SHADOW_RENDERMODE_LIGHT_VERTEX: - R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface_texture->basetexture, rsurface_texture->currentskinframe->pants, rsurface_texture->currentskinframe->shirt, rsurface_texture->currentskinframe->nmap, rsurface_texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt); + R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, lightcolorpants, lightcolorshirt, rsurface.texture->basetexture, rsurface.texture->currentskinframe->pants, rsurface.texture->currentskinframe->shirt, rsurface.texture->currentskinframe->nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, dopants, doshirt); break; default: Con_Printf("R_Shadow_RenderLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode); @@ -2177,17 +2308,17 @@ void R_Shadow_RenderLighting(int firstvertex, int numvertices, int numtriangles, switch (r_shadow_rendermode) { case R_SHADOW_RENDERMODE_VISIBLELIGHTING: - GL_DepthTest(!(rsurface_texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) && !r_showdisabledepthtest.integer); - R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, numtriangles, element3i, lightcolorbase, vec3_origin, vec3_origin, rsurface_texture->basetexture, r_texture_black, r_texture_black, rsurface_texture->currentskinframe->nmap, rsurface_texture->glosstexture, ambientscale, diffusescale, specularscale, false, false); + GL_DepthTest(!(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) && !r_showdisabledepthtest.integer); + R_Shadow_RenderLighting_VisibleLighting(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, rsurface.texture->currentskinframe->nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false); break; case R_SHADOW_RENDERMODE_LIGHT_GLSL: - R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, numtriangles, element3i, lightcolorbase, vec3_origin, vec3_origin, rsurface_texture->basetexture, r_texture_black, r_texture_black, rsurface_texture->currentskinframe->nmap, rsurface_texture->glosstexture, ambientscale, diffusescale, specularscale, false, false); + R_Shadow_RenderLighting_Light_GLSL(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, rsurface.texture->currentskinframe->nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false); break; case R_SHADOW_RENDERMODE_LIGHT_DOT3: - R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, numtriangles, element3i, lightcolorbase, vec3_origin, vec3_origin, rsurface_texture->basetexture, r_texture_black, r_texture_black, rsurface_texture->currentskinframe->nmap, rsurface_texture->glosstexture, ambientscale, diffusescale, specularscale, false, false); + R_Shadow_RenderLighting_Light_Dot3(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, rsurface.texture->currentskinframe->nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false); break; case R_SHADOW_RENDERMODE_LIGHT_VERTEX: - R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i, lightcolorbase, vec3_origin, vec3_origin, rsurface_texture->basetexture, r_texture_black, r_texture_black, rsurface_texture->currentskinframe->nmap, rsurface_texture->glosstexture, ambientscale, diffusescale, specularscale, false, false); + R_Shadow_RenderLighting_Light_Vertex(firstvertex, numvertices, numtriangles, element3i, element3i_bufferobject, element3i_bufferoffset, lightcolorbase, vec3_origin, vec3_origin, rsurface.texture->basetexture, r_texture_black, r_texture_black, rsurface.texture->currentskinframe->nmap, rsurface.texture->glosstexture, ambientscale, diffusescale, specularscale, false, false); break; default: Con_Printf("R_Shadow_RenderLighting: unknown r_shadow_rendermode %i\n", r_shadow_rendermode); @@ -2526,19 +2657,19 @@ void R_Shadow_DrawWorldShadow(int numsurfaces, int *surfacelist, const unsigned for (mesh = r_shadow_rtlight->static_meshchain_shadow;mesh;mesh = mesh->next) { r_refdef.stats.lights_shadowtriangles += mesh->numtriangles; - R_Mesh_VertexPointer(mesh->vertex3f); + R_Mesh_VertexPointer(mesh->vertex3f, mesh->vbo, mesh->vbooffset_vertex3f); GL_LockArrays(0, mesh->numverts); if (r_shadow_rendermode == R_SHADOW_RENDERMODE_STENCIL) { // decrement stencil if backface is behind depthbuffer GL_CullFace(GL_BACK); // quake is backwards, this culls front faces qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);CHECKGLERROR - R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i); + R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->ebo, 0); // increment stencil if frontface is behind depthbuffer GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);CHECKGLERROR } - R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i); + R_Mesh_Draw(0, mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->ebo, 0); GL_LockArrays(0, 0); } CHECKGLERROR @@ -2620,15 +2751,19 @@ void R_Shadow_DrawEntityLight(entity_render_t *ent, int numsurfaces, int *surfac void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) { - int i, usestencil; + int i; float f; int numleafs, numsurfaces; int *leaflist, *surfacelist; unsigned char *leafpvs, *shadowtrispvs, *lighttrispvs; int numlightentities; + int numlightentities_noselfshadow; int numshadowentities; + int numshadowentities_noselfshadow; entity_render_t *lightentities[MAX_EDICTS]; + entity_render_t *lightentities_noselfshadow[MAX_EDICTS]; entity_render_t *shadowentities[MAX_EDICTS]; + entity_render_t *shadowentities_noselfshadow[MAX_EDICTS]; // skip lights that don't light because of ambientscale+diffusescale+specularscale being 0 (corona only lights) // skip lights that are basically invisible (color 0 0 0) @@ -2721,7 +2856,9 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) // make a list of lit entities and shadow casting entities numlightentities = 0; + numlightentities_noselfshadow = 0; numshadowentities = 0; + numshadowentities_noselfshadow = 0; // add dynamic entities that are lit by the light if (r_drawentities.integer) { @@ -2746,12 +2883,26 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) // so now check if it's in a leaf seen by the light if (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingLeafPVS && !r_refdef.worldmodel->brush.BoxTouchingLeafPVS(r_refdef.worldmodel, leafpvs, ent->mins, ent->maxs)) continue; - lightentities[numlightentities++] = ent; + if (ent->flags & RENDER_NOSELFSHADOW) + lightentities_noselfshadow[numlightentities_noselfshadow++] = ent; + else + lightentities[numlightentities++] = ent; // since it is lit, it probably also casts a shadow... // about the VectorDistance2 - light emitting entities should not cast their own shadow Matrix4x4_OriginFromMatrix(&ent->matrix, org); if ((ent->flags & RENDER_SHADOW) && model->DrawShadowVolume && VectorDistance2(org, rtlight->shadoworigin) > 0.1) - shadowentities[numshadowentities++] = ent; + { + // note: exterior models without the RENDER_NOSELFSHADOW + // flag still create a RENDER_NOSELFSHADOW shadow but + // are lit normally, this means that they are + // self-shadowing but do not shadow other + // RENDER_NOSELFSHADOW entities such as the gun + // (very weird, but keeps the player shadow off the gun) + if (ent->flags & (RENDER_NOSELFSHADOW | RENDER_EXTERIORMODEL)) + shadowentities_noselfshadow[numshadowentities_noselfshadow++] = ent; + else + shadowentities[numshadowentities++] = ent; + } } else if (ent->flags & RENDER_SHADOW) { @@ -2764,7 +2915,12 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) // about the VectorDistance2 - light emitting entities should not cast their own shadow Matrix4x4_OriginFromMatrix(&ent->matrix, org); if ((ent->flags & RENDER_SHADOW) && model->DrawShadowVolume && VectorDistance2(org, rtlight->shadoworigin) > 0.1) - shadowentities[numshadowentities++] = ent; + { + if (ent->flags & (RENDER_NOSELFSHADOW | RENDER_EXTERIORMODEL)) + shadowentities_noselfshadow[numshadowentities_noselfshadow++] = ent; + else + shadowentities[numshadowentities++] = ent; + } } } } @@ -2782,51 +2938,95 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) // count this light in the r_speeds r_refdef.stats.lights++; - usestencil = false; - if (numsurfaces + numshadowentities && rtlight->shadow && (rtlight->isstatic ? r_refdef.rtworldshadows : r_refdef.rtdlightshadows)) + if (r_showshadowvolumes.integer && numsurfaces + numshadowentities + numshadowentities_noselfshadow && rtlight->shadow && (rtlight->isstatic ? r_refdef.rtworldshadows : r_refdef.rtdlightshadows)) + { + // optionally draw visible shape of the shadow volumes + // for performance analysis by level designers + R_Shadow_RenderMode_VisibleShadowVolumes(); + if (numsurfaces) + R_Shadow_DrawWorldShadow(numsurfaces, surfacelist, shadowtrispvs); + for (i = 0;i < numshadowentities;i++) + R_Shadow_DrawEntityShadow(shadowentities[i]); + for (i = 0;i < numshadowentities_noselfshadow;i++) + R_Shadow_DrawEntityShadow(shadowentities_noselfshadow[i]); + } + + if (gl_stencil && numsurfaces + numshadowentities + numshadowentities_noselfshadow && rtlight->shadow && (rtlight->isstatic ? r_refdef.rtworldshadows : r_refdef.rtdlightshadows)) { // draw stencil shadow volumes to mask off pixels that are in shadow // so that they won't receive lighting - if (gl_stencil) + R_Shadow_RenderMode_StencilShadowVolumes(true); + if (numsurfaces) + R_Shadow_DrawWorldShadow(numsurfaces, surfacelist, shadowtrispvs); + for (i = 0;i < numshadowentities;i++) + R_Shadow_DrawEntityShadow(shadowentities[i]); + if (numlightentities_noselfshadow) { - usestencil = true; - R_Shadow_RenderMode_StencilShadowVolumes(); - if (numsurfaces) - R_Shadow_DrawWorldShadow(numsurfaces, surfacelist, shadowtrispvs); - for (i = 0;i < numshadowentities;i++) - R_Shadow_DrawEntityShadow(shadowentities[i]); + // draw lighting in the unmasked areas + R_Shadow_RenderMode_Lighting(true, false); + for (i = 0;i < numlightentities_noselfshadow;i++) + R_Shadow_DrawEntityLight(lightentities_noselfshadow[i], numsurfaces, surfacelist); + + // optionally draw the illuminated areas + // for performance analysis by level designers + if (r_showlighting.integer) + { + R_Shadow_RenderMode_VisibleLighting(!r_showdisabledepthtest.integer, false); + for (i = 0;i < numlightentities_noselfshadow;i++) + R_Shadow_DrawEntityLight(lightentities_noselfshadow[i], numsurfaces, surfacelist); + } + + R_Shadow_RenderMode_StencilShadowVolumes(false); } + for (i = 0;i < numshadowentities_noselfshadow;i++) + R_Shadow_DrawEntityShadow(shadowentities_noselfshadow[i]); - // optionally draw visible shape of the shadow volumes - // for performance analysis by level designers - if (r_showshadowvolumes.integer) + if (numsurfaces + numlightentities) { - R_Shadow_RenderMode_VisibleShadowVolumes(); + // draw lighting in the unmasked areas + R_Shadow_RenderMode_Lighting(true, false); if (numsurfaces) - R_Shadow_DrawWorldShadow(numsurfaces, surfacelist, shadowtrispvs); - for (i = 0;i < numshadowentities;i++) - R_Shadow_DrawEntityShadow(shadowentities[i]); + R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs); + for (i = 0;i < numlightentities;i++) + R_Shadow_DrawEntityLight(lightentities[i], numsurfaces, surfacelist); + + // optionally draw the illuminated areas + // for performance analysis by level designers + if (r_showlighting.integer) + { + R_Shadow_RenderMode_VisibleLighting(!r_showdisabledepthtest.integer, false); + if (numsurfaces) + R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs); + for (i = 0;i < numlightentities;i++) + R_Shadow_DrawEntityLight(lightentities[i], numsurfaces, surfacelist); + } } } - - if (numsurfaces + numlightentities) + else { - // draw lighting in the unmasked areas - R_Shadow_RenderMode_Lighting(usestencil, false); - if (numsurfaces) - R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs); - for (i = 0;i < numlightentities;i++) - R_Shadow_DrawEntityLight(lightentities[i], numsurfaces, surfacelist); - - // optionally draw the illuminated areas - // for performance analysis by level designers - if (r_showlighting.integer) + if (numsurfaces + numlightentities) { - R_Shadow_RenderMode_VisibleLighting(usestencil && !r_showdisabledepthtest.integer, false); + // draw lighting in the unmasked areas + R_Shadow_RenderMode_Lighting(false, false); if (numsurfaces) R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs); for (i = 0;i < numlightentities;i++) R_Shadow_DrawEntityLight(lightentities[i], numsurfaces, surfacelist); + for (i = 0;i < numlightentities_noselfshadow;i++) + R_Shadow_DrawEntityLight(lightentities_noselfshadow[i], numsurfaces, surfacelist); + + // optionally draw the illuminated areas + // for performance analysis by level designers + if (r_showlighting.integer) + { + R_Shadow_RenderMode_VisibleLighting(false, false); + if (numsurfaces) + R_Shadow_DrawWorldLight(numsurfaces, surfacelist, lighttrispvs); + for (i = 0;i < numlightentities;i++) + R_Shadow_DrawEntityLight(lightentities[i], numsurfaces, surfacelist); + for (i = 0;i < numlightentities_noselfshadow;i++) + R_Shadow_DrawEntityLight(lightentities_noselfshadow[i], numsurfaces, surfacelist); + } } } } @@ -2890,7 +3090,7 @@ void R_DrawModelShadows(void) else r_shadow_shadowingrendermode = R_SHADOW_RENDERMODE_STENCIL; - R_Shadow_RenderMode_StencilShadowVolumes(); + R_Shadow_RenderMode_StencilShadowVolumes(true); for (i = 0;i < r_refdef.numentities;i++) { @@ -2924,11 +3124,12 @@ void R_DrawModelShadows(void) GL_ScissorTest(true); R_Mesh_Matrix(&identitymatrix); R_Mesh_ResetTextureState(); - R_Mesh_VertexPointer(vertex3f); - R_Mesh_ColorPointer(NULL); + R_Mesh_VertexPointer(vertex3f, 0, 0); + R_Mesh_ColorPointer(NULL, 0, 0); // set up a 50% darkening blend on shadowed areas GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + GL_DepthRange(0, 1); GL_DepthTest(false); GL_DepthMask(false); qglPolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);CHECKGLERROR @@ -2941,7 +3142,7 @@ void R_DrawModelShadows(void) qglStencilFunc(GL_NOTEQUAL, 128, ~0);CHECKGLERROR // apply the blend to the shadowed areas - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); // restoring the perspective view is done by R_RenderScene //R_SetupView(&r_view.matrix); @@ -3148,7 +3349,7 @@ void R_Shadow_DrawCursor_TransparentCallback(const entity_render_t *ent, const r { // this is never batched (there can be only one) float scale = r_editlights_cursorgrid.value * 0.5f; - R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_crosshairs[1]->tex, NULL, false, r_editlights_cursorlocation, r_view.right, r_view.up, scale, -scale, -scale, scale, 1, 1, 1, 0.5f); + R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_crosshairs[1]->tex, NULL, false, false, r_editlights_cursorlocation, r_view.right, r_view.up, scale, -scale, -scale, scale, 1, 1, 1, 0.5f); } void R_Shadow_DrawLightSprite_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist) @@ -3162,7 +3363,7 @@ void R_Shadow_DrawLightSprite_TransparentCallback(const entity_render_t *ent, co intensity = 0.75 + 0.25 * sin(realtime * M_PI * 4.0); if (!light->shadow) intensity *= 0.5f; - R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_crosshairs[surfacelist[0]]->tex, NULL, false, light->origin, r_view.right, r_view.up, 8, -8, -8, 8, intensity, intensity, intensity, 0.5); + R_DrawSprite(GL_SRC_ALPHA, GL_ONE, r_crosshairs[surfacelist[0]]->tex, NULL, false, false, light->origin, r_view.right, r_view.up, 8, -8, -8, 8, intensity, intensity, intensity, 0.5f); } void R_Shadow_DrawLightSprites(void) @@ -3415,7 +3616,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void) data = r_refdef.worldmodel->brush.entities; if (!data) return; - for (entnum = 0;COM_ParseTokenConsole(&data) && com_token[0] == '{';entnum++) + for (entnum = 0;COM_ParseToken_Simple(&data, false) && com_token[0] == '{';entnum++) { type = LIGHTTYPE_MINUSX; origin[0] = origin[1] = origin[2] = 0; @@ -3433,7 +3634,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void) islight = false; while (1) { - if (!COM_ParseTokenConsole(&data)) + if (!COM_ParseToken_Simple(&data, false)) break; // error if (com_token[0] == '}') break; // end of entity @@ -3443,7 +3644,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void) strlcpy(key, com_token, sizeof(key)); while (key[strlen(key)-1] == ' ') // remove trailing spaces key[strlen(key)-1] = 0; - if (!COM_ParseTokenConsole(&data)) + if (!COM_ParseToken_Simple(&data, false)) break; // error strlcpy(value, com_token, sizeof(value)); @@ -4051,24 +4252,24 @@ void R_Shadow_EditLights_DrawSelectedLightProperties(void) for (lightcount = 0, light = r_shadow_worldlightchain;light;lightcount++, light = light->next) if (light == r_shadow_selectedlight) lightnumber = lightcount; - sprintf(temp, "Cursor %f %f %f Total Lights %i", r_editlights_cursorlocation[0], r_editlights_cursorlocation[1], r_editlights_cursorlocation[2], lightcount);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; + sprintf(temp, "Cursor %f %f %f Total Lights %i", r_editlights_cursorlocation[0], r_editlights_cursorlocation[1], r_editlights_cursorlocation[2], lightcount);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; if (r_shadow_selectedlight == NULL) return; - sprintf(temp, "Light #%i properties", lightnumber);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Origin : %f %f %f\n", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Angles : %f %f %f\n", r_shadow_selectedlight->angles[0], r_shadow_selectedlight->angles[1], r_shadow_selectedlight->angles[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Color : %f %f %f\n", r_shadow_selectedlight->color[0], r_shadow_selectedlight->color[1], r_shadow_selectedlight->color[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Radius : %f\n", r_shadow_selectedlight->radius);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Corona : %f\n", r_shadow_selectedlight->corona);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Style : %i\n", r_shadow_selectedlight->style);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Shadows : %s\n", r_shadow_selectedlight->shadow ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Cubemap : %s\n", r_shadow_selectedlight->cubemapname);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "CoronaSize : %f\n", r_shadow_selectedlight->coronasizescale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Ambient : %f\n", r_shadow_selectedlight->ambientscale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Diffuse : %f\n", r_shadow_selectedlight->diffusescale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "Specular : %f\n", r_shadow_selectedlight->specularscale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "NormalMode : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_NORMALMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; - sprintf(temp, "RealTimeMode : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_REALTIMEMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0);y += 8; + sprintf(temp, "Light #%i properties", lightnumber);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "Origin : %f %f %f\n", r_shadow_selectedlight->origin[0], r_shadow_selectedlight->origin[1], r_shadow_selectedlight->origin[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "Angles : %f %f %f\n", r_shadow_selectedlight->angles[0], r_shadow_selectedlight->angles[1], r_shadow_selectedlight->angles[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "Color : %f %f %f\n", r_shadow_selectedlight->color[0], r_shadow_selectedlight->color[1], r_shadow_selectedlight->color[2]);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "Radius : %f\n", r_shadow_selectedlight->radius);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "Corona : %f\n", r_shadow_selectedlight->corona);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "Style : %i\n", r_shadow_selectedlight->style);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "Shadows : %s\n", r_shadow_selectedlight->shadow ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "Cubemap : %s\n", r_shadow_selectedlight->cubemapname);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "CoronaSize : %f\n", r_shadow_selectedlight->coronasizescale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "Ambient : %f\n", r_shadow_selectedlight->ambientscale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "Diffuse : %f\n", r_shadow_selectedlight->diffusescale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "Specular : %f\n", r_shadow_selectedlight->specularscale);DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "NormalMode : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_NORMALMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; + sprintf(temp, "RealTimeMode : %s\n", (r_shadow_selectedlight->flags & LIGHTFLAG_REALTIMEMODE) ? "yes" : "no");DrawQ_String(x, y, temp, 0, 8, 8, 1, 1, 1, 1, 0, NULL, true);y += 8; } void R_Shadow_EditLights_ToggleShadow_f(void)