Generated planet textures are now mip-mapped, and generated emission maps now inherit options (in particular, mip-mapping) from their source textures (in order of precedence: emission_and_illumination_map, emission_map or illumination_map).

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@4529 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2011-04-27 22:02:17 +00:00
parent 92749b1a1e
commit f4e20b12d5
8 changed files with 131 additions and 64 deletions

View File

@ -47,6 +47,10 @@ SOFTWARE.
OOColor *_illuminationColor;
BOOL _isCombinedMap;
uint32_t _textureOptions;
GLfloat _anisotropy;
GLfloat _lodBias;
#ifndef NDEBUG
NSString *_emissionDesc;
NSString *_illuminationDesc;
@ -60,12 +64,14 @@ SOFTWARE.
diffuseMap:(OOTexture *)diffuseMap
diffuseColor:(OOColor *)diffuseColor
illuminationMap:(OOTextureLoader *)illuminationMapLoader
illuminationColor:(OOColor *)illuminationColor;
illuminationColor:(OOColor *)illuminationColor
optionsSpecifier:(NSDictionary *)spec;
- (id) initWithEmissionAndIlluminationMap:(OOTextureLoader *)emissionAndIlluminationMapLoader
diffuseMap:(OOTexture *)diffuseMap
diffuseColor:(OOColor *)diffuseColor
emissionColor:(OOColor *)emissionColor
illuminationColor:(OOColor *)illuminationColor;
illuminationColor:(OOColor *)illuminationColor
optionsSpecifier:(NSDictionary *)spec;
@end

View File

