[Quake2world-dev] r293 - quake2world/trunk/src
jdolan at jdolan.dyndns.org
jdolan at jdolan.dyndns.org
Sun Mar 22 03:43:31 UTC 2009
Author: jdolan
Date: 2009-03-22 03:43:30 +0000 (Sun, 22 Mar 2009)
New Revision: 293
Modified:
quake2world/trunk/src/r_image.c
quake2world/trunk/src/r_image.h
quake2world/trunk/src/r_lightmap.c
Log:
Use GL_RGB for lightmaps/deluxemaps, save a buttload of texture memory.
Modified: quake2world/trunk/src/r_image.c
===================================================================
--- quake2world/trunk/src/r_image.c 2009-03-21 18:14:35 UTC (rev 292)
+++ quake2world/trunk/src/r_image.c 2009-03-22 03:43:30 UTC (rev 293)
@@ -214,35 +214,40 @@
/*
* R_SoftenTexture
*/
-void R_SoftenTexture(byte *in, int width, int height){
+void R_SoftenTexture(byte *in, int width, int height, imagetype_t type){
byte *out;
- int i, j, k;
+ int i, j, k, bpp;
byte *src, *dest;
byte *u, *d, *l, *r;
+ if(type == it_lightmap || type == it_deluxemap)
+ bpp = 3;
+ else
+ bpp = 4;
+
// soften into a copy of the original image, as in-place would be incorrect
- out = (byte *)Z_Malloc(width * height * 4);
- memcpy(out, in, width * height * 4);
+ out = (byte *)Z_Malloc(width * height * bpp);
+ memcpy(out, in, width * height * bpp);
for(i = 1; i < height - 1; i++){
for(j = 1; j < width - 1; j++){
- src = in + ((i * width) + j) * 4; // current input pixel
+ src = in + ((i * width) + j) * bpp; // current input pixel
- u = (src - (width * 4)); // and it's neighbors
- d = (src + (width * 4));
- l = (src - (1 * 4));
- r = (src + (1 * 4));
+ u = (src - (width * bpp)); // and it's neighbors
+ d = (src + (width * bpp));
+ l = (src - (1 * bpp));
+ r = (src + (1 * bpp));
- dest = out + ((i * width) + j) * 4; // current output pixel
+ dest = out + ((i * width) + j) * bpp; // current output pixel
- for(k = 0; k < 4; k++)
+ for(k = 0; k < bpp; k++)
dest[k] = (u[k] + d[k] + l[k] + r[k]) / 4;
}
}
// copy the softened image over the input image, and free it
- memcpy(in, out, width * height * 4);
+ memcpy(in, out, width * height * bpp);
Z_Free(out);
}
@@ -293,29 +298,33 @@
* the image's average color. Also handles image inversion and monochrome. This is
* all munged into one function to reduce loops on level load.
*/
-void R_FilterTexture(unsigned *in, int width, int height, vec3_t color, imagetype_t type){
+void R_FilterTexture(byte *in, int width, int height, vec3_t color, imagetype_t type){
vec3_t intensity, luminosity, temp;
- int i, j, c, mask;
+ int i, j, c, bpp, mask;
unsigned col[3];
byte *p;
float max, d;
- p = (byte *)in;
+ p = in;
c = width * height;
- mask = 0; // monochrome/invert
+ bpp = mask = 0; // monochrome / invert
- if(type == it_world || type == it_effect || type == it_material)
+ if(type == it_world || type == it_effect || type == it_material){
+ bpp = 4;
mask = 1;
- else if(type == it_lightmap)
+ }
+ else if(type == it_lightmap){
+ bpp = 3;
mask = 2;
+ }
if(color) // compute average color
VectorClear(col);
VectorSet(luminosity, 0.2125, 0.7154, 0.0721);
- for(i = 0; i < c; i++, p+= 4){
+ for(i = 0; i < c; i++, p+= bpp){
VectorScale(p, 1.0 / 255.0, temp); // convert to float
@@ -447,7 +456,7 @@
}
if(type == it_effect || type == it_world || type == it_material || type == it_skin) // and filtered
- R_FilterTexture(scaled, upload_width, upload_height, color, type);
+ R_FilterTexture((byte *)scaled, upload_width, upload_height, color, type);
if(mipmap){ // and mipmapped
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, r_filter_min);
Modified: quake2world/trunk/src/r_image.h
===================================================================
--- quake2world/trunk/src/r_image.h 2009-03-21 18:14:35 UTC (rev 292)
+++ quake2world/trunk/src/r_image.h 2009-03-22 03:43:30 UTC (rev 293)
@@ -88,8 +88,8 @@
extern image_t *r_warptexture;
// r_image.c
-void R_SoftenTexture(byte *in, int width, int height);
-void R_FilterTexture(unsigned *in, int width, int height, vec3_t color, imagetype_t type);
+void R_SoftenTexture(byte *in, int width, int height, imagetype_t type);
+void R_FilterTexture(byte *in, int width, int height, vec3_t color, imagetype_t type);
image_t *R_UploadImage(const char *name, void *data, int width, int height, imagetype_t type);
image_t *R_LoadImage(const char *name, imagetype_t type);
void R_TextureMode(const char *mode);
Modified: quake2world/trunk/src/r_lightmap.c
===================================================================
--- quake2world/trunk/src/r_lightmap.c 2009-03-21 18:14:35 UTC (rev 292)
+++ quake2world/trunk/src/r_lightmap.c 2009-03-22 03:43:30 UTC (rev 293)
@@ -43,8 +43,8 @@
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r_lightmaps.size, r_lightmaps.size,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, r_lightmaps.sample_buffer);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, r_lightmaps.size, r_lightmaps.size,
+ 0, GL_RGB, GL_UNSIGNED_BYTE, r_lightmaps.sample_buffer);
r_lightmaps.lightmap_texnum++;
@@ -60,16 +60,16 @@
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r_lightmaps.size, r_lightmaps.size,
- 0, GL_RGBA, GL_UNSIGNED_BYTE, r_lightmaps.direction_buffer);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, r_lightmaps.size, r_lightmaps.size,
+ 0, GL_RGB, GL_UNSIGNED_BYTE, r_lightmaps.direction_buffer);
r_lightmaps.deluxemap_texnum++;
}
// clear the allocation block and buffers
- memset(r_lightmaps.allocated, 0, r_lightmaps.size * sizeof(unsigned));
- memset(r_lightmaps.sample_buffer, 0, r_lightmaps.size * r_lightmaps.size * sizeof(unsigned));
- memset(r_lightmaps.direction_buffer, 0, r_lightmaps.size * r_lightmaps.size * sizeof(unsigned));
+ memset(r_lightmaps.allocated, 0, r_lightmaps.size * 3);
+ memset(r_lightmaps.sample_buffer, 0, r_lightmaps.size * r_lightmaps.size * 3);
+ memset(r_lightmaps.direction_buffer, 0, r_lightmaps.size * r_lightmaps.size * 3);
}
@@ -116,7 +116,7 @@
const int smax = (surf->stextents[0] / r_loadmodel->lightmap_scale) + 1;
const int tmax = (surf->stextents[1] / r_loadmodel->lightmap_scale) + 1;
- stride -= (smax * 4);
+ stride -= (smax * 3);
for(i = 0; i < tmax; i++, sout += stride, dout += stride){
for(j = 0; j < smax; j++){
@@ -124,17 +124,15 @@
sout[0] = 255;
sout[1] = 255;
sout[2] = 255;
- sout[3] = 255;
- sout += 4;
+ sout += 3;
if(r_loadmodel->version == BSP_VERSION_){
dout[0] = 127;
dout[1] = 127;
dout[2] = 255;
- dout[3] = 255;
- dout += 4;
+ dout += 3;
}
}
}
@@ -158,36 +156,34 @@
const int tmax = (surf->stextents[1] / r_loadmodel->lightmap_scale) + 1;
const int size = smax * tmax;
- stride -= (smax * 4);
+ stride -= (smax * 3);
- lightmap = (byte *)Z_Malloc(size * 4);
+ lightmap = (byte *)Z_Malloc(size * 3);
lm = lightmap;
deluxemap = dm = NULL;
if(r_loadmodel->version == BSP_VERSION_){
- deluxemap = (byte *)Z_Malloc(size * 4);
+ deluxemap = (byte *)Z_Malloc(size * 3);
dm = deluxemap;
}
// convert the raw lightmap samples to RGBA for softening
- for(i = j = 0; i < size; i++, lm += 4, dm += 4){
+ for(i = j = 0; i < size; i++, lm += 3, dm += 3){
lm[0] = surf->samples[j++];
lm[1] = surf->samples[j++];
lm[2] = surf->samples[j++];
- lm[3] = 255; // pad alpha
// read in directional samples for deluxe mapping as well
if(r_loadmodel->version == BSP_VERSION_){
dm[0] = surf->samples[j++];
dm[1] = surf->samples[j++];
dm[2] = surf->samples[j++];
- dm[3] = 255; // pad alpha
}
}
// apply modulate, contrast, resolve average surface color, etc..
- R_FilterTexture((unsigned *)lightmap, smax, tmax, surf->color, it_lightmap);
+ R_FilterTexture(lightmap, smax, tmax, surf->color, it_lightmap);
if(surf->texinfo->flags & (SURF_BLEND33 | SURF_ALPHATEST))
surf->color[3] = 0.25;
@@ -199,10 +195,10 @@
// soften it if it's sufficiently large
if(r_soften->value && size > 128){
for(i = 0; i < r_soften->value; i++){
- R_SoftenTexture(lightmap, smax, tmax);
+ R_SoftenTexture(lightmap, smax, tmax, it_lightmap);
if(r_loadmodel->version == BSP_VERSION_)
- R_SoftenTexture(deluxemap, smax, tmax);
+ R_SoftenTexture(deluxemap, smax, tmax, it_deluxemap);
}
}
@@ -224,8 +220,7 @@
sout[0] = lm[0];
sout[1] = lm[1];
sout[2] = lm[2];
- sout[3] = lm[3];
- sout += 4;
+ sout += 3;
// and to the surface, discarding alpha
l[0] = lm[0];
@@ -233,17 +228,16 @@
l[2] = lm[2];
l += 3;
- lm += 4;
+ lm += 3;
// lastly copy the deluxemap to the strided block
if(r_loadmodel->version == BSP_VERSION_){
dout[0] = dm[0];
dout[1] = dm[1];
dout[2] = dm[2];
- dout[3] = dm[3];
- dout += 4;
+ dout += 3;
- dm += 4;
+ dm += 3;
}
}
}
@@ -282,12 +276,12 @@
surf->deluxemap_texnum = r_lightmaps.deluxemap_texnum;
samples = r_lightmaps.sample_buffer;
- samples += (surf->light_t * r_lightmaps.size + surf->light_s) * 4;
+ samples += (surf->light_t * r_lightmaps.size + surf->light_s) * 3;
directions = r_lightmaps.direction_buffer;
- directions += (surf->light_t * r_lightmaps.size + surf->light_s) * 4;
+ directions += (surf->light_t * r_lightmaps.size + surf->light_s) * 3;
- stride = r_lightmaps.size * 4;
+ stride = r_lightmaps.size * 3;
if(surf->samples)
R_BuildLightmap(surf, samples, directions, stride);
More information about the Quake2World-dev
mailing list