OpenGL2: Use RGBM instead of RGBE encoding for lightmaps.

This commit is contained in:
SmileTheory 2013-09-16 05:57:14 -07:00
parent 7e875c6941
commit e80faf812e
4 changed files with 26 additions and 38 deletions

View file

@ -142,49 +142,32 @@ static void R_ColorShiftLightingFloats(float in[4], float out[4], float scale )
out[3] = in[3];
}
void ColorToRGBE(const vec3_t color, unsigned char rgbe[4])
// Modified from http://graphicrants.blogspot.jp/2009/04/rgbm-color-encoding.html
void ColorToRGBM(const vec3_t color, unsigned char rgbm[4])
{
vec3_t sample;
float maxComponent;
int e;
VectorCopy(color, sample);
VectorScale(color, 1.0f / 32.0f, sample);
maxComponent = sample[0];
if(sample[1] > maxComponent)
maxComponent = sample[1];
if(sample[2] > maxComponent)
maxComponent = sample[2];
if(0.000001f > maxComponent)
maxComponent = 0.000001f;
if(maxComponent > 1.0f)
maxComponent = 1.0f;
if(maxComponent < 1e-32)
{
rgbe[0] = 0;
rgbe[1] = 0;
rgbe[2] = 0;
rgbe[3] = 0;
}
else
{
#if 0
maxComponent = frexp(maxComponent, &e) * 255.0 / maxComponent;
rgbe[0] = (unsigned char) (sample[0] * maxComponent);
rgbe[1] = (unsigned char) (sample[1] * maxComponent);
rgbe[2] = (unsigned char) (sample[2] * maxComponent);
rgbe[3] = (unsigned char) (e + 128);
#else
e = ceil(log(maxComponent) / log(2.0f));//ceil(log2(maxComponent));
VectorScale(sample, 1.0 / pow(2.0f, e)/*exp2(e)*/, sample);
VectorScale(sample, 1.0f / maxComponent, sample);
rgbe[0] = (unsigned char) (sample[0] * 255);
rgbe[1] = (unsigned char) (sample[1] * 255);
rgbe[2] = (unsigned char) (sample[2] * 255);
rgbe[3] = (unsigned char) (e + 128);
#endif
}
rgbm[0] = (unsigned char) (sample[0] * 255);
rgbm[1] = (unsigned char) (sample[1] * 255);
rgbm[2] = (unsigned char) (sample[2] * 255);
rgbm[3] = (unsigned char) (maxComponent * 255);
}
void ColorToRGBA16F(const vec3_t color, unsigned short rgba16f[4])
{
rgba16f[0] = FloatToHalf(color[0]);
@ -290,8 +273,13 @@ static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) {
tr.deluxemaps = ri.Hunk_Alloc( tr.numLightmaps * sizeof(image_t *), h_low );
}
if (r_hdr->integer && glRefConfig.textureFloat && glRefConfig.halfFloatPixel)
textureInternalFormat = GL_RGBA16F_ARB;
if (r_hdr->integer)
{
if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel)
textureInternalFormat = GL_RGBA16F_ARB;
else
textureInternalFormat = GL_RGBA8;
}
if (r_mergeLightmaps->integer)
{
@ -429,7 +417,7 @@ static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) {
if (glRefConfig.textureFloat && glRefConfig.halfFloatPixel)
ColorToRGBA16F(color, (unsigned short *)(&image[j*8]));
else
ColorToRGBE(color, &image[j*4]);
ColorToRGBM(color, &image[j*4]);
}
else
{