@ -48,7 +48,8 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB);
diffuseColor:(OOColor *)diffuseColor
illuminationMap:(OOTextureLoader *)illuminationMapLoader
illuminationColor:(OOColor *)illuminationColor
isCombinedMap:(BOOL)isCombinedMap;
isCombinedMap:(BOOL)isCombinedMap
optionsSpecifier:(NSDictionary *)spec;
@end
@ -61,6 +62,7 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB);
diffuseColor:(OOColor *)diffuseColor
illuminationMap:(OOTextureLoader *)illuminationMapLoader
illuminationColor:(OOColor *)illuminationColor
optionsSpecifier:(NSDictionary *)spec
{
return [self initWithEmissionMap:emissionMapLoader
emissionColor:emissionColor
@ -68,7 +70,8 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB);
diffuseColor:diffuseColor
illuminationMap:illuminationMapLoader
illuminationColor:illuminationColor
isCombinedMap:NO];
isCombinedMap:NO
optionsSpecifier:spec];
}
@ -77,6 +80,7 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB);
diffuseColor:(OOColor *)diffuseColor
emissionColor:(OOColor *)emissionColor
illuminationColor:(OOColor *)illuminationColor
optionsSpecifier:(NSDictionary *)spec
{
return [self initWithEmissionMap:emissionAndIlluminationMapLoader
emissionColor:emissionColor
@ -84,7 +88,8 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB);
diffuseColor:diffuseColor
illuminationMap:nil
illuminationColor:illuminationColor
isCombinedMap:YES];
isCombinedMap:YES
optionsSpecifier:spec];
}
@ -95,6 +100,7 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB);
illuminationMap:(OOTextureLoader *)illuminationMapLoader
illuminationColor:(OOColor *)illuminationColor
isCombinedMap:(BOOL)isCombinedMap
optionsSpecifier:(NSDictionary *)spec
{
if (emissionMapLoader == nil && illuminationMapLoader == nil)
{
@ -104,7 +110,13 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB);
NSParameterAssert(illuminationMapLoader == nil || !isCombinedMap);
if ((self = [super init]))
uint32_t options;
GLfloat anisotropy;
GLfloat lodBias;
OOInterpretTextureSpecifier(spec, NULL, &options, &anisotropy, &lodBias);
options = OOApplyTetureOptionDefaults(options & ~kOOTextureExtractChannelMask);
if ((self = [super initWithPath:@"<generated emission map>" options:options]))
{
/* Illumination contribution is:
illuminationMap * illuminationColor * diffuseMap * diffuseColor
@ -119,7 +131,7 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB);
_cacheKey = [[NSString stringWithFormat:@"Combined emission map\nSingle source: %@\nemission:%@ * %@, illumination: %@ * %@ * %@",
_isCombinedMap ? @"yes" : @"no",
isCombinedMap ? @"yes" : @"no",
[emissionMapLoader cacheKey],
[emissionColor rgbaDescription],
[illuminationMapLoader cacheKey],
@ -130,6 +142,10 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB);
_illuminationColor = [illuminationColor retain];
_isCombinedMap = isCombinedMap;
_textureOptions = options;
_anisotropy = anisotropy;
_lodBias = lodBias;
/* Extract pixmap from diffuse map. This must be done in the main
thread even if scheduling is fixed, because it might involve
reading back pixels from OpenGL.
@ -234,6 +250,24 @@ static void ScaleToMatch(OOPixMap *pmA, OOPixMap *pmB);
#endif
- (uint32_t) textureOptions
{
return _textureOptions;
}
- (GLfloat) anisotropy
{
return _anisotropy;
}
- (GLfloat) lodBias
{
return _lodBias;
}
- (NSString *) cacheKey
{
return _cacheKey;

View File

@ -94,7 +94,8 @@ SOFTWARE.
diffuseMap:_diffuseMap
diffuseColor:diffuseColor
emissionColor:emissionColor
illuminationColor:illuminationColor];
illuminationColor:illuminationColor
optionsSpecifier:emissionAndIlluminationSpec];
}
else
{
@ -109,7 +110,8 @@ SOFTWARE.
diffuseMap:_diffuseMap
diffuseColor:diffuseColor
illuminationMap:illuminationMap
illuminationColor:illuminationColor];
illuminationColor:illuminationColor
optionsSpecifier:emissionSpec ?: illuminationSpec];
}
_emissionMap = [[OOTexture textureWithGenerator:[generator autorelease]] retain];

View File

@ -2,7 +2,7 @@
OOPixMapTextureLoader.h
Load a texture from a pixmap.
Load a texture from a pixmap. The loader takes ownership of the pixmap.
Copyright (C) 2010-2011 Jens Ayton

View File

@ -26,6 +26,7 @@ SOFTWARE.
*/
#import "OOPixMapTextureLoader.h"
#import "OOTextureScaling.h"
@implementation OOPixMapTextureLoader
@ -37,7 +38,7 @@ SOFTWARE.
if (freeWhenDone) _pixMap = pixMap;
else _pixMap = OODuplicatePixMap(_pixMap, 0);
_texOptions = options;
_texOptions = OOApplyTetureOptionDefaults(options);
if (!OOIsValidPixMap(_pixMap)) DESTROY(self);
}
@ -56,6 +57,22 @@ SOFTWARE.
- (void) loadTexture
{
// Generate mip maps if needed.
if ((_texOptions & kOOTextureMinFilterMask) == kOOTextureMinFilterMipMap)
{
size_t size = OOMinimumPixMapBufferSize(_pixMap) * 4 / 3;
BOOL generateMipMaps = OOExpandPixMap(&_pixMap, size);
if (generateMipMaps)
{
OOGenerateMipMaps(_pixMap.pixels,_pixMap.width, _pixMap.height, _pixMap.format);
}
else
{
_texOptions = (_texOptions & ~kOOTextureMinFilterMask) | kOOTextureMinFilterMipMap;
}
}
// Set up output ivars as per OOTextureLoader contract.
_data = _pixMap.pixels;
_width = _pixMap.width;
_height = _pixMap.height;

View File

@ -284,3 +284,5 @@ BOOL OOCubeMapsAvailable(void);
may be NULL.
*/
BOOL OOInterpretTextureSpecifier(id specifier, NSString **outName, uint32_t *outOptions, float *outAnisotropy, float *outLODBias);
uint32_t OOApplyTetureOptionDefaults(uint32_t options);

View File

@ -123,53 +123,6 @@ static NSString *sGlobalTraceContext = nil;
if (EXPECT_NOT(name == nil)) return nil;
if (EXPECT_NOT(!sCheckedExtensions)) [self checkExtensions];
// Set default flags if needed
if ((options & kOOTextureMinFilterMask) == kOOTextureMinFilterDefault)
{
if ([UNIVERSE reducedDetail])
{
options |= kOOTextureMinFilterLinear;
}
else
{
options |= kOOTextureMinFilterMipMap;
}
}
if (!gOOTextureInfo.textureMaxLevelAvailable)
{
/* In the unlikely case of an OpenGL system without GL_SGIS_texture_lod,
disable mip-mapping completely. Strictly this is only needed for
non-square textures, but extra logic for such a rare case isn't
worth it.
*/
if ((options & kOOTextureMinFilterMask) == kOOTextureMinFilterMipMap)
{
options ^= kOOTextureMinFilterMipMap ^ kOOTextureMinFilterLinear;
}
}
if (options & kOOTextureAllowRectTexture)
{
// Apply rectangle texture restrictions (regardless of whether rectangle textures are available, for consistency)
options &= kOOTextureFlagsAllowedForRectangleTexture;
if ((options & kOOTextureMinFilterMask) == kOOTextureMinFilterMipMap)
{
options = (kOOTextureMinFilterMask & ~kOOTextureMinFilterMask) | kOOTextureMinFilterLinear;
}
#if GL_EXT_texture_rectangle
if (!gOOTextureInfo.rectangleTextureAvailable)
{
options &= ~kOOTextureAllowRectTexture;
}
#else
options &= ~kOOTextureAllowRectTexture;
#endif
}
options &= kOOTextureDefinedFlags;
if (!gOOTextureInfo.anisotropyAvailable || (options & kOOTextureMinFilterMask) != kOOTextureMinFilterMipMap)
{
anisotropy = 0.0f;
@ -180,7 +133,7 @@ static NSString *sGlobalTraceContext = nil;
}
noFNF = (options & kOOTextureNoFNFMessage) != 0;
options &= ~kOOTextureNoFNFMessage;
options = OOApplyTetureOptionDefaults(options & ~kOOTextureNoFNFMessage);
// Look for existing texture
key = [NSString stringWithFormat:@"%@%@%@:0x%.4X/%g/%g", directory ? directory : (NSString *)@"", directory ? @"/" : @"", name, options, anisotropy, lodBias];
@ -257,7 +210,7 @@ static NSString *sGlobalTraceContext = nil;
OOTexture *result = [[[OOConcreteTexture alloc] initWithLoader:generator
key:[generator cacheKey]
options:[generator textureOptions]
options:OOApplyTetureOptionDefaults([generator textureOptions])
anisotropy:[generator anisotropy]
lodBias:[generator lodBias]] autorelease];
@ -761,3 +714,56 @@ BOOL OOInterpretTextureSpecifier(id specifier, NSString **outName, uint32_t *out
return YES;
}
uint32_t OOApplyTetureOptionDefaults(uint32_t options)
{
// Set default flags if needed
if ((options & kOOTextureMinFilterMask) == kOOTextureMinFilterDefault)
{
if ([UNIVERSE reducedDetail])
{
options |= kOOTextureMinFilterLinear;
}
else
{
options |= kOOTextureMinFilterMipMap;
}
}
if (!gOOTextureInfo.textureMaxLevelAvailable)
{
/* In the unlikely case of an OpenGL system without GL_SGIS_texture_lod,
disable mip-mapping completely. Strictly this is only needed for
non-square textures, but extra logic for such a rare case isn't
worth it.
*/
if ((options & kOOTextureMinFilterMask) == kOOTextureMinFilterMipMap)
{
options ^= kOOTextureMinFilterMipMap ^ kOOTextureMinFilterLinear;
}
}
if (options & kOOTextureAllowRectTexture)
{
// Apply rectangle texture restrictions (regardless of whether rectangle textures are available, for consistency)
options &= kOOTextureFlagsAllowedForRectangleTexture;
if ((options & kOOTextureMinFilterMask) == kOOTextureMinFilterMipMap)
{
options = (kOOTextureMinFilterMask & ~kOOTextureMinFilterMask) | kOOTextureMinFilterLinear;
}
#if GL_EXT_texture_rectangle
if (!gOOTextureInfo.rectangleTextureAvailable)
{
options &= ~kOOTextureAllowRectTexture;
}
#else
options &= ~kOOTextureAllowRectTexture;
#endif
}
options &= kOOTextureDefinedFlags;
return options;
}

View File

@ -227,7 +227,7 @@ int32_t OSAtomicAdd32(int32_t __theAmount, volatile int32_t *__theValue);
BOOL dumpThis = (dumpPlanes & DUMP_CHANNELS) != 0; \
SInt32 dumpID = dumpThis ? OSAtomicAdd32(1, &sPreviousDumpID) : 0;
#define DUMP_MIP_MAP_DUMP(px, w, h) if (dumpThis) DumpMipMap(px, w, h, dumpPlanes, dumpID, dumpLevel++);
static void DumpMipMap(void *data, OOPixMapDimension width, OOPixMapDimension height, OOPixMapComponentCount planes, SInt32 ID, uint32_t level);
static void DumpMipMap(void *data, OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, SInt32 ID, uint32_t level);
#else
#define DUMP_MIP_MAP_PREPARE(pl) do { (void)pl; } while (0)
#define DUMP_MIP_MAP_DUMP(px, w, h) do { (void)px; (void)w; (void)h; } while (0)
@ -878,10 +878,10 @@ static void ScaleToHalf_4_x2(void *srcBytes, void *dstBytes, OOPixMapDimension s
#if DUMP_MIP_MAPS
static void DumpMipMap(void *data, OOPixMapDimension width, OOPixMapDimension height, OOPixMapComponentCount components, SInt32 ID, uint32_t level)
static void DumpMipMap(void *data, OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, SInt32 ID, uint32_t level)
{
OOPixMap pixMap = OOMakePixMap(data, width, height, components, 0, 0);
OODumpPixMap(pixMap, [NSString stringWithFormat:@"mipmap dump ID %u lv%u %uch %ux%u", ID, level, components, width, height]);
OOPixMap pixMap = OOMakePixMap(data, width, height, format, 0, 0);
OODumpPixMap(pixMap, [NSString stringWithFormat:@"mipmap dump ID %u lv%u %@ %ux%u", ID, level, OOPixMapFormatName(format), width, height]);
}
#endif