]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
more work on mod_generatelightmaps:
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 27 Nov 2009 10:29:15 +0000 (10:29 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 27 Nov 2009 10:29:15 +0000 (10:29 +0000)
migrated light sampling code from r_shadow.c to model_shared.c

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9521 d7cf8633-e32d-0410-b094-e92efae38249

model_shared.c
r_shadow.c

index 701a560a7635b4be6ad40b9b288f2115257f9e0f..3c011c719a1054827fad7c66f00df831daa6363a 100644 (file)
@@ -3046,20 +3046,134 @@ typedef struct lightmaptriangle_s
 }
 lightmaptriangle_t;
 
+typedef struct lightmaplight_s
+{
+       float origin[3];
+       float radius;
+       float iradius;
+       float radius2;
+       float color[3];
+}
+lightmaplight_t;
+
 lightmaptriangle_t *mod_generatelightmaps_lightmaptriangles;
 
 #define MAX_LIGHTMAPSAMPLES 64
 static int mod_generatelightmaps_numoffsets[3];
 static float mod_generatelightmaps_offsets[3][MAX_LIGHTMAPSAMPLES][3];
 
-extern void R_SampleRTLights(const float *pos, float *sample, int numoffsets, const float *offsets);
+static int mod_generatelightmaps_numlights;
+static lightmaplight_t *mod_generatelightmaps_lightinfo;
+
+extern int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color);
+static void Mod_GenerateLightmaps_CreateLights(dp_model_t *model)
+{
+       int index;
+       int result;
+       lightmaplight_t *lightinfo;
+       float origin[3];
+       float radius;
+       float color[3];
+       mod_generatelightmaps_numlights = 0;
+       for (index = 0;;index++)
+       {
+               result = R_Shadow_GetRTLightInfo(index, origin, &radius, color);
+               if (result < 0)
+                       break;
+               if (result > 0)
+                       mod_generatelightmaps_numlights++;
+       }
+       if (mod_generatelightmaps_numlights > 0)
+       {
+               mod_generatelightmaps_lightinfo = Mem_Alloc(tempmempool, mod_generatelightmaps_numlights * sizeof(*mod_generatelightmaps_lightinfo));
+               lightinfo = mod_generatelightmaps_lightinfo;
+               for (index = 0;;index++)
+               {
+                       result = R_Shadow_GetRTLightInfo(index, lightinfo->origin, &lightinfo->radius, lightinfo->color);
+                       if (result < 0)
+                               break;
+                       if (result > 0)
+                               lightinfo++;
+               }
+       }
+       for (index = 0, lightinfo = mod_generatelightmaps_lightinfo;index < mod_generatelightmaps_numlights;index++, lightinfo++)
+       {
+               lightinfo->iradius = 1.0f / lightinfo->radius;
+               lightinfo->radius2 = lightinfo->radius * lightinfo->radius;
+               // TODO: compute svbsp
+       }
+}
 
