cubemap filters for rtlights are now supported
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 18 Feb 2004 14:06:38 +0000 (14:06 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 18 Feb 2004 14:06:38 +0000 (14:06 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3905 d7cf8633-e32d-0410-b094-e92efae38249

gl_models.c
gl_rmain.c
gl_rsurf.c
image.c
image.h
model_alias.c
model_brush.c
model_shared.h
r_shadow.c
todo

index 59f3d85..1f6fc96 100644 (file)
@@ -328,7 +328,7 @@ void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightor
        }
 }
 
-void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz)
+void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
        int c, meshnum, layernum;
        float fog, ifog, lightcolor2[3];
@@ -383,7 +383,7 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
                        if (layer->flags & ALIASLAYER_SPECULAR)
                        {
                                c_alias_polys += mesh->num_triangles;
-                               R_Shadow_SpecularLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, NULL);
+                               R_Shadow_SpecularLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, lightcubemap);
                        }
                        else if (layer->flags & ALIASLAYER_DIFFUSE)
                        {
@@ -412,7 +412,7 @@ void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
                                        lightcolor2[2] *= bcolor[2] * (1.0f / 255.0f);
                                }
                                c_alias_polys += mesh->num_triangles;
-                               R_Shadow_DiffuseLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, NULL);
+                               R_Shadow_DiffuseLighting(mesh->num_vertices, mesh->num_triangles, mesh->data_element3i, aliasvert_vertex3f, aliasvert_svector3f, aliasvert_tvector3f, aliasvert_normal3f, mesh->data_texcoord2f, relativelightorigin, lightradius, lightcolor2, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, layer->texture, layer->nmap, lightcubemap);
                        }
                }
        }
@@ -802,12 +802,12 @@ void R_Model_Zymotic_Draw(entity_render_t *ent)
        }
 }
 
-void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, float lightradius2, float lightdistbias, float lightsubtract, float *lightcolor)
+void R_Model_Zymotic_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius)
 {
        // FIXME
 }
 
-void R_Model_Zymotic_DrawOntoLight(entity_render_t *ent)
+void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
        // FIXME
 }
index 35e9759..c0d23b1 100644 (file)
@@ -605,6 +605,7 @@ void R_ShadowVolumeLighting(int visiblevolumes)
                                        R_Shadow_Stage_LightWithoutShadows();
 
                                // calculate world to filter matrix
+                               //Matrix4x4_CreateFromQuakeEntity(&matrix, wl->origin[0], wl->origin[1], wl->origin[2], wl->angles[0] + cl.time * 12, wl->angles[1] + cl.time * 45, wl->angles[2], lightradius);
                                Matrix4x4_CreateFromQuakeEntity(&matrix, wl->origin[0], wl->origin[1], wl->origin[2], wl->angles[0], wl->angles[1], wl->angles[2], lightradius);
                                Matrix4x4_Invert_Simple(&matrix_worldtofilter, &matrix);
                                // calculate world to attenuationxyz/xy matrix
@@ -628,7 +629,7 @@ void R_ShadowVolumeLighting(int visiblevolumes)
                                        if (r_shadow_staticworldlights.integer)
                                                R_Shadow_DrawStaticWorldLight_Light(wl, &ent->matrix, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz);
                                        else
-                                               ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz);
+                                               ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, wl->cubemap);
                                }
                                if (r_drawentities.integer)
                                {
@@ -644,7 +645,7 @@ void R_ShadowVolumeLighting(int visiblevolumes)
                                                        Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix);
                                                        Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix);
                                                        Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix);
-                                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz);
+                                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, wl->cubemap);
                                                }
                                        }
                                }
@@ -713,7 +714,7 @@ void R_ShadowVolumeLighting(int visiblevolumes)
                                        Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix);
                                        Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix);
                                        Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix);
-                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz);
+                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, NULL);
                                }
                                if (r_drawentities.integer)
                                {
@@ -729,7 +730,7 @@ void R_ShadowVolumeLighting(int visiblevolumes)
                                                        Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix);
                                                        Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix);
                                                        Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix);
-                                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz);
+                                                       ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz, NULL);
                                                }
                                        }
                                }
