Skip to content

Commit

Permalink
Added: Texture analysis TA_SKY_LINE_BOTTOM_COLOR
Browse files Browse the repository at this point in the history
Rather than use the average top line texture color for the lower hemisphere
of the sky sphere renderer, average the bottom line and use that instead.
This looks a little better than mountains that fade into a deep red mist...
  • Loading branch information
danij-deng committed Nov 26, 2011
1 parent d00e5e8 commit 8875924
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 26 deletions.
3 changes: 2 additions & 1 deletion doomsday/engine/portable/include/texture.h
Expand Up @@ -34,7 +34,8 @@ typedef enum {
TA_COLORPALETTE = TEXTURE_ANALYSIS_FIRST,
TA_SPRITE_AUTOLIGHT,
TA_MAP_AMBIENTLIGHT,
TA_SKY_SPHEREFADEOUT,
TA_SKY_LINE_TOP_COLOR,
TA_SKY_LINE_BOTTOM_COLOR,
TEXTURE_ANALYSIS_COUNT
} texture_analysisid_t;

Expand Down
33 changes: 31 additions & 2 deletions doomsday/engine/portable/src/gl_texmanager.c
Expand Up @@ -3055,15 +3055,15 @@ static void performImageAnalyses(texture_t* tex, const image_t* image,
// Average top line color for sky sphere fadeout?
if(TST_GENERAL == spec->type && TC_SKYSPHERE_DIFFUSE == TS_GENERAL(spec)->context)
{
averagecolor_analysis_t* sf = (averagecolor_analysis_t*) Texture_Analysis(tex, TA_SKY_SPHEREFADEOUT);
averagecolor_analysis_t* sf = (averagecolor_analysis_t*) Texture_Analysis(tex, TA_SKY_LINE_TOP_COLOR);
boolean firstInit = (!sf);

if(firstInit)
{
sf = (averagecolor_analysis_t*) malloc(sizeof *sf);
if(!sf)
Con_Error("Textures::performImageAnalyses: Failed on allocation of %lu bytes for new AverageColorAnalysis.", (unsigned long) sizeof *sf);
Texture_AttachAnalysis(tex, TA_SKY_SPHEREFADEOUT, sf);
Texture_AttachAnalysis(tex, TA_SKY_LINE_TOP_COLOR, sf);
}

if(firstInit || forceUpdate)
Expand All @@ -3080,6 +3080,35 @@ static void performImageAnalyses(texture_t* tex, const image_t* image,
}
}
}

// Average bottom line color for sky sphere fadeout?
if(TST_GENERAL == spec->type && TC_SKYSPHERE_DIFFUSE == TS_GENERAL(spec)->context)
{
averagecolor_analysis_t* sf = (averagecolor_analysis_t*) Texture_Analysis(tex, TA_SKY_LINE_BOTTOM_COLOR);
boolean firstInit = (!sf);

if(firstInit)
{
sf = (averagecolor_analysis_t*) malloc(sizeof *sf);
if(!sf)
Con_Error("Textures::performImageAnalyses: Failed on allocation of %lu bytes for new AverageColorAnalysis.", (unsigned long) sizeof *sf);
Texture_AttachAnalysis(tex, TA_SKY_LINE_BOTTOM_COLOR, sf);
}

if(firstInit || forceUpdate)
{
if(0 == image->paletteId)
{
FindAverageLineColor(image->pixels, image->width, image->height,
image->pixelSize, image->height-1, sf->color);
}
else
{
FindAverageLineColorIdx(image->pixels, image->width, image->height,
image->height-1, R_ToColorPalette(image->paletteId), false, sf->color);
}
}
}
}