+static void Mod_GenerateLightmaps_DestroyLights(dp_model_t *model)
+{
+       if (mod_generatelightmaps_lightinfo)
+               Mem_Free(mod_generatelightmaps_lightinfo);
+       mod_generatelightmaps_lightinfo = NULL;
+       mod_generatelightmaps_numlights = 0;
+}
+
+extern cvar_t r_shadow_lightattenuationdividebias;
+extern cvar_t r_shadow_lightattenuationlinearscale;
 static void Mod_GenerateLightmaps_SamplePoint(const float *pos, float *sample, int numoffsets, const float *offsets)
 {
        int i;
+       float relativepoint[3];
+       float color[3];
+       float offsetpos[3];
+       float dist;
+       float dist2;
+       float intensity;
+       trace_t trace;
+       int offsetindex;
+       int hits;
+       int tests;
+       const lightmaplight_t *lightinfo;
        for (i = 0;i < 5*3;i++)
                sample[i] = 0.0f;
-       R_SampleRTLights(pos, sample, numoffsets, offsets);
+       for (i = 0, lightinfo = mod_generatelightmaps_lightinfo;i < mod_generatelightmaps_numlights;i++, lightinfo++)
+       {
+               //R_SampleRTLights(pos, sample, numoffsets, offsets);
+               VectorSubtract(lightinfo->origin, pos, relativepoint);
+               dist2 = VectorLength2(relativepoint);
+               if (dist2 >= lightinfo->radius2)
+                       continue;
+               dist = sqrt(dist2) * lightinfo->iradius;
+               intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0;
+               if (intensity <= 0)
+                       continue;
+               if (cl.worldmodel && cl.worldmodel->TraceLine && numoffsets > 0)
+               {
+                       hits = 0;
+                       tests = 0;
+                       for (offsetindex = 0;offsetindex < numoffsets;offsetindex++)
+                       {
+                               // test line of sight through the collision system (slow)
+                               VectorAdd(pos, offsets + 3*offsetindex, offsetpos);
+                               cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, pos, offsetpos, SUPERCONTENTS_VISBLOCKERMASK);
+                               // don't count samples that start in solid
+                               if (trace.startsolid || trace.fraction < 1)
+                                       continue;
+                               tests++;
+                               cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, offsetpos, lightinfo->origin, SUPERCONTENTS_VISBLOCKERMASK);
+                               if (trace.fraction == 1)
+                                       hits++;
+                       }
+                       if (!hits)
+                               continue;
+                       // scale intensity according to how many rays succeeded
+                       intensity *= (float)hits / tests;
+               }
+               // scale down intensity to add to both ambient and diffuse
+               intensity *= 0.5f;
+               VectorNormalize(relativepoint);
+               VectorScale(lightinfo->color, intensity, color);
+               VectorMA(sample    , 1.0f            , color, sample    );
+               VectorMA(sample + 3, relativepoint[0], color, sample + 3);
+               VectorMA(sample + 6, relativepoint[1], color, sample + 6);
+               VectorMA(sample + 9, relativepoint[2], color, sample + 9);
+               intensity *= VectorLength(color);
+               VectorMA(sample + 12, intensity, relativepoint, sample + 12);
+       }
 }
 
 static void Mod_GenerateLightmaps_LightmapSample(const float *pos, const float *normal, unsigned char *lm_bgr, unsigned char *lm_dir)
@@ -3147,14 +3261,6 @@ static void Mod_GenerateLightmaps_InitSampleOffsets(dp_model_t *model)
        }
 }
 