index 13c97be..253444e 100644 (file)
@@ -1851,7 +1851,7 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto
        }
 }
 
-void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz)
+void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
        int surfnum;
        msurface_t *surf;
@@ -1879,8 +1879,8 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
                                t = surf->texinfo->texture->currentframe;
                                if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
                                {
-                                       R_Shadow_DiffuseLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, NULL);
-                                       R_Shadow_SpecularLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, NULL);
+                                       R_Shadow_DiffuseLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, lightcubemap);
+                                       R_Shadow_SpecularLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, lightcubemap);
                                }
                        }
                }
@@ -2395,15 +2395,15 @@ void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
        }
 }
 
-void R_Q3BSP_DrawFaceLight(entity_render_t *ent, q3mface_t *face, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz)
+void R_Q3BSP_DrawFaceLight(entity_render_t *ent, q3mface_t *face, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
        if ((face->texture->surfaceflags & Q3SURFACEFLAG_NODRAW) || !face->num_triangles)
                return;
-       R_Shadow_DiffuseLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.base, face->texture->skin.nmap, NULL);
-       R_Shadow_SpecularLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.gloss, face->texture->skin.nmap, NULL);
+       R_Shadow_DiffuseLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.base, face->texture->skin.nmap, lightcubemap);
+       R_Shadow_SpecularLighting(face->num_vertices, face->num_triangles, face->data_element3i, face->data_vertex3f, face->data_svector3f, face->data_tvector3f, face->data_normal3f, face->data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, face->texture->skin.gloss, face->texture->skin.nmap, lightcubemap);
 }
 
-void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz)
+void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
        int i;
        q3mface_t *face;
@@ -2427,7 +2427,7 @@ void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t
                //else
                        for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++)
                                if ((ent != &cl_entities[0].render || face->visframe == r_framecount) && BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs))
-                                       R_Q3BSP_DrawFaceLight(ent, face, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz);
+                                       R_Q3BSP_DrawFaceLight(ent, face, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, lightcubemap);
        }
 }
 
diff --git a/image.c b/image.c
index 27fc794..b46e3f4 100644 (file)
--- a/image.c
+++ b/image.c
@@ -7,6 +7,38 @@
 int            image_width;
 int            image_height;
 
