X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=gl_rmain.c;h=10fa60d5dc94ec884cb43a00113848cbb4cb039a;hb=3a12518a4f3897519c5578d154c597b8549b8dcf;hp=9342ecd413d2acab60d897639744e13b58199e41;hpb=f22bf10b0b1853106ebea646d4f350b64553df0d;p=xonotic%2Fdarkplaces.git diff --git a/gl_rmain.c b/gl_rmain.c index 9342ecd4..10fa60d5 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -69,11 +69,11 @@ cvar_t gl_fogend = {0, "gl_fogend","0", "nehahra fog end distance (for Nehahra c cvar_t r_textureunits = {0, "r_textureunits", "32", "number of hardware texture units reported by driver (note: setting this to 1 turns off gl_combine)"}; -cvar_t r_glsl = {0, "r_glsl", "1", "enables use of OpenGL 2.0 pixel shaders for lighting"}; -cvar_t r_glsl_offsetmapping = {0, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"}; -cvar_t r_glsl_offsetmapping_reliefmapping = {0, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"}; -cvar_t r_glsl_offsetmapping_scale = {0, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"}; -cvar_t r_glsl_deluxemapping = {0, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"}; +cvar_t r_glsl = {CVAR_SAVE, "r_glsl", "1", "enables use of OpenGL 2.0 pixel shaders for lighting"}; +cvar_t r_glsl_offsetmapping = {CVAR_SAVE, "r_glsl_offsetmapping", "0", "offset mapping effect (also known as parallax mapping or virtual displacement mapping)"}; +cvar_t r_glsl_offsetmapping_reliefmapping = {CVAR_SAVE, "r_glsl_offsetmapping_reliefmapping", "0", "relief mapping effect (higher quality)"}; +cvar_t r_glsl_offsetmapping_scale = {CVAR_SAVE, "r_glsl_offsetmapping_scale", "0.04", "how deep the offset mapping effect is"}; +cvar_t r_glsl_deluxemapping = {CVAR_SAVE, "r_glsl_deluxemapping", "1", "use per pixel lighting on deluxemap-compiled q3bsp maps (or a value of 2 forces deluxemap shading even without deluxemaps)"}; cvar_t r_lerpsprites = {CVAR_SAVE, "r_lerpsprites", "1", "enables animation smoothing on sprites (requires r_lerpmodels 1)"}; cvar_t r_lerpmodels = {CVAR_SAVE, "r_lerpmodels", "1", "enables animation smoothing on models"}; @@ -98,7 +98,7 @@ cvar_t developer_texturelogging = {0, "developer_texturelogging", "0", "produces cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"}; -cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"}; // used for testing renderer code changes, otherwise does nothing +cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"}; cvar_t r_batchmode = {0, "r_batchmode", "1", "selects method of rendering multiple surfaces with one driver call (values are 0, 1, 2, etc...)"}; typedef struct r_glsl_bloomshader_s @@ -143,7 +143,7 @@ rtexture_t *r_texture_fogattenuation; //rtexture_t *r_texture_fogintensity; // information about each possible shader permutation -r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_COUNT]; +r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_MAX]; // currently selected permutation r_glsl_permutation_t *r_glsl_permutation; @@ -478,10 +478,12 @@ static const char *builtinshaderstring = "// fragment shader specific:\n" "#ifdef FRAGMENT_SHADER\n" "\n" +"// 11 textures, we can only use up to 16 on DX9-class hardware\n" "uniform sampler2D Texture_Normal;\n" "uniform sampler2D Texture_Color;\n" "uniform sampler2D Texture_Gloss;\n" "uniform samplerCube Texture_Cube;\n" +"uniform sampler2D Texture_Attenuation;\n" "uniform sampler2D Texture_FogMask;\n" "uniform sampler2D Texture_Pants;\n" "uniform sampler2D Texture_Shirt;\n" @@ -509,13 +511,8 @@ static const char *builtinshaderstring = "uniform myhalf SpecularScale;\n" "uniform myhalf SpecularPower;\n" "\n" -"void main(void)\n" +"vec2 OffsetMapping(vec2 TexCoord)\n" "{\n" -" // apply offsetmapping\n" -"#ifdef USEOFFSETMAPPING\n" -" vec2 TexCoordOffset = TexCoord;\n" -"#define TexCoord TexCoordOffset\n" -"\n" " vec3 eyedir = vec3(normalize(EyeVector));\n" " float depthbias = 1.0 - eyedir.z; // should this be a -?\n" " depthbias = 1.0 - depthbias * depthbias;\n" @@ -541,7 +538,7 @@ static const char *builtinshaderstring = " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n" " if (RT.z > texture2D(Texture_Normal, RT.xy).a) RT += OffsetVector;OffsetVector *= 0.5;RT -= OffsetVector;\n" " TexCoord = RT.xy;\n" -"#elif 1\n" +"#else\n" " // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n" " //vec2 OffsetVector = vec2(EyeVector.xy * (1.0 / EyeVector.z) * depthbias) * OffsetMapping_Scale * vec2(-0.333, 0.333);\n" " //vec2 OffsetVector = vec2(normalize(EyeVector.xy)) * OffsetMapping_Scale * vec2(-0.333, 0.333);\n" @@ -550,39 +547,16 @@ static const char *builtinshaderstring = " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" " TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" -"#elif 0\n" -" // 10 sample offset mapping\n" -" //vec2 OffsetVector = vec2(EyeVector.xy * (1.0 / EyeVector.z) * depthbias) * OffsetMapping_Scale * vec2(-0.333, 0.333);\n" -" //vec2 OffsetVector = vec2(normalize(EyeVector.xy)) * OffsetMapping_Scale * vec2(-0.333, 0.333);\n" -" vec2 OffsetVector = vec2(eyedir.xy) * OffsetMapping_Scale * vec2(-0.1, 0.1);\n" -" //TexCoord += OffsetVector * 3.0;\n" -" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" -" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" -" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" -" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" -" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" -" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" -" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" -" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" -" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" -" TexCoord -= OffsetVector * texture2D(Texture_Normal, TexCoord).a;\n" -"#elif 1\n" -" // parallax mapping as described in the paper\n" -" // 'Parallax Mapping with Offset Limiting: A Per-Pixel Approximation of Uneven Surfaces' by Terry Welsh\n" -" // The paper provides code in the ARB fragment program assembly language\n" -" // I translated it to GLSL but may have done something wrong - SavageX\n" -" // LordHavoc: removed bias and simplified to one line\n" -" // LordHavoc: this is just a single sample offsetmapping...\n" -" TexCoordOffset += vec2(eyedir.x, -1.0 * eyedir.y) * OffsetMapping_Scale * texture2D(Texture_Normal, TexCoord).a;\n" -"#else\n" -" // parallax mapping as described in the paper\n" -" // 'Parallax Mapping with Offset Limiting: A Per-Pixel Approximation of Uneven Surfaces' by Terry Welsh\n" -" // The paper provides code in the ARB fragment program assembly language\n" -" // I translated it to GLSL but may have done something wrong - SavageX\n" -" float height = texture2D(Texture_Normal, TexCoord).a;\n" -" height = (height - 0.5) * OffsetMapping_Scale; // bias and scale\n" -" TexCoordOffset += height * vec2(eyedir.x, -1.0 * eyedir.y);\n" "#endif\n" +" return TexCoord;\n" +"}\n" +"\n" +"void main(void)\n" +"{\n" +" // apply offsetmapping\n" +"#ifdef USEOFFSETMAPPING\n" +" vec2 TexCoordOffset = OffsetMapping(TexCoord);\n" +"#define TexCoord TexCoordOffset\n" "#endif\n" "\n" " // combine the diffuse textures (base, pants, shirt)\n" @@ -597,15 +571,28 @@ static const char *builtinshaderstring = "#ifdef MODE_LIGHTSOURCE\n" " // light source\n" "\n" -" // get the surface normal and light normal\n" +" // calculate surface normal, light normal, and specular normal\n" +" // compute color intensity for the two textures (colormap and glossmap)\n" +" // scale by light color and attenuation as efficiently as possible\n" +" // (do as much scalar math as possible rather than vector math)\n" +"#ifdef USESPECULAR\n" " myhvec3 surfacenormal = normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5));\n" " myhvec3 diffusenormal = myhvec3(normalize(LightVector));\n" +" myhvec3 specularnormal = normalize(diffusenormal + myhvec3(normalize(EyeVector)));\n" "\n" " // calculate directional shading\n" -" color.rgb *= AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0));\n" -"#ifdef USESPECULAR\n" -" myhvec3 specularnormal = normalize(diffusenormal + myhvec3(normalize(EyeVector)));\n" -" color.rgb += myhvec3(texture2D(Texture_Gloss, TexCoord)) * SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n" +" color.rgb = LightColor * myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * (color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0))) + (SpecularScale * pow(myhalf(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower)) * myhvec3(texture2D(Texture_Gloss, TexCoord)));\n" +"#else\n" +"#ifdef USEDIFFUSE\n" +" myhvec3 surfacenormal = normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5));\n" +" myhvec3 diffusenormal = myhvec3(normalize(LightVector));\n" +"\n" +" // calculate directional shading\n" +" color.rgb = LightColor * myhalf(texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0))) * color.rgb * (AmbientScale + DiffuseScale * myhalf(max(float(dot(surfacenormal, diffusenormal)), 0.0)));\n" +"#else\n" +" // calculate directionless shading\n" +" color.rgb = color.rgb * LightColor * myhalf(texture2D(Texture_Attenuation, length(CubeVector)));\n" +"#endif\n" "#endif\n" "\n" "#ifdef USECUBEFILTER\n" @@ -614,20 +601,6 @@ static const char *builtinshaderstring = " color.rgb *= myhvec3(textureCube(Texture_Cube, CubeVector));\n" "#endif\n" "\n" -" // apply light color\n" -" color.rgb *= LightColor;\n" -"\n" -" // apply attenuation\n" -" //\n" -" // the attenuation is (1-(x*x+y*y+z*z)) which gives a large bright\n" -" // center and sharp falloff at the edge, this is about the most efficient\n" -" // we can get away with as far as providing illumination.\n" -" //\n" -" // pow(1-(x*x+y*y+z*z), 4) is far more realistic but needs large lights to\n" -" // provide significant illumination, large = slow = pain.\n" -"// color.rgb *= myhalf(max(1.0 - dot(CubeVector, CubeVector), 0.0));\n" -" color.rgb *= myhalf(max(2.0 - 2.0 * length(CubeVector), 0.0) / (1 + dot(CubeVector, CubeVector)));\n" -"\n" "\n" "\n" "\n" @@ -706,6 +679,7 @@ const char *permutationinfo[][2] = {"#define USEGLOW\n", " glow"}, {"#define USEFOG\n", " fog"}, {"#define USECOLORMAPPING\n", " colormapping"}, + {"#define USEDIFFUSE\n", " diffuse"}, {"#define USESPECULAR\n", " specular"}, {"#define USECUBEFILTER\n", " cubefilter"}, {"#define USEOFFSETMAPPING\n", " offsetmapping"}, @@ -717,14 +691,14 @@ void R_GLSL_CompilePermutation(const char *filename, int permutation) { int i; qboolean shaderfound; - r_glsl_permutation_t *p = r_glsl_permutations + (permutation & SHADERPERMUTATION_COUNTMASK); + r_glsl_permutation_t *p = r_glsl_permutations + (permutation & SHADERPERMUTATION_MASK); int vertstrings_count; int geomstrings_count; int fragstrings_count; char *shaderstring; - const char *vertstrings_list[SHADERPERMUTATION_COUNT+1]; - const char *geomstrings_list[SHADERPERMUTATION_COUNT+1]; - const char *fragstrings_list[SHADERPERMUTATION_COUNT+1]; + const char *vertstrings_list[32+1]; + const char *geomstrings_list[32+1]; + const char *fragstrings_list[32+1]; char permutationname[256]; if (p->compiled) return; @@ -792,6 +766,7 @@ void R_GLSL_CompilePermutation(const char *filename, int permutation) p->loc_Texture_Color = qglGetUniformLocationARB(p->program, "Texture_Color"); p->loc_Texture_Gloss = qglGetUniformLocationARB(p->program, "Texture_Gloss"); p->loc_Texture_Cube = qglGetUniformLocationARB(p->program, "Texture_Cube"); + p->loc_Texture_Attenuation = qglGetUniformLocationARB(p->program, "Texture_Attenuation"); p->loc_Texture_FogMask = qglGetUniformLocationARB(p->program, "Texture_FogMask"); p->loc_Texture_Pants = qglGetUniformLocationARB(p->program, "Texture_Pants"); p->loc_Texture_Shirt = qglGetUniformLocationARB(p->program, "Texture_Shirt"); @@ -827,6 +802,7 @@ void R_GLSL_CompilePermutation(const char *filename, int permutation) if (p->loc_Texture_Lightmap >= 0) qglUniform1iARB(p->loc_Texture_Lightmap, 7); if (p->loc_Texture_Deluxemap >= 0) qglUniform1iARB(p->loc_Texture_Deluxemap, 8); if (p->loc_Texture_Glow >= 0) qglUniform1iARB(p->loc_Texture_Glow, 9); + if (p->loc_Texture_Attenuation >= 0) qglUniform1iARB(p->loc_Texture_Attenuation, 10); CHECKGLERROR qglUseProgramObjectARB(0);CHECKGLERROR } @@ -839,21 +815,23 @@ void R_GLSL_CompilePermutation(const char *filename, int permutation) void R_GLSL_Restart_f(void) { int i; - for (i = 0;i < SHADERPERMUTATION_COUNT;i++) + for (i = 0;i < SHADERPERMUTATION_MAX;i++) if (r_glsl_permutations[i].program) GL_Backend_FreeProgram(r_glsl_permutations[i].program); memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations)); } -int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting) +extern rtexture_t *r_shadow_attenuationgradienttexture; +extern rtexture_t *r_shadow_attenuation2dtexture; +extern rtexture_t *r_shadow_attenuation3dtexture; +int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale) { // select a permutation of the lighting shader appropriate to this // combination of texture, entity, light source, and fogging, only use the // minimum features necessary to avoid wasting rendering time in the // fragment shader on features that are not being used const char *shaderfilename = NULL; - int permutation = 0; - float specularscale = rsurface_texture->specularscale; + unsigned int permutation = 0; r_glsl_permutation = NULL; // TODO: implement geometry-shader based shadow volumes someday if (r_shadow_rtlight) @@ -861,11 +839,12 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting) // light source shaderfilename = "glsl/default.glsl"; permutation = SHADERPERMUTATION_MODE_LIGHTSOURCE | SHADERPERMUTATION_USES_VERTEXSHADER | SHADERPERMUTATION_USES_FRAGMENTSHADER; - specularscale *= r_shadow_rtlight->specularscale; if (r_shadow_rtlight->currentcubemap != r_texture_whitecube) permutation |= SHADERPERMUTATION_CUBEFILTER; + if (diffusescale > 0) + permutation |= SHADERPERMUTATION_DIFFUSE; if (specularscale > 0) - permutation |= SHADERPERMUTATION_SPECULAR; + permutation |= SHADERPERMUTATION_SPECULAR | SHADERPERMUTATION_DIFFUSE; if (r_refdef.fogenabled) permutation |= SHADERPERMUTATION_FOG; if (rsurface_texture->colormapping) @@ -956,30 +935,30 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting) permutation |= SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING; } } - if (!r_glsl_permutations[permutation & SHADERPERMUTATION_COUNTMASK].program) + if (!r_glsl_permutations[permutation & SHADERPERMUTATION_MASK].program) { - if (!r_glsl_permutations[permutation & SHADERPERMUTATION_COUNTMASK].compiled) + if (!r_glsl_permutations[permutation & SHADERPERMUTATION_MASK].compiled) R_GLSL_CompilePermutation(shaderfilename, permutation); - if (!r_glsl_permutations[permutation & SHADERPERMUTATION_COUNTMASK].program) + if (!r_glsl_permutations[permutation & SHADERPERMUTATION_MASK].program) { // remove features until we find a valid permutation - int i; - for (i = SHADERPERMUTATION_COUNT-1;;i>>=1) + unsigned int i; + for (i = SHADERPERMUTATION_MASK;;i>>=1) { + if (!i) + return 0; // utterly failed // reduce i more quickly whenever it would not remove any bits if (permutation < i) continue; permutation &= i; - if (!r_glsl_permutations[permutation & SHADERPERMUTATION_COUNTMASK].compiled) + if (!r_glsl_permutations[permutation & SHADERPERMUTATION_MASK].compiled) R_GLSL_CompilePermutation(shaderfilename, permutation); - if (r_glsl_permutations[permutation & SHADERPERMUTATION_COUNTMASK].program) + if (r_glsl_permutations[permutation & SHADERPERMUTATION_MASK].program) break; - if (!i) - return 0; // utterly failed } } } - r_glsl_permutation = r_glsl_permutations + (permutation & SHADERPERMUTATION_COUNTMASK); + r_glsl_permutation = r_glsl_permutations + (permutation & SHADERPERMUTATION_MASK); CHECKGLERROR qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR R_Mesh_TexMatrix(0, &rsurface_texture->currenttexmatrix); @@ -987,19 +966,30 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting) { if (r_glsl_permutation->loc_Texture_Cube >= 0 && r_shadow_rtlight) R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap)); if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, r_shadow_entitylightorigin[0], r_shadow_entitylightorigin[1], r_shadow_entitylightorigin[2]); - if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]); - if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, r_shadow_rtlight->ambientscale); - if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, r_shadow_rtlight->diffusescale); - if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, specularscale); + if (permutation & SHADERPERMUTATION_DIFFUSE) + { + if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]); + if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, ambientscale); + if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, diffusescale); + if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, specularscale); + } + else + { + // ambient only is simpler + if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0] * ambientscale, lightcolorbase[1] * ambientscale, lightcolorbase[2] * ambientscale); + if (r_glsl_permutation->loc_AmbientScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_AmbientScale, 1); + if (r_glsl_permutation->loc_DiffuseScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_DiffuseScale, 0); + if (r_glsl_permutation->loc_SpecularScale >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularScale, 0); + } } else if (permutation & SHADERPERMUTATION_MODE_LIGHTDIRECTION) { if (r_glsl_permutation->loc_AmbientColor >= 0) - qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, rsurface_entity->modellight_ambient[0], rsurface_entity->modellight_ambient[1], rsurface_entity->modellight_ambient[2]); + qglUniform3fARB(r_glsl_permutation->loc_AmbientColor, rsurface_entity->modellight_ambient[0] * ambientscale, rsurface_entity->modellight_ambient[1] * ambientscale, rsurface_entity->modellight_ambient[2] * ambientscale); if (r_glsl_permutation->loc_DiffuseColor >= 0) - qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, rsurface_entity->modellight_diffuse[0], rsurface_entity->modellight_diffuse[1], rsurface_entity->modellight_diffuse[2]); + qglUniform3fARB(r_glsl_permutation->loc_DiffuseColor, rsurface_entity->modellight_diffuse[0] * diffusescale, rsurface_entity->modellight_diffuse[1] * diffusescale, rsurface_entity->modellight_diffuse[2] * diffusescale); if (r_glsl_permutation->loc_SpecularColor >= 0) - qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, rsurface_entity->modellight_diffuse[0] * rsurface_texture->specularscale, rsurface_entity->modellight_diffuse[1] * rsurface_texture->specularscale, rsurface_entity->modellight_diffuse[2] * rsurface_texture->specularscale); + qglUniform3fARB(r_glsl_permutation->loc_SpecularColor, rsurface_entity->modellight_diffuse[0] * specularscale, rsurface_entity->modellight_diffuse[1] * specularscale, rsurface_entity->modellight_diffuse[2] * specularscale); if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface_entity->modellight_lightdir[0], rsurface_entity->modellight_lightdir[1], rsurface_entity->modellight_lightdir[2]); } @@ -1013,6 +1003,7 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting) if (r_glsl_permutation->loc_Texture_Color >= 0) R_Mesh_TexBind(1, R_GetTexture(rsurface_texture->basetexture)); if (r_glsl_permutation->loc_Texture_Gloss >= 0) R_Mesh_TexBind(2, R_GetTexture(rsurface_texture->glosstexture)); //if (r_glsl_permutation->loc_Texture_Cube >= 0 && permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE) R_Mesh_TexBindCubeMap(3, R_GetTexture(r_shadow_rtlight->currentcubemap)); + if (r_glsl_permutation->loc_Texture_Attenuation >= 0) R_Mesh_TexBind(10, R_GetTexture(r_shadow_attenuationgradienttexture)); if (r_glsl_permutation->loc_Texture_FogMask >= 0) R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation)); if (r_glsl_permutation->loc_Texture_Pants >= 0) R_Mesh_TexBind(5, R_GetTexture(rsurface_texture->currentskinframe->pants)); if (r_glsl_permutation->loc_Texture_Shirt >= 0) R_Mesh_TexBind(6, R_GetTexture(rsurface_texture->currentskinframe->shirt)); @@ -1053,9 +1044,9 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting) void R_SwitchSurfaceShader(int permutation) { - if (r_glsl_permutation != r_glsl_permutations + (permutation & SHADERPERMUTATION_COUNTMASK)) + if (r_glsl_permutation != r_glsl_permutations + (permutation & SHADERPERMUTATION_MASK)) { - r_glsl_permutation = r_glsl_permutations + (permutation & SHADERPERMUTATION_COUNTMASK); + r_glsl_permutation = r_glsl_permutations + (permutation & SHADERPERMUTATION_MASK); CHECKGLERROR qglUseProgramObjectARB(r_glsl_permutation->program); CHECKGLERROR @@ -1825,9 +1816,9 @@ void R_Bloom_CopyScreenTexture(float colorscale) r_refdef.stats.bloom++; R_ResetViewRendering2D(); - R_Mesh_VertexPointer(r_screenvertex3f); - R_Mesh_ColorPointer(NULL); - R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f); + R_Mesh_VertexPointer(r_screenvertex3f, 0, 0); + R_Mesh_ColorPointer(NULL, 0, 0); + R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f, 0, 0); R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_screen)); // copy view into the screen texture @@ -1842,7 +1833,7 @@ void R_Bloom_CopyScreenTexture(float colorscale) GL_BlendFunc(GL_ONE, GL_ZERO); GL_Color(colorscale, colorscale, colorscale, 1); // TODO: optimize with multitexture or GLSL - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight; // we now have a bloom image in the framebuffer @@ -1871,8 +1862,8 @@ void R_Bloom_MakeTexture(void) r_refdef.stats.bloom++; R_ResetViewRendering2D(); - R_Mesh_VertexPointer(r_screenvertex3f); - R_Mesh_ColorPointer(NULL); + R_Mesh_VertexPointer(r_screenvertex3f, 0, 0); + R_Mesh_ColorPointer(NULL, 0, 0); // we have a bloom image in the framebuffer CHECKGLERROR @@ -1885,8 +1876,8 @@ void R_Bloom_MakeTexture(void) GL_BlendFunc(GL_DST_COLOR, GL_SRC_COLOR); GL_Color(r, r, r, 1); R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom)); - R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f); - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight; // copy the vertically blurred bloom view to a texture @@ -1901,7 +1892,7 @@ void R_Bloom_MakeTexture(void) if (r_hdr.integer) brighten *= r_hdr_range.value; R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom)); - R_Mesh_TexCoordPointer(0, 2, r_bloomstate.offsettexcoord2f); + R_Mesh_TexCoordPointer(0, 2, r_bloomstate.offsettexcoord2f, 0, 0); for (dir = 0;dir < 2;dir++) { @@ -1930,7 +1921,7 @@ void R_Bloom_MakeTexture(void) //r = (dir ? 1.0f : brighten)/(range*2+1); r = (dir ? 1.0f : brighten)/(range*2+1)*(1 - x*x/(float)(range*range)); GL_Color(r, r, r, 1); - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight; GL_BlendFunc(GL_ONE, GL_ONE); } @@ -1948,17 +1939,17 @@ void R_Bloom_MakeTexture(void) { GL_BlendFunc(GL_ONE, GL_ZERO); R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom)); - R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f); + R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0); GL_Color(1, 1, 1, 1); - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight; GL_BlendFunc(GL_ONE, GL_ONE); qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); R_Mesh_TexBind(0, R_GetTexture(r_texture_white)); - R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f); + R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0); GL_Color(r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, r_bloom_colorsubtract.value, 1); - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_bloomstate.bloomwidth * r_bloomstate.bloomheight; qglBlendEquationEXT(GL_FUNC_ADD_EXT); @@ -2014,13 +2005,13 @@ static void R_BlendView(void) // the bloom texture was made earlier this render, so we just need to // blend it onto the screen... R_ResetViewRendering2D(); - R_Mesh_VertexPointer(r_screenvertex3f); - R_Mesh_ColorPointer(NULL); + R_Mesh_VertexPointer(r_screenvertex3f, 0, 0); + R_Mesh_ColorPointer(NULL, 0, 0); GL_Color(1, 1, 1, 1); GL_BlendFunc(GL_ONE, GL_ONE); R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom)); - R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f); - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_view.width * r_view.height; } else if (r_bloomstate.enabled) @@ -2033,40 +2024,40 @@ static void R_BlendView(void) // put the original screen image back in place and blend the bloom // texture on it R_ResetViewRendering2D(); - R_Mesh_VertexPointer(r_screenvertex3f); - R_Mesh_ColorPointer(NULL); + R_Mesh_VertexPointer(r_screenvertex3f, 0, 0); + R_Mesh_ColorPointer(NULL, 0, 0); GL_Color(1, 1, 1, 1); GL_BlendFunc(GL_ONE, GL_ZERO); // do both in one pass if possible R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_bloom)); - R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f); + R_Mesh_TexCoordPointer(0, 2, r_bloomstate.bloomtexcoord2f, 0, 0); if (r_textureunits.integer >= 2 && gl_combine.integer) { R_Mesh_TexCombine(1, GL_ADD, GL_ADD, 1, 1); R_Mesh_TexBind(1, R_GetTexture(r_bloomstate.texture_screen)); - R_Mesh_TexCoordPointer(1, 2, r_bloomstate.screentexcoord2f); + R_Mesh_TexCoordPointer(1, 2, r_bloomstate.screentexcoord2f, 0, 0); } else { - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_view.width * r_view.height; // now blend on the bloom texture GL_BlendFunc(GL_ONE, GL_ONE); R_Mesh_TexBind(0, R_GetTexture(r_bloomstate.texture_screen)); - R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f); + R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f, 0, 0); } - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); r_refdef.stats.bloom_drawpixels += r_view.width * r_view.height; } if (r_refdef.viewblend[3] >= (1.0f / 256.0f)) { // apply a color tint to the whole view R_ResetViewRendering2D(); - R_Mesh_VertexPointer(r_screenvertex3f); - R_Mesh_ColorPointer(NULL); + R_Mesh_VertexPointer(r_screenvertex3f, 0, 0); + R_Mesh_ColorPointer(NULL, 0, 0); GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_Color(r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]); - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); } } @@ -2352,10 +2343,10 @@ void R_DrawBBoxMesh(vec3_t mins, vec3_t maxs, float cr, float cg, float cb, floa c[2] = c[2] * f1 + r_refdef.fogcolor[2] * f2; } } - R_Mesh_VertexPointer(vertex3f); - R_Mesh_ColorPointer(color); + R_Mesh_VertexPointer(vertex3f, 0, 0); + R_Mesh_ColorPointer(color, 0, 0); R_Mesh_ResetTextureState(); - R_Mesh_Draw(8, 12); + R_Mesh_Draw(8, 12, 0, 0); } */ @@ -2417,12 +2408,12 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight } GL_DepthTest(!(ent->effects & EF_NODEPTHTEST)); GL_CullFace((ent->effects & EF_DOUBLESIDED) ? GL_NONE : GL_FRONT); // quake is backwards, this culls back faces - R_Mesh_VertexPointer(nomodelvertex3f); + R_Mesh_VertexPointer(nomodelvertex3f, 0, 0); if (r_refdef.fogenabled) { vec3_t org; memcpy(color4f, nomodelcolor4f, sizeof(float[6*4])); - R_Mesh_ColorPointer(color4f); + R_Mesh_ColorPointer(color4f, 0, 0); Matrix4x4_OriginFromMatrix(&ent->matrix, org); f2 = VERTEXFOGTABLE(VectorDistance(org, r_view.origin)); f1 = 1 - f2; @@ -2437,14 +2428,14 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight else if (ent->alpha != 1) { memcpy(color4f, nomodelcolor4f, sizeof(float[6*4])); - R_Mesh_ColorPointer(color4f); + R_Mesh_ColorPointer(color4f, 0, 0); for (i = 0, c = color4f;i < 6;i++, c += 4) c[3] *= ent->alpha; } else - R_Mesh_ColorPointer(nomodelcolor4f); + R_Mesh_ColorPointer(nomodelcolor4f, 0, 0); R_Mesh_ResetTextureState(); - R_Mesh_Draw(0, 6, 8, nomodelelements); + R_Mesh_Draw(0, 6, 8, nomodelelements, 0, 0); } void R_DrawNoModel(entity_render_t *ent) @@ -2516,21 +2507,21 @@ void R_DrawSprite(int blendfunc1, int blendfunc2, rtexture_t *texture, rtexture_ vertex3f[10] = origin[1] + left[1] * scalex1 + up[1] * scaley1; vertex3f[11] = origin[2] + left[2] * scalex1 + up[2] * scaley1; - R_Mesh_VertexPointer(vertex3f); - R_Mesh_ColorPointer(NULL); + R_Mesh_VertexPointer(vertex3f, 0, 0); + R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); R_Mesh_TexBind(0, R_GetTexture(texture)); - R_Mesh_TexCoordPointer(0, 2, spritetexcoord2f); + R_Mesh_TexCoordPointer(0, 2, spritetexcoord2f, 0, 0); // FIXME: fixed function path can't properly handle r_view.colorscale > 1 GL_Color(cr * ifog * r_view.colorscale, cg * ifog * r_view.colorscale, cb * ifog * r_view.colorscale, ca); - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); if (blendfunc2 == GL_ONE_MINUS_SRC_ALPHA) { R_Mesh_TexBind(0, R_GetTexture(fogtexture)); GL_BlendFunc(blendfunc1, GL_ONE); GL_Color(r_refdef.fogcolor[0] * fog * r_view.colorscale, r_refdef.fogcolor[1] * fog * r_view.colorscale, r_refdef.fogcolor[2] * fog * r_view.colorscale, ca); - R_Mesh_Draw(0, 4, 2, polygonelements); + R_Mesh_Draw(0, 4, 2, polygonelements, 0, 0); } } @@ -2635,11 +2626,11 @@ void R_Mesh_AddBrushMeshFromPlanes(rmesh_t *mesh, int numplanes, mplane_t *plane static void R_DrawCollisionBrush(const colbrushf_t *brush) { int i; - R_Mesh_VertexPointer(brush->points->v); + R_Mesh_VertexPointer(brush->points->v, 0, 0); i = (int)(((size_t)brush) / sizeof(colbrushf_t)); GL_Color((i & 31) * (1.0f / 32.0f) * r_view.colorscale, ((i >> 5) & 31) * (1.0f / 32.0f) * r_view.colorscale, ((i >> 10) & 31) * (1.0f / 32.0f) * r_view.colorscale, 0.2f); GL_LockArrays(0, brush->numpoints); - R_Mesh_Draw(0, brush->numpoints, brush->numtriangles, brush->elements); + R_Mesh_Draw(0, brush->numpoints, brush->numtriangles, brush->elements, 0, 0); GL_LockArrays(0, 0); } @@ -2648,11 +2639,11 @@ static void R_DrawCollisionSurface(const entity_render_t *ent, const msurface_t int i; if (!surface->num_collisiontriangles) return; - R_Mesh_VertexPointer(surface->data_collisionvertex3f); + R_Mesh_VertexPointer(surface->data_collisionvertex3f, 0, 0); i = (int)(((size_t)surface) / sizeof(msurface_t)); GL_Color((i & 31) * (1.0f / 32.0f) * r_view.colorscale, ((i >> 5) & 31) * (1.0f / 32.0f) * r_view.colorscale, ((i >> 10) & 31) * (1.0f / 32.0f) * r_view.colorscale, 0.2f); GL_LockArrays(0, surface->num_collisionvertices); - R_Mesh_Draw(0, surface->num_collisionvertices, surface->num_collisiontriangles, surface->data_collisionelement3i); + R_Mesh_Draw(0, surface->num_collisionvertices, surface->num_collisiontriangles, surface->data_collisionelement3i, 0, 0); GL_LockArrays(0, 0); } @@ -2736,6 +2727,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t) t->backgroundbasetexture = t->backgroundnumskinframes ? ((!t->colormapping && t->backgroundcurrentskinframe->merged) ? t->backgroundcurrentskinframe->merged : t->backgroundcurrentskinframe->base) : r_texture_white; t->backgroundglosstexture = r_texture_white; t->specularpower = r_shadow_glossexponent.value; + // TODO: store reference values for these in the texture? t->specularscale = 0; if (r_shadow_gloss.integer > 0) { @@ -2887,14 +2879,32 @@ void R_Mesh_ResizeArrays(int newvertices) } float *rsurface_modelvertex3f; +int rsurface_modelvertex3f_bufferobject; +size_t rsurface_modelvertex3f_bufferoffset; float *rsurface_modelsvector3f; +int rsurface_modelsvector3f_bufferobject; +size_t rsurface_modelsvector3f_bufferoffset; float *rsurface_modeltvector3f; +int rsurface_modeltvector3f_bufferobject; +size_t rsurface_modeltvector3f_bufferoffset; float *rsurface_modelnormal3f; +int rsurface_modelnormal3f_bufferobject; +size_t rsurface_modelnormal3f_bufferoffset; float *rsurface_vertex3f; +int rsurface_vertex3f_bufferobject; +size_t rsurface_vertex3f_bufferoffset; float *rsurface_svector3f; +int rsurface_svector3f_bufferobject; +size_t rsurface_svector3f_bufferoffset; float *rsurface_tvector3f; +int rsurface_tvector3f_bufferobject; +size_t rsurface_tvector3f_bufferoffset; float *rsurface_normal3f; +int rsurface_normal3f_bufferobject; +size_t rsurface_normal3f_bufferoffset; float *rsurface_lightmapcolor4f; +int rsurface_lightmapcolor4f_bufferobject; +size_t rsurface_lightmapcolor4f_bufferoffset; vec3_t rsurface_modelorg; qboolean rsurface_generatedvertex; const entity_render_t *rsurface_entity; @@ -2927,14 +2937,30 @@ void RSurf_ActiveWorldEntity(void) R_Mesh_Matrix(&identitymatrix); VectorCopy(r_view.origin, rsurface_modelorg); rsurface_modelvertex3f = rsurface_model->surfmesh.data_vertex3f; + rsurface_modelvertex3f_bufferobject = rsurface_model->surfmesh.vbo; + rsurface_modelvertex3f_bufferoffset = rsurface_model->surfmesh.vbooffset_vertex3f; rsurface_modelsvector3f = rsurface_model->surfmesh.data_svector3f; + rsurface_modelsvector3f_bufferobject = rsurface_model->surfmesh.vbo; + rsurface_modelsvector3f_bufferoffset = rsurface_model->surfmesh.vbooffset_svector3f; rsurface_modeltvector3f = rsurface_model->surfmesh.data_tvector3f; + rsurface_modeltvector3f_bufferobject = rsurface_model->surfmesh.vbo; + rsurface_modeltvector3f_bufferoffset = rsurface_model->surfmesh.vbooffset_tvector3f; rsurface_modelnormal3f = rsurface_model->surfmesh.data_normal3f; + rsurface_modelnormal3f_bufferobject = rsurface_model->surfmesh.vbo; + rsurface_modelnormal3f_bufferoffset = rsurface_model->surfmesh.vbooffset_normal3f; rsurface_generatedvertex = false; rsurface_vertex3f = rsurface_modelvertex3f; + rsurface_vertex3f_bufferobject = rsurface_modelvertex3f_bufferobject; + rsurface_vertex3f_bufferoffset = rsurface_modelvertex3f_bufferoffset; rsurface_svector3f = rsurface_modelsvector3f; + rsurface_svector3f_bufferobject = rsurface_modelsvector3f_bufferobject; + rsurface_svector3f_bufferoffset = rsurface_modelsvector3f_bufferoffset; rsurface_tvector3f = rsurface_modeltvector3f; + rsurface_tvector3f_bufferobject = rsurface_modeltvector3f_bufferobject; + rsurface_tvector3f_bufferoffset = rsurface_modeltvector3f_bufferoffset; rsurface_normal3f = rsurface_modelnormal3f; + rsurface_normal3f_bufferobject = rsurface_modelnormal3f_bufferobject; + rsurface_normal3f_bufferoffset = rsurface_modelnormal3f_bufferoffset; } void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, qboolean wanttangents) @@ -2972,20 +2998,44 @@ void RSurf_ActiveModelEntity(const entity_render_t *ent, qboolean wantnormals, q rsurface_modelnormal3f = NULL; Mod_Alias_GetMesh_Vertices(rsurface_model, rsurface_entity->frameblend, rsurface_array_modelvertex3f, NULL, NULL, NULL); } + rsurface_modelvertex3f_bufferobject = 0; + rsurface_modelvertex3f_bufferoffset = 0; + rsurface_modelsvector3f_bufferobject = 0; + rsurface_modelsvector3f_bufferoffset = 0; + rsurface_modeltvector3f_bufferobject = 0; + rsurface_modeltvector3f_bufferoffset = 0; + rsurface_modelnormal3f_bufferobject = 0; + rsurface_modelnormal3f_bufferoffset = 0; rsurface_generatedvertex = true; } else { rsurface_modelvertex3f = rsurface_model->surfmesh.data_vertex3f; + rsurface_modelvertex3f_bufferobject = rsurface_model->surfmesh.vbo; + rsurface_modelvertex3f_bufferoffset = rsurface_model->surfmesh.vbooffset_vertex3f; rsurface_modelsvector3f = rsurface_model->surfmesh.data_svector3f; + rsurface_modelsvector3f_bufferobject = rsurface_model->surfmesh.vbo; + rsurface_modelsvector3f_bufferoffset = rsurface_model->surfmesh.vbooffset_svector3f; rsurface_modeltvector3f = rsurface_model->surfmesh.data_tvector3f; + rsurface_modeltvector3f_bufferobject = rsurface_model->surfmesh.vbo; + rsurface_modeltvector3f_bufferoffset = rsurface_model->surfmesh.vbooffset_tvector3f; rsurface_modelnormal3f = rsurface_model->surfmesh.data_normal3f; + rsurface_modelnormal3f_bufferobject = rsurface_model->surfmesh.vbo; + rsurface_modelnormal3f_bufferoffset = rsurface_model->surfmesh.vbooffset_normal3f; rsurface_generatedvertex = false; } rsurface_vertex3f = rsurface_modelvertex3f; + rsurface_vertex3f_bufferobject = rsurface_modelvertex3f_bufferobject; + rsurface_vertex3f_bufferoffset = rsurface_modelvertex3f_bufferoffset; rsurface_svector3f = rsurface_modelsvector3f; + rsurface_svector3f_bufferobject = rsurface_modelsvector3f_bufferobject; + rsurface_svector3f_bufferoffset = rsurface_modelsvector3f_bufferoffset; rsurface_tvector3f = rsurface_modeltvector3f; + rsurface_tvector3f_bufferobject = rsurface_modeltvector3f_bufferobject; + rsurface_tvector3f_bufferoffset = rsurface_modeltvector3f_bufferoffset; rsurface_normal3f = rsurface_modelnormal3f; + rsurface_normal3f_bufferobject = rsurface_modelnormal3f_bufferobject; + rsurface_normal3f_bufferoffset = rsurface_modelnormal3f_bufferoffset; } void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generatetangents, int texturenumsurfaces, msurface_t **texturesurfacelist) @@ -3000,12 +3050,18 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta if (generatenormals && !rsurface_modelnormal3f) { rsurface_normal3f = rsurface_modelnormal3f = rsurface_array_modelnormal3f; + rsurface_normal3f_bufferobject = rsurface_modelnormal3f_bufferobject = 0; + rsurface_normal3f_bufferoffset = rsurface_modelnormal3f_bufferoffset = 0; Mod_BuildNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_element3i, rsurface_array_modelnormal3f, r_smoothnormals_areaweighting.integer); } if (generatetangents && !rsurface_modelsvector3f) { rsurface_svector3f = rsurface_modelsvector3f = rsurface_array_modelsvector3f; + rsurface_svector3f_bufferobject = rsurface_modelsvector3f_bufferobject = 0; + rsurface_svector3f_bufferoffset = rsurface_modelsvector3f_bufferoffset = 0; rsurface_tvector3f = rsurface_modeltvector3f = rsurface_array_modeltvector3f; + rsurface_tvector3f_bufferobject = rsurface_modeltvector3f_bufferobject = 0; + rsurface_tvector3f_bufferoffset = rsurface_modeltvector3f_bufferoffset = 0; Mod_BuildTextureVectorsFromNormals(0, rsurface_model->surfmesh.num_vertices, rsurface_model->surfmesh.num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_modelnormal3f, rsurface_model->surfmesh.data_element3i, rsurface_array_modelsvector3f, rsurface_array_modeltvector3f, r_smoothnormals_areaweighting.integer); } } @@ -3053,18 +3109,34 @@ void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generateta Mod_BuildTextureVectorsFromNormals(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, rsurface_modelvertex3f, rsurface_model->surfmesh.data_texcoordtexture2f, rsurface_array_deformednormal3f, rsurface_model->surfmesh.data_element3i + surface->num_firsttriangle * 3, rsurface_array_deformedsvector3f, rsurface_array_deformedtvector3f, r_smoothnormals_areaweighting.integer); } rsurface_vertex3f = rsurface_array_deformedvertex3f; + rsurface_vertex3f_bufferobject = 0; + rsurface_vertex3f_bufferoffset = 0; rsurface_svector3f = rsurface_array_deformedsvector3f; + rsurface_svector3f_bufferobject = 0; + rsurface_svector3f_bufferoffset = 0; rsurface_tvector3f = rsurface_array_deformedtvector3f; + rsurface_tvector3f_bufferobject = 0; + rsurface_tvector3f_bufferoffset = 0; rsurface_normal3f = rsurface_array_deformednormal3f; + rsurface_normal3f_bufferobject = 0; + rsurface_normal3f_bufferoffset = 0; } else { - rsurface_vertex3f = rsurface_modelvertex3f; + rsurface_vertex3f = rsurface_modelvertex3f; + rsurface_vertex3f_bufferobject = rsurface_modelvertex3f_bufferobject; + rsurface_vertex3f_bufferoffset = rsurface_modelvertex3f_bufferoffset; rsurface_svector3f = rsurface_modelsvector3f; + rsurface_svector3f_bufferobject = rsurface_modelsvector3f_bufferobject; + rsurface_svector3f_bufferoffset = rsurface_modelsvector3f_bufferoffset; rsurface_tvector3f = rsurface_modeltvector3f; - rsurface_normal3f = rsurface_modelnormal3f; + rsurface_tvector3f_bufferobject = rsurface_modeltvector3f_bufferobject; + rsurface_tvector3f_bufferoffset = rsurface_modeltvector3f_bufferoffset; + rsurface_normal3f = rsurface_modelnormal3f; + rsurface_normal3f_bufferobject = rsurface_modelnormal3f_bufferobject; + rsurface_normal3f_bufferoffset = rsurface_modelnormal3f_bufferoffset; } - R_Mesh_VertexPointer(rsurface_vertex3f); + R_Mesh_VertexPointer(rsurface_vertex3f, rsurface_vertex3f_bufferobject, rsurface_vertex3f_bufferoffset); } void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacelist) @@ -3080,7 +3152,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel if (texturenumsurfaces == 1) { GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); } else if (r_batchmode.integer == 2) { @@ -3093,7 +3165,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel j = i + 1; if (surface->num_triangles > MAXBATCHTRIANGLES) { - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); continue; } memcpy(batchelements, rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle, surface->num_triangles * sizeof(int[3])); @@ -3112,7 +3184,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel } surface2 = texturesurfacelist[j-1]; numvertices = endvertex - firstvertex; - R_Mesh_Draw(firstvertex, numvertices, batchtriangles, batchelements); + R_Mesh_Draw(firstvertex, numvertices, batchtriangles, batchelements, 0, 0); } } else if (r_batchmode.integer == 1) @@ -3127,7 +3199,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel numvertices = surface2->num_firstvertex + surface2->num_vertices - surface->num_firstvertex; numtriangles = surface2->num_firsttriangle + surface2->num_triangles - surface->num_firsttriangle; GL_LockArrays(surface->num_firstvertex, numvertices); - R_Mesh_Draw(surface->num_firstvertex, numvertices, numtriangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, numvertices, numtriangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); } } else @@ -3136,7 +3208,7 @@ void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacel { surface = texturesurfacelist[i]; GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); } } } @@ -3158,7 +3230,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa if (deluxemaptexunit >= 0) R_Mesh_TexBind(deluxemaptexunit, R_GetTexture(surface->deluxemaptexture)); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); } else if (r_batchmode.integer == 2) { @@ -3174,7 +3246,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa j = i + 1; if (surface->num_triangles > MAXBATCHTRIANGLES) { - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); continue; } memcpy(batchelements, rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle, surface->num_triangles * sizeof(int[3])); @@ -3193,7 +3265,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa } surface2 = texturesurfacelist[j-1]; numvertices = endvertex - firstvertex; - R_Mesh_Draw(firstvertex, numvertices, batchtriangles, batchelements); + R_Mesh_Draw(firstvertex, numvertices, batchtriangles, batchelements, 0, 0); } } else if (r_batchmode.integer == 1) @@ -3227,7 +3299,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa numvertices = surface2->num_firstvertex + surface2->num_vertices - surface->num_firstvertex; numtriangles = surface2->num_firsttriangle + surface2->num_triangles - surface->num_firsttriangle; GL_LockArrays(surface->num_firstvertex, numvertices); - R_Mesh_Draw(surface->num_firstvertex, numvertices, numtriangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, numvertices, numtriangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); } #if 0 Con_Printf("\n"); @@ -3242,7 +3314,7 @@ static void RSurf_DrawBatch_WithLightmapSwitching(int texturenumsurfaces, msurfa if (deluxemaptexunit >= 0) R_Mesh_TexBind(deluxemaptexunit, R_GetTexture(surface->deluxemaptexture)); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); } } } @@ -3260,7 +3332,7 @@ static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **te { float f = ((j + surface->num_firsttriangle) & 31) * (1.0f / 31.0f) * r_view.colorscale; GL_Color(f, f, f, 1); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, 1, (rsurface_model->surfmesh.data_element3i + 3 * (j + surface->num_firsttriangle))); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, 1, (rsurface_model->surfmesh.data_element3i + 3 * (j + surface->num_firsttriangle)), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * (j + surface->num_firsttriangle))); } } } @@ -3272,7 +3344,7 @@ static void RSurf_DrawBatch_ShowSurfaces(int texturenumsurfaces, msurface_t **te int k = (int)(((size_t)surface) / sizeof(msurface_t)); GL_Color((k & 15) * (1.0f / 16.0f) * r_view.colorscale, ((k >> 4) & 15) * (1.0f / 16.0f) * r_view.colorscale, ((k >> 8) & 15) * (1.0f / 16.0f) * r_view.colorscale, 1); GL_LockArrays(surface->num_firstvertex, surface->num_vertices); - R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle)); + R_Mesh_Draw(surface->num_firstvertex, surface->num_vertices, surface->num_triangles, (rsurface_model->surfmesh.data_element3i + 3 * surface->num_firsttriangle), rsurface_model->surfmesh.ebo, (sizeof(int[3]) * surface->num_firsttriangle)); } } } @@ -3315,6 +3387,8 @@ static void RSurf_DrawBatch_GL11_ApplyFog(int texturenumsurfaces, msurface_t **t } } rsurface_lightmapcolor4f = rsurface_array_color4f; + rsurface_lightmapcolor4f_bufferobject = 0; + rsurface_lightmapcolor4f_bufferoffset = 0; } static void RSurf_DrawBatch_GL11_ApplyColor(int texturenumsurfaces, msurface_t **texturesurfacelist, float r, float g, float b, float a) @@ -3336,15 +3410,19 @@ static void RSurf_DrawBatch_GL11_ApplyColor(int texturenumsurfaces, msurface_t * } } rsurface_lightmapcolor4f = rsurface_array_color4f; + rsurface_lightmapcolor4f_bufferobject = 0; + rsurface_lightmapcolor4f_bufferoffset = 0; } static void RSurf_DrawBatch_GL11_Lightmap(int texturenumsurfaces, msurface_t **texturesurfacelist, float r, float g, float b, float a, qboolean applycolor, qboolean applyfog) { // TODO: optimize rsurface_lightmapcolor4f = NULL; + rsurface_lightmapcolor4f_bufferobject = 0; + rsurface_lightmapcolor4f_bufferoffset = 0; if (applyfog) RSurf_DrawBatch_GL11_ApplyFog(texturenumsurfaces, texturesurfacelist); if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, r, g, b, a); - R_Mesh_ColorPointer(rsurface_lightmapcolor4f); + R_Mesh_ColorPointer(rsurface_lightmapcolor4f, rsurface_lightmapcolor4f_bufferobject, rsurface_lightmapcolor4f_bufferoffset); GL_Color(r, g, b, a); RSurf_DrawBatch_WithLightmapSwitching(texturenumsurfaces, texturesurfacelist, 0, -1); } @@ -3354,9 +3432,11 @@ static void RSurf_DrawBatch_GL11_Unlit(int texturenumsurfaces, msurface_t **text // TODO: optimize applyfog && applycolor case // just apply fog if necessary, and tint the fog color array if necessary rsurface_lightmapcolor4f = NULL; + rsurface_lightmapcolor4f_bufferobject = 0; + rsurface_lightmapcolor4f_bufferoffset = 0; if (applyfog) RSurf_DrawBatch_GL11_ApplyFog(texturenumsurfaces, texturesurfacelist); if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, r, g, b, a); - R_Mesh_ColorPointer(rsurface_lightmapcolor4f); + R_Mesh_ColorPointer(rsurface_lightmapcolor4f, rsurface_lightmapcolor4f_bufferobject, rsurface_lightmapcolor4f_bufferoffset); GL_Color(r, g, b, a); RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); } @@ -3406,12 +3486,18 @@ static void RSurf_DrawBatch_GL11_VertexColor(int texturenumsurfaces, msurface_t } } rsurface_lightmapcolor4f = rsurface_array_color4f; + rsurface_lightmapcolor4f_bufferobject = 0; + rsurface_lightmapcolor4f_bufferoffset = 0; } else + { rsurface_lightmapcolor4f = rsurface_model->surfmesh.data_lightmapcolor4f; + rsurface_lightmapcolor4f_bufferobject = rsurface_model->surfmesh.vbo; + rsurface_lightmapcolor4f_bufferoffset = rsurface_model->surfmesh.vbooffset_lightmapcolor4f; + } if (applyfog) RSurf_DrawBatch_GL11_ApplyFog(texturenumsurfaces, texturesurfacelist); if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, r, g, b, a); - R_Mesh_ColorPointer(rsurface_lightmapcolor4f); + R_Mesh_ColorPointer(rsurface_lightmapcolor4f, rsurface_lightmapcolor4f_bufferobject, rsurface_lightmapcolor4f_bufferoffset); GL_Color(r, g, b, a); RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); } @@ -3460,6 +3546,8 @@ static void RSurf_DrawBatch_GL11_VertexShade(int texturenumsurfaces, msurface_t a = 1; applycolor = false; rsurface_lightmapcolor4f = rsurface_array_color4f; + rsurface_lightmapcolor4f_bufferobject = 0; + rsurface_lightmapcolor4f_bufferoffset = 0; } else { @@ -3467,10 +3555,12 @@ static void RSurf_DrawBatch_GL11_VertexShade(int texturenumsurfaces, msurface_t g = ambientcolor[1]; b = ambientcolor[2]; rsurface_lightmapcolor4f = NULL; + rsurface_lightmapcolor4f_bufferobject = 0; + rsurface_lightmapcolor4f_bufferoffset = 0; } if (applyfog) RSurf_DrawBatch_GL11_ApplyFog(texturenumsurfaces, texturesurfacelist); if (applycolor) RSurf_DrawBatch_GL11_ApplyColor(texturenumsurfaces, texturesurfacelist, r, g, b, a); - R_Mesh_ColorPointer(rsurface_lightmapcolor4f); + R_Mesh_ColorPointer(rsurface_lightmapcolor4f, rsurface_lightmapcolor4f_bufferobject, rsurface_lightmapcolor4f_bufferoffset); GL_Color(r, g, b, a); RSurf_DrawBatch_Simple(texturenumsurfaces, texturesurfacelist); } @@ -3484,7 +3574,7 @@ static void R_DrawTextureSurfaceList_ShowSurfaces(int texturenumsurfaces, msurfa rsurface_mode = RSURFMODE_SHOWSURFACES; GL_DepthMask(true); GL_BlendFunc(GL_ONE, GL_ZERO); - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); } RSurf_PrepareVerticesForBatch(false, false, texturenumsurfaces, texturesurfacelist); @@ -3523,7 +3613,7 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, msurface_t **te if (rsurface_model->type == mod_brushq1 && r_q1bsp_skymasking.integer && !r_viewcache.world_novis) { GL_Color(r_refdef.fogcolor[0] * r_view.colorscale, r_refdef.fogcolor[1] * r_view.colorscale, r_refdef.fogcolor[2] * r_view.colorscale, 1); - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); if (skyrendermasked) { @@ -3553,7 +3643,7 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **t R_Mesh_ResetTextureState(); } - R_SetupSurfaceShader(vec3_origin, rsurface_lightmode == 2); + R_SetupSurfaceShader(vec3_origin, rsurface_lightmode == 2, 1, 1, rsurface_texture->specularscale); if (!r_glsl_permutation) return; @@ -3561,32 +3651,32 @@ static void R_DrawTextureSurfaceList_GL20(int texturenumsurfaces, msurface_t **t RSurf_PrepareVerticesForBatch(true, r_glsl_permutation->loc_Texture_Normal, texturenumsurfaces, texturesurfacelist); else RSurf_PrepareVerticesForBatch(r_glsl_permutation->loc_Texture_Normal, r_glsl_permutation->loc_Texture_Normal, texturenumsurfaces, texturesurfacelist); - 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); - R_Mesh_TexCoordPointer(4, 2, rsurface_model->surfmesh.data_texcoordlightmap2f); + 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); + R_Mesh_TexCoordPointer(4, 2, rsurface_model->surfmesh.data_texcoordlightmap2f, rsurface_model->surfmesh.vbo, rsurface_model->surfmesh.vbooffset_texcoordlightmap2f); if (rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT) { R_Mesh_TexBind(7, R_GetTexture(r_texture_white)); if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap)); - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); } else if (rsurface_uselightmaptexture) { R_Mesh_TexBind(7, R_GetTexture(texturesurfacelist[0]->lightmaptexture)); if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(8, R_GetTexture(texturesurfacelist[0]->deluxemaptexture)); - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); } else { R_Mesh_TexBind(7, R_GetTexture(r_texture_white)); if (r_glsl_permutation->loc_Texture_Deluxemap >= 0) R_Mesh_TexBind(8, R_GetTexture(r_texture_blanknormalmap)); - R_Mesh_ColorPointer(rsurface_model->surfmesh.data_lightmapcolor4f); + R_Mesh_ColorPointer(rsurface_model->surfmesh.data_lightmapcolor4f, rsurface_model->surfmesh.vbo, rsurface_model->surfmesh.vbooffset_lightmapcolor4f); } if (rsurface_uselightmaptexture && !(rsurface_texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)) @@ -3643,7 +3733,7 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, msurface_t **t } layercolor[3] = layer->color[3]; applycolor = layercolor[0] != 1 || layercolor[1] != 1 || layercolor[2] != 1 || layercolor[3] != 1; - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0; switch (layer->type) { @@ -3651,10 +3741,14 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, msurface_t **t memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(r_texture_white); m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f; + m.pointer_texcoord_bufferobject[0] = rsurface_model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface_model->surfmesh.vbooffset_texcoordlightmap2f; m.tex[1] = R_GetTexture(layer->texture); m.texmatrix[1] = layer->texmatrix; m.texrgbscale[1] = layertexrgbscale; 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; R_Mesh_TextureState(&m); if (rsurface_lightmode == 2) RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog); @@ -3669,6 +3763,8 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, msurface_t **t m.texmatrix[0] = layer->texmatrix; m.texrgbscale[0] = layertexrgbscale; 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; R_Mesh_TextureState(&m); RSurf_DrawBatch_GL11_Unlit(texturenumsurfaces, texturesurfacelist, layercolor[0], layercolor[1], layercolor[2], layercolor[3], applycolor, applyfog); break; @@ -3680,10 +3776,12 @@ static void R_DrawTextureSurfaceList_GL13(int texturenumsurfaces, msurface_t **t m.tex[0] = R_GetTexture(layer->texture); m.texmatrix[0] = layer->texmatrix; 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; } R_Mesh_TextureState(&m); // generate a color array for the fog pass - R_Mesh_ColorPointer(rsurface_array_color4f); + R_Mesh_ColorPointer(rsurface_array_color4f, 0, 0); for (texturesurfaceindex = 0;texturesurfaceindex < texturenumsurfaces;texturesurfaceindex++) { int i; @@ -3738,7 +3836,7 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t } GL_DepthMask(layer->depthmask); GL_BlendFunc(layer->blendfunc1, layer->blendfunc2); - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); applyfog = (layer->flags & TEXTURELAYERFLAG_FOGDARKEN) != 0; switch (layer->type) { @@ -3750,6 +3848,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(r_texture_white); m.pointer_texcoord[0] = rsurface_model->surfmesh.data_texcoordlightmap2f; + m.pointer_texcoord_bufferobject[0] = rsurface_model->surfmesh.vbo; + m.pointer_texcoord_bufferoffset[0] = rsurface_model->surfmesh.vbooffset_texcoordlightmap2f; R_Mesh_TextureState(&m); if (rsurface_lightmode == 2) RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, 1, 1, 1, 1, false, false); @@ -3764,6 +3864,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t m.tex[0] = R_GetTexture(layer->texture); m.texmatrix[0] = layer->texmatrix; 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; R_Mesh_TextureState(&m); RSurf_DrawBatch_GL11_Unlit(texturenumsurfaces, texturesurfacelist, layer->color[0] * 0.5f, layer->color[1] * 0.5f, layer->color[2] * 0.5f, layer->color[3], layer->color[0] != 2 || layer->color[1] != 2 || layer->color[2] != 2 || layer->color[3] != 1, false); } @@ -3774,6 +3876,8 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t m.tex[0] = R_GetTexture(layer->texture); m.texmatrix[0] = layer->texmatrix; 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; R_Mesh_TextureState(&m); if (rsurface_lightmode == 2) RSurf_DrawBatch_GL11_VertexShade(texturenumsurfaces, texturesurfacelist, layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog); @@ -3787,18 +3891,22 @@ static void R_DrawTextureSurfaceList_GL11(int texturenumsurfaces, msurface_t **t m.tex[0] = R_GetTexture(layer->texture); m.texmatrix[0] = layer->texmatrix; 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; R_Mesh_TextureState(&m); RSurf_DrawBatch_GL11_Unlit(texturenumsurfaces, texturesurfacelist, layer->color[0], layer->color[1], layer->color[2], layer->color[3], layer->color[0] != 1 || layer->color[1] != 1 || layer->color[2] != 1 || layer->color[3] != 1, applyfog); break; case TEXTURELAYERTYPE_FOG: // singletexture fogging - R_Mesh_ColorPointer(rsurface_array_color4f); + R_Mesh_ColorPointer(rsurface_array_color4f, 0, 0); if (layer->texture) { memset(&m, 0, sizeof(m)); m.tex[0] = R_GetTexture(layer->texture); m.texmatrix[0] = layer->texmatrix; 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; R_Mesh_TextureState(&m); } else @@ -3888,6 +3996,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const j = i + 1; surface = rsurface_model->data_surfaces + surfacelist[i]; texture = surface->texture; + R_UpdateTextureInfo(ent, texture); rsurface_texture = texture->currentframe; rsurface_uselightmaptexture = surface->lightmaptexture != NULL; // scan ahead until we find a different texture @@ -3985,8 +4094,8 @@ void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, in GL_CullFace(GL_NONE); R_Mesh_Matrix(&identitymatrix); - R_Mesh_VertexPointer(vertex3f); - R_Mesh_ColorPointer(NULL); + R_Mesh_VertexPointer(vertex3f, 0, 0); + R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); i = surfacelist[0]; @@ -4010,7 +4119,7 @@ void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, in for (j = 0;j < 3;j++, i++) vertex3f[i] = mins[j] + size[j] * locboxvertex3f[i]; - R_Mesh_Draw(0, 6*4, 6*2, locboxelement3i); + R_Mesh_Draw(0, 6*4, 6*2, locboxelement3i, 0, 0); } void R_DrawLocs(void) @@ -4035,7 +4144,7 @@ void R_DrawCollisionBrushes(entity_render_t *ent) if (!model->brush.num_brushes) return; CHECKGLERROR - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); GL_BlendFunc(GL_SRC_ALPHA, GL_ONE); GL_DepthMask(false); @@ -4061,7 +4170,7 @@ void R_DrawTrianglesAndNormals(entity_render_t *ent, qboolean drawtris, qboolean GL_DepthTest(!r_showdisabledepthtest.integer); GL_DepthMask(true); GL_BlendFunc(GL_ONE, GL_ZERO); - R_Mesh_ColorPointer(NULL); + R_Mesh_ColorPointer(NULL, 0, 0); R_Mesh_ResetTextureState(); for (i = 0, j = model->firstmodelsurface, surface = model->data_surfaces + j;i < model->nummodelsurfaces;i++, j++, surface++) {