-static void Mod_GenerateLightmaps_CreateLights(dp_model_t *model)
-{
-}
-
-static void Mod_GenerateLightmaps_DestroyLights(dp_model_t *model)
-{
-}
-
 static void Mod_GenerateLightmaps_DestroyLightmaps(dp_model_t *model)
 {
        msurface_t *surface;
@@ -3524,8 +3630,8 @@ static void Mod_GenerateLightmaps_CreateLightmaps(dp_model_t *model)
                                pixeloffset = ((triangle->lightmapindex * lm_texturesize + y + triangle->lmoffset[1]) * lm_texturesize + triangle->lmoffset[0]) * 4;
                                for (x = 0;x < triangle->lmsize[0];x++, pixeloffset += 4)
                                {
-                                       samplecenter[axis1] = x*lmiscale[0] + triangle->lmbase[0];
-                                       samplecenter[axis2] = y*lmiscale[1] + triangle->lmbase[1];
+                                       samplecenter[axis1] = (x+0.5f)*lmiscale[0] + triangle->lmbase[0];
+                                       samplecenter[axis2] = (y+0.5f)*lmiscale[1] + triangle->lmbase[1];
                                        samplecenter[axis] = samplecenter[axis1]*slopex + samplecenter[axis2]*slopey + slopebase;
                                        VectorMA(samplecenter, 0.125f, samplenormal, samplecenter);
                                        Mod_GenerateLightmaps_LightmapSample(samplecenter, samplenormal, lightmappixels + pixeloffset, deluxemappixels + pixeloffset);
index 341009deb4618327532ac6bcac1771bc4ed6f480..d9a4933ea7badada5898a3f1ee182e6ab8935544 100644 (file)
@@ -5098,77 +5098,24 @@ void R_Shadow_DrawLightSprites(void)
        R_MeshQueue_AddTransparent(r_editlights_cursorlocation, R_Shadow_DrawCursor_TransparentCallback, NULL, 0, NULL);
 }
 
-void R_SampleRTLights(const float *pos, float *sample, int numoffsets, const float *offsets)
+int R_Shadow_GetRTLightInfo(unsigned int lightindex, float *origin, float *radius, float *color)
 {
-       int flag;
-       size_t lightindex;
+       unsigned int range;
        dlight_t *light;
        rtlight_t *rtlight;
-       size_t range;
-       vec3_t relativepoint;
-       vec3_t localpoint;
-       vec3_t color;
-       vec3_t offsetpos;
-       vec_t dist;
-       vec_t intensity;
-       trace_t trace;
-       int offsetindex;
-       int hits;
-       int tests;
-       flag = LIGHTFLAG_REALTIMEMODE;
        range = Mem_ExpandableArray_IndexRange(&r_shadow_worldlightsarray);
-       for (lightindex = 0;lightindex < range;lightindex++)
-       {
-               light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
-               if (!light)
-                       continue;
-               rtlight = &light->rtlight;
-               if (!(rtlight->flags & flag))
-                       continue;
-               VectorSubtract(rtlight->shadoworigin, pos, relativepoint);
-               // early out
-               if (VectorLength2(relativepoint) >= rtlight->radius*rtlight->radius)
-                       continue;
-               Matrix4x4_Transform(&rtlight->matrix_worldtolight, pos, localpoint);
-               dist = VectorLength(localpoint);
-               intensity = dist < 1 ? ((1.0f - dist) * r_shadow_lightattenuationlinearscale.value / (r_shadow_lightattenuationdividebias.value + dist*dist)) : 0;
-               if (intensity <= 0)
-                       continue;
-               if (cl.worldmodel && cl.worldmodel->TraceLine && numoffsets > 0)
-               {
-                       hits = 0;
-                       tests = 0;
-                       for (offsetindex = 0;offsetindex < numoffsets;offsetindex++)
-                       {
-                               // test line of sight through the collision system (slow)
-                               VectorAdd(pos, offsets + 3*offsetindex, offsetpos);
-                               cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, pos, offsetpos, SUPERCONTENTS_VISBLOCKERMASK);
-                               if (trace.startsolid || trace.fraction < 1)
-                                       continue;
-                               cl.worldmodel->TraceLine(cl.worldmodel, NULL, NULL, &trace, offsetpos, rtlight->shadoworigin, SUPERCONTENTS_VISBLOCKERMASK);
-                               // don't count samples that start in solid
-                               if (trace.startsolid)
-                                       continue;
-                               tests++;
-                               if (trace.fraction == 1)
-                                       hits++;
-                       }
-                       if (!hits)
-                               continue;
-                       // scale intensity according to how many rays succeeded
-                       intensity *= (float)hits / tests;
-               }
-               // scale down intensity to add to both ambient and diffuse
-               intensity *= 0.5f;
-               VectorNormalize(relativepoint);
-               VectorScale(rtlight->color, intensity, color);
-               VectorMA(sample    , 1.0f            , color, sample    );
-               VectorMA(sample + 3, relativepoint[0], color, sample + 3);
-               VectorMA(sample + 6, relativepoint[1], color, sample + 6);
-               VectorMA(sample + 9, relativepoint[2], color, sample + 9);
-               intensity *= VectorLength(color);
-               VectorMA(sample + 12, intensity, relativepoint, sample + 12);
-       }
+       if (lightindex >= range)
+               return -1;
+       light = (dlight_t *) Mem_ExpandableArray_RecordAtIndex(&r_shadow_worldlightsarray, lightindex);
+       if (!light)
+               return 0;
+       rtlight = &light->rtlight;
+       //if (!(rtlight->flags & flag))
+       //      return 0;
+       VectorCopy(rtlight->shadoworigin, origin);
+       *radius = rtlight->radius;
+       VectorCopy(rtlight->color, color);
+       return 1;
 }
 
 void R_Shadow_SelectLightInView(void)