+void Image_CopyMux(qbyte *outpixels, const qbyte *inpixels, int width, int height, int flipx, int flipy, int flipdiagonal, int numincomponents, int numoutcomponents, int *inputcomponentindices)
+{
+       int c, x, y;
+       const qbyte *in, *inrow, *incolumn;
+       if (flipdiagonal)
+       {
+               for (y = 0;y < height;y++)
+               {
+                       incolumn = inpixels + (flipx ? width - 1 - y : y) * numincomponents;
+                       for (x = 0;x < width;x++)
+                       {
+                               in = incolumn + (flipy ? height - 1 - x : x) * width * numincomponents;
+                               for (c = 0;c < numoutcomponents;c++)
+                                       *outpixels++ = in[inputcomponentindices[c]];
+                       }
+               }
+       }
+       else
+       {
+               for (y = 0;y < height;y++)
+               {
+                       inrow = inpixels + (flipy ? height - 1 - y : y) * width * numincomponents;
+                       for (x = 0;x < width;x++)
+                       {
+                               in = inrow + (flipx ? width - 1 - x : x) * numincomponents;
+                               for (c = 0;c < numoutcomponents;c++)
+                                       *outpixels++ = in[inputcomponentindices[c]];
+                       }
+               }
+       }
+}
+
 void Image_GammaRemapRGB(const qbyte *in, qbyte *out, int pixels, const qbyte *gammar, const qbyte *gammag, const qbyte *gammab)
 {
        while (pixels--)
diff --git a/image.h b/image.h
index 71a5535..f85a806 100644 (file)
--- a/image.h
+++ b/image.h
@@ -2,6 +2,10 @@
 #ifndef IMAGE_H
 #define IMAGE_H
 
+// swizzle components (even converting number of components) and flip images
+// (warning: input must be different than output due to non-linear read/write)
+void Image_CopyMux(qbyte *outpixels, const qbyte *inpixels, int width, int height, int flipx, int flipy, int flipdiagonal, int numincomponents, int numoutcomponents, int *inputcomponentindices);
+
 // applies gamma correction to RGB pixels, in can be the same as out
 void Image_GammaRemapRGB(const qbyte *in, qbyte *out, int pixels, const qbyte *gammar, const qbyte *gammag, const qbyte *gammab);
 
index d0a9c3c..d91ef81 100644 (file)
@@ -312,7 +312,7 @@ void Mod_BuildAliasSkinsFromSkinFiles(aliasskin_t *skin, skinfile_t *skinfile, c
 #define BOUNDF(VALUE,MIN,MAX) if (VALUE < MIN || VALUE >= MAX) Host_Error("model %s has an invalid ##VALUE (%f exceeds %f - %f)\n", loadmodel->name, VALUE, MIN, MAX);
 extern void R_Model_Alias_Draw(entity_render_t *ent);
 extern void R_Model_Alias_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
+extern void R_Model_Alias_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
 void Mod_IDP0_Load(model_t *mod, void *buffer)
 {
        int i, j, version, totalskins, skinwidth, skinheight, groupframes, groupskins, numverts;
@@ -970,7 +970,7 @@ void Mod_IDP3_Load(model_t *mod, void *buffer)
 extern void R_Model_Zymotic_DrawSky(entity_render_t *ent);
 extern void R_Model_Zymotic_Draw(entity_render_t *ent);
 extern void R_Model_Zymotic_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
+extern void R_Model_Zymotic_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
 void Mod_ZYMOTICMODEL_Load(model_t *mod, void *buffer)
 {
        zymtype1header_t *pinmodel, *pheader;
index 8acc3ce..2209463 100644 (file)
@@ -2819,7 +2819,7 @@ static void Mod_Q1BSP_RoundUpToHullSize(model_t *cmodel, const vec3_t inmins, co
 extern void R_Model_Brush_DrawSky(entity_render_t *ent);
 extern void R_Model_Brush_Draw(entity_render_t *ent);
 extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
+extern void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
 void Mod_Q1BSP_Load(model_t *mod, void *buffer)
 {
        int i, j, k;
@@ -5259,7 +5259,7 @@ static int Mod_Q3BSP_NativeContentsFromSuperContents(model_t *model, int superco
 extern void R_Q3BSP_DrawSky(struct entity_render_s *ent);
 extern void R_Q3BSP_Draw(struct entity_render_s *ent);
 extern void R_Q3BSP_DrawShadowVolume(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
-extern void R_Q3BSP_DrawLight(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
+extern void R_Q3BSP_DrawLight(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
 void Mod_Q3BSP_Load(model_t *mod, void *buffer)
 {
        int i, j;
index 00a11b2..0aafccc 100644 (file)
@@ -576,7 +576,7 @@ typedef struct model_s
        // draw a shadow volume for the model based on light source
        void(*DrawShadowVolume)(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
        // draw the lighting on a model (through stencil)
-       void(*DrawLight)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz);
+       void(*DrawLight)(struct entity_render_s *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltofilter, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap);
        // trace a box against this model
        void (*TraceBox)(struct model_s *model, int frame, struct trace_s *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask);
        // fields belonging to each type of model
index e92bafc..bd0f1c0 100644 (file)
@@ -115,6 +115,7 @@ the (currently upcoming) game Doom3.
 #include "r_shadow.h"
 #include "cl_collision.h"
 #include "portals.h"
+#include "image.h"
 
 extern void R_Shadow_EditLights_Init(void);
 
@@ -147,6 +148,9 @@ rtexture_t *r_shadow_blankbumptexture;
 rtexture_t *r_shadow_blankglosstexture;
 rtexture_t *r_shadow_blankwhitetexture;
 
+// used only for light filters (cubemaps)
+rtexturepool_t *r_shadow_filters_texturepool;
+
 cvar_t r_shadow_realtime_world_lightmaps = {0, "r_shadow_realtime_world_lightmaps", "0"};
 cvar_t r_shadow_lightattenuationpower = {0, "r_shadow_lightattenuationpower", "0.5"};
 cvar_t r_shadow_lightattenuationscale = {0, "r_shadow_lightattenuationscale", "1"};
@@ -201,6 +205,7 @@ void r_shadow_start(void)
        r_shadow_blankglosstexture = NULL;
        r_shadow_blankwhitetexture = NULL;
        r_shadow_texturepool = NULL;
+       r_shadow_filters_texturepool = NULL;
        R_Shadow_ClearWorldLights();
        r_shadow_reloadlights = true;
 }
@@ -216,6 +221,7 @@ void r_shadow_shutdown(void)
        r_shadow_blankglosstexture = NULL;
        r_shadow_blankwhitetexture = NULL;
        R_FreeTexturePool(&r_shadow_texturepool);
+       R_FreeTexturePool(&r_shadow_filters_texturepool);
        maxshadowelements = 0;
        shadowelements = NULL;
        maxvertexupdate = 0;
@@ -1291,14 +1297,16 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element
 
                        memset(&m, 0, sizeof(m));
                        m.tex[0] = R_GetTexture(basetexture);
-                       m.texcubemap[1] = R_GetTexture(lightcubemap);
                        m.pointer_texcoord[0] = texcoord2f;
-                       m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
+                       if (lightcubemap)
+                       {
+                               m.texcubemap[1] = R_GetTexture(lightcubemap);
+                               m.pointer_texcoord[1] = varray_texcoord3f[1];
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                       }
                        R_Mesh_State_Texture(&m);
                        qglColorMask(1,1,1,0);
                        GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
-                       if (lightcubemap)
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
                        VectorScale(lightcolor, r_shadow_lightintensityscale.value, color2);
                        for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
                        {
@@ -1341,14 +1349,16 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element
 
                        memset(&m, 0, sizeof(m));
                        m.tex[0] = R_GetTexture(basetexture);
-                       m.texcubemap[1] = R_GetTexture(lightcubemap);
                        m.pointer_texcoord[0] = texcoord2f;
-                       m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
+                       if (lightcubemap)
+                       {
+                               m.texcubemap[1] = R_GetTexture(lightcubemap);
+                               m.pointer_texcoord[1] = varray_texcoord3f[1];
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                       }
                        R_Mesh_State_Texture(&m);
                        qglColorMask(1,1,1,0);
                        GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
-                       if (lightcubemap)
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
                        VectorScale(lightcolor, r_shadow_lightintensityscale.value, color2);
                        for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
                        {
@@ -1426,14 +1436,16 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element
 
                        memset(&m, 0, sizeof(m));
                        m.tex[0] = R_GetTexture(basetexture);
-                       m.texcubemap[1] = R_GetTexture(lightcubemap);
                        m.pointer_texcoord[0] = texcoord2f;
-                       m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
+                       if (lightcubemap)
+                       {
+                               m.texcubemap[1] = R_GetTexture(lightcubemap);
+                               m.pointer_texcoord[1] = varray_texcoord3f[1];
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                       }
                        R_Mesh_State_Texture(&m);
                        qglColorMask(1,1,1,0);
                        GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
-                       if (lightcubemap)
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
                        VectorScale(lightcolor, r_shadow_lightintensityscale.value, color2);
                        for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
                        {
@@ -1479,14 +1491,16 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element
 
                        memset(&m, 0, sizeof(m));
                        m.tex[0] = R_GetTexture(basetexture);
-                       m.texcubemap[1] = R_GetTexture(lightcubemap);
                        m.pointer_texcoord[0] = texcoord2f;
-                       m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
+                       if (lightcubemap)
+                       {
+                               m.texcubemap[1] = R_GetTexture(lightcubemap);
+                               m.pointer_texcoord[1] = varray_texcoord3f[1];
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                       }
                        R_Mesh_State_Texture(&m);
                        qglColorMask(1,1,1,0);
                        GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
-                       if (lightcubemap)
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
                        VectorScale(lightcolor, r_shadow_lightintensityscale.value, color2);
                        for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
                        {
@@ -1597,14 +1611,16 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen
 
                        memset(&m, 0, sizeof(m));
                        m.tex[0] = R_GetTexture(glosstexture);
-                       m.texcubemap[1] = R_GetTexture(lightcubemap);
+                       if (lightcubemap)
+                       {
+                               m.texcubemap[1] = R_GetTexture(lightcubemap);
+                               m.pointer_texcoord[1] = varray_texcoord3f[1];
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                       }
                        m.pointer_texcoord[0] = texcoord2f;
-                       m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
                        R_Mesh_State_Texture(&m);
                        qglColorMask(1,1,1,0);
                        GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
-                       if (lightcubemap)
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
                        VectorScale(lightcolor, colorscale, color2);
                        for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
                        {
@@ -1719,14 +1735,16 @@ void R_Shadow_SpecularLighting(int numverts, int numtriangles, const int *elemen
 
                        memset(&m, 0, sizeof(m));
                        m.tex[0] = R_GetTexture(glosstexture);
-                       m.texcubemap[1] = R_GetTexture(lightcubemap);
+                       if (lightcubemap)
+                       {
+                               m.texcubemap[1] = R_GetTexture(lightcubemap);
+                               m.pointer_texcoord[1] = varray_texcoord3f[1];
+                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
+                       }
                        m.pointer_texcoord[0] = texcoord2f;
-                       m.pointer_texcoord[1] = lightcubemap ? varray_texcoord3f[1] : NULL;
                        R_Mesh_State_Texture(&m);
                        qglColorMask(1,1,1,0);
                        GL_BlendFunc(GL_DST_ALPHA, GL_ONE);
-                       if (lightcubemap)
-                               R_Shadow_Transform_Vertex3f_TexCoord3f(varray_texcoord3f[1], numverts, vertex3f, matrix_modeltofilter);
                        VectorScale(lightcolor, colorscale, color2);
                        for (renders = 0;renders < 64 && (color2[0] > 0 || color2[1] > 0 || color2[2] > 0);renders++, color2[0]--, color2[1]--, color2[2]--)
                        {
@@ -1805,8 +1823,8 @@ void R_Shadow_DrawStaticWorldLight_Light(worldlight_t *light, matrix4x4_t *matri
        }
        for (mesh = light->meshchain_light;mesh;mesh = mesh->next)
        {
-               R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_diffuse, mesh->map_normal, NULL);
-               R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_specular, mesh->map_normal, NULL);
+               R_Shadow_DiffuseLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_diffuse, mesh->map_normal, light->cubemap);
+               R_Shadow_SpecularLighting(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->vertex3f, mesh->svector3f, mesh->tvector3f, mesh->normal3f, mesh->texcoord2f, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltofilter, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, mesh->map_specular, mesh->map_normal, light->cubemap);
        }
 }
 
@@ -1824,6 +1842,93 @@ vec3_t r_editlights_cursorlocation;
 
 static int lightpvsbytes;
 static qbyte lightpvs[(MAX_MAP_LEAFS + 7)/ 8];
+//static char *suffix[6] = {"ft", "bk", "rt", "lf", "up", "dn"};
+typedef struct suffixinfo
+{
+       char *suffix;
+       int flipx, flipy, flipdiagonal;
+}
+suffixinfo_t;
+static suffixinfo_t suffix[3][6] =
+{
+       {
+               {"posx", false, false, false},
+               {"negx", false, false, false},
+               {"posy", false, false, false},
+               {"negy", false, false, false},
+               {"posz", false, false, false},
+               {"negz", false, false, false}
+       },
+       {
+               {"px", false, false, false},
+               {"nx", false, false, false},
+               {"py", false, false, false},
+               {"ny", false, false, false},
+               {"pz", false, false, false},
+               {"nz", false, false, false}
+       },
+       {
+               {"ft", true, false, true},
+               {"bk", false, true, true},
+               {"lf", true, true, false},
+               {"rt", false, false, false},
+               {"up", false, false, false},
+               {"dn", false, false, false}
+       }
+};
+
+static int componentorder[4] = {0, 1, 2, 3};
+
+rtexture_t *R_Shadow_LoadCubemap(const char *basename)
+{
+       int i, j, cubemapsize;
+       qbyte *cubemappixels, *image_rgba;
+       rtexture_t *cubemaptexture;
+       char name[256];
+       // must start 0 so the first loadimagepixels has no requested width/height
+       cubemapsize = 0;
+       cubemappixels = NULL;
+       cubemaptexture = NULL;
+       for (j = 0;j < 3 && !cubemappixels;j++)
+       {
+               for (i = 0;i < 6;i++)
+               {
+                       snprintf(name, sizeof(name), "%s%s", basename, suffix[j][i].suffix);
+                       if ((image_rgba = loadimagepixels(name, true, cubemapsize, cubemapsize)))
+                       {
+                               if (image_width == image_height)
+                               {
+                                       if (!cubemappixels && image_width >= 1)
+                                       {
+                                               cubemapsize = image_width;
+                                               // note this clears to black, so unavailable sizes are black
+                                               cubemappixels = Mem_Alloc(tempmempool, 6*cubemapsize*cubemapsize*4);
+                                       }
+                                       if (cubemappixels)
+                                               Image_CopyMux(cubemappixels+i*cubemapsize*cubemapsize*4, image_rgba, cubemapsize, cubemapsize, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, componentorder);
+                               }
+                               else
+                                       Con_Printf("Cubemap image \"%s\" (%ix%i) is not square, OpenGL requires square cubemaps.\n", name, image_width, image_height);
+                               Mem_Free(image_rgba);
+                       }
+               }
+       }
+       if (cubemappixels)
+       {
+               if (!r_shadow_filters_texturepool)
+                       r_shadow_filters_texturepool = R_AllocTexturePool();
+               cubemaptexture = R_LoadTextureCubeMap(r_shadow_filters_texturepool, basename, cubemapsize, cubemappixels, TEXTYPE_RGBA, TEXF_PRECACHE, NULL);
+               Mem_Free(cubemappixels);
+       }
+       else
+               Con_Printf("Failed to load Cubemap \"%s\"\n", basename);
+       return cubemaptexture;
+}
+
+void R_Shadow_FreeCubemaps(void)
+{
+       R_FreeTexturePool(&r_shadow_filters_texturepool);
+}
 
 void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style, const char *cubemapname, int castshadow)
 {
@@ -1863,7 +1968,7 @@ void R_Shadow_NewWorldLight(vec3_t origin, float radius, vec3_t color, int style
        {
                e->cubemapname = Mem_Alloc(r_shadow_mempool, strlen(cubemapname) + 1);
                strcpy(e->cubemapname, cubemapname);
-               // FIXME: add cubemap loading (and don't load a cubemap twice)
+               e->cubemap = R_Shadow_LoadCubemap(e->cubemapname);
        }
        // FIXME: rewrite this to store ALL geometry into a cache in the light
        if (e->castshadows)
@@ -2066,6 +2171,7 @@ void R_Shadow_ClearWorldLights(void)
        while (r_shadow_worldlightchain)
                R_Shadow_FreeWorldLight(r_shadow_worldlightchain);
        r_shadow_selectedlight = NULL;
+       R_Shadow_FreeCubemaps();
 }
 
 void R_Shadow_SelectLight(worldlight_t *light)
diff --git a/todo b/todo
index 0850de8..fd77b16 100644 (file)
--- a/todo
+++ b/todo
@@ -35,8 +35,9 @@
 -n darkplaces: server is starting before the "port" cvar is set by commandline and scripts? (yummyluv)
 -n darkplaces: typing ip in join game menu should show 'trying' and 'no response' after a while, or 'no network' if networking is not initialized (yummyluv)
 -n dpmod: make grapple off-hand (joe hill)
-0 darkplaces: add r_shadow_realtime_world_lightmaps cvar to control lightmap brightness (Mitchell)
-0 darkplaces: add gl_lightmaps cvar to disable texturing except lightmaps for testing (Vic)
+-n darkplaces: implement cubemap support on rtlights (romi, Vermeulen, Mitchell)
+d darkplaces: add r_shadow_realtime_world_lightmaps cvar to control lightmap brightness (Mitchell)
+-n darkplaces: add gl_lightmaps cvar to disable texturing except lightmaps for testing (Vic)
 0 hmap2: release hmap2 (Vic, Supajoe)
 4 darkplaces: add capability for qc entities to act as bones in a model, and send them as compressed origins in the parent entity's updates, with perhaps a limit of 16 bones, this would allow some simple serverside ragdoll (Mitchell)
 4 darkplaces: add .psk/.psa (ut2003/ut2004) model support (Mitchell)