static texturevariant_t* tryLoadImageAndPrepareVariant(texture_t* tex,
Expand Down
35 changes: 24 additions & 11 deletions doomsday/engine/portable/src/r_sky.c
Expand Up @@ -101,7 +101,8 @@ static void configureDefaultSky(void)
static void calculateSkyLightColor(void)
{
float avgMaterialColor[3];
rcolor_t capColor = { 0, 0, 0, 0 };
rcolor_t topCapColor = { 0, 0, 0, 0 };
rcolor_t bottomCapColor = { 0, 0, 0, 0 };
skylayer_t* slayer;
int i, avgCount;

Expand Down Expand Up @@ -136,12 +137,19 @@ static void calculateSkyLightColor(void)
if(i == firstSkyLayer && MSU_texture(ms, MTU_PRIMARY))
{
const texture_t* tex = MSU_texture(ms, MTU_PRIMARY);
const averagecolor_analysis_t* avgTopColor = (const averagecolor_analysis_t*)
Texture_Analysis(tex, TA_SKY_SPHEREFADEOUT);
assert(avgTopColor);
capColor.red = avgTopColor->color[CR];
capColor.green = avgTopColor->color[CG];
capColor.blue = avgTopColor->color[CB];
const averagecolor_analysis_t* avgLineColor = (const averagecolor_analysis_t*)
Texture_Analysis(tex, TA_SKY_LINE_TOP_COLOR);
assert(avgLineColor);
topCapColor.red = avgLineColor->color[CR];
topCapColor.green = avgLineColor->color[CG];
topCapColor.blue = avgLineColor->color[CB];

avgLineColor = (const averagecolor_analysis_t*)
Texture_Analysis(tex, TA_SKY_LINE_BOTTOM_COLOR);
assert(avgLineColor);
bottomCapColor.red = avgLineColor->color[CR];
bottomCapColor.green = avgLineColor->color[CG];
bottomCapColor.blue = avgLineColor->color[CB];
}

if(!(skyModelsInited && !alwaysDrawSphere))
Expand All @@ -160,10 +168,15 @@ static void calculateSkyLightColor(void)
skyAmbientColor[CB] = avgMaterialColor[CB];

// The caps cover a large amount of the sky sphere, so factor it in too.
skyAmbientColor[CR] += 2 * capColor.red;
skyAmbientColor[CG] += 2 * capColor.green;
skyAmbientColor[CB] += 2 * capColor.blue;
avgCount += 2;
skyAmbientColor[CR] += topCapColor.red;
skyAmbientColor[CG] += topCapColor.green;
skyAmbientColor[CB] += topCapColor.blue;
++avgCount;

skyAmbientColor[CR] += bottomCapColor.red;
skyAmbientColor[CG] += bottomCapColor.green;
skyAmbientColor[CB] += bottomCapColor.blue;
++avgCount;

skyAmbientColor[CR] /= avgCount;
skyAmbientColor[CG] /= avgCount;
Expand Down
32 changes: 20 additions & 12 deletions doomsday/engine/portable/src/rend_sky.c
Expand Up @@ -278,7 +278,13 @@ static void renderHemisphere(void)
glDisable(GL_TEXTURE_2D);
}

static void configureRenderHemisphereStateForLayer(int layer, boolean setupCap)
typedef enum {
HC_NONE = 0,
HC_TOP,
HC_BOTTOM
} hemispherecap_t;

static void configureRenderHemisphereStateForLayer(int layer, hemispherecap_t setupCap)
{
int magMode;
DGLuint tex;
Expand All @@ -288,7 +294,7 @@ static void configureRenderHemisphereStateForLayer(int layer, boolean setupCap)
tex = 0;
magMode = GL_LINEAR;
skyTexWidth = skyTexHeight = 1;
if(setupCap)
if(setupCap != HC_NONE)
skyFadeout = false;
}
else
Expand Down Expand Up @@ -318,16 +324,17 @@ static void configureRenderHemisphereStateForLayer(int layer, boolean setupCap)
magMode = MSU(ms, MTU_PRIMARY).magMode;
Texture_Dimensions(MSU_texture(ms, MTU_PRIMARY), &skyTexWidth, &skyTexHeight);

if(setupCap)
if(setupCap != HC_NONE)
{
const averagecolor_analysis_t* avgTopColor = (const averagecolor_analysis_t*)
Texture_Analysis(MSU_texture(ms, MTU_PRIMARY), TA_SKY_SPHEREFADEOUT);
const averagecolor_analysis_t* avgLineColor = (const averagecolor_analysis_t*)
Texture_Analysis(MSU_texture(ms, MTU_PRIMARY),
(setupCap == HC_TOP? TA_SKY_LINE_TOP_COLOR : TA_SKY_LINE_BOTTOM_COLOR));
const float fadeoutLimit = R_SkyLayerFadeoutLimit(layer);
assert(avgTopColor);
assert(avgLineColor);

skyCapColor.red = avgTopColor->color[CR];
skyCapColor.green = avgTopColor->color[CG];
skyCapColor.blue = avgTopColor->color[CB];
skyCapColor.red = avgLineColor->color[CR];
skyCapColor.green = avgLineColor->color[CG];
skyCapColor.blue = avgLineColor->color[CB];

// Is the colored fadeout in use?
skyFadeout = (skyCapColor.red >= fadeoutLimit ||
Expand All @@ -337,7 +344,7 @@ static void configureRenderHemisphereStateForLayer(int layer, boolean setupCap)
}

skyTexOffset = R_SkyLayerOffset(layer);
if(setupCap && !skyFadeout)
if(setupCap != HC_NONE && !skyFadeout)
{
// Default color is black.
skyCapColor.red = skyCapColor.green = skyCapColor.blue = 0;
Expand All @@ -359,6 +366,7 @@ static void renderSkyHemisphere(int flags)
{
int firstSkyLayer = R_SkyFirstActiveLayer();
const boolean yflip = !!(flags & SKYHEMI_LOWER);
hemispherecap_t cap = !!(flags & SKYHEMI_LOWER)? HC_BOTTOM : HC_TOP;

if(yflip)
{
Expand All @@ -369,7 +377,7 @@ static void renderSkyHemisphere(int flags)
}

// First render the cap and the background for fadeouts, if needed.
configureRenderHemisphereStateForLayer(firstSkyLayer, true/*setup cap*/);
configureRenderHemisphereStateForLayer(firstSkyLayer, cap);
renderHemisphereCap();

if(!(flags & SKYHEMI_JUST_CAP))
Expand All @@ -383,7 +391,7 @@ static void renderSkyHemisphere(int flags)
if(!R_SkyLayerActive(i)) continue;
if(i != firstSkyLayer)
{
configureRenderHemisphereStateForLayer(i, false/*do not setup cap*/);
configureRenderHemisphereStateForLayer(i, HC_NONE);
}

popTextureMatrix = false;
Expand Down

0 comments on commit 8875924

Please sign in to comment.