46#define RGBA_IMAGE_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
47#elif OOLITE_LITTLE_ENDIAN
48#define RGBA_IMAGE_TYPE GL_UNSIGNED_BYTE
50#error Neither OOLITE_BIG_ENDIAN nor OOLITE_LITTLE_ENDIAN is defined as nonzero!
54@interface OOConcreteTexture (Private)
59#if OO_TEXTURE_CUBE_MAP
65#if OOTEXTURE_RELOADABLE
79 options:(uint32_t)options
80 anisotropy:(GLfloat)anisotropy
81 lodBias:(GLfloat)lodBias
95#if GL_EXT_texture_filter_anisotropic
96 _anisotropy = OOClamp_0_1_f(anisotropy) *
gOOTextureInfo.anisotropyScale;
98#if GL_EXT_texture_lod_bias
117- (id)initWithPath:(NSString *)path
119 options:(uint32_t)options
120 anisotropy:(
float)anisotropy
121 lodBias:(GLfloat)lodBias
130 if ((
self = [
self initWithLoader:loader key:key options:options anisotropy:anisotropy lodBias:lodBias]))
132#if OOTEXTURE_RELOADABLE
117- (id)initWithPath:(NSString *)path {
…}
144 OOLog(
_trace ?
@"texture.allocTrace.dealloc" :
@"texture.dealloc",
@"Deallocating and uncaching texture %p",
self);
147#if OOTEXTURE_RELOADABLE
163#ifndef OOTEXTURE_NO_CACHE
181 NSString *stateDesc =
nil;
187 stateDesc = [
NSString stringWithFormat:@"%u x %u", _width, _height];
191 stateDesc =
@"LOAD ERROR";
196 stateDesc =
@"loading";
199 return [
NSString stringWithFormat:@"%@, %@", _key, stateDesc];
214#if OOTEXTURE_RELOADABLE
215 NSString *
name = [_path lastPathComponent];
217 NSString *
name = [[[[
self cacheKey] componentsSeparatedByString:@":"] objectAtIndex:0] lastPathComponent];
220 NSString *channelSuffix =
nil;
224 channelSuffix =
@":r";
228 channelSuffix =
@":g";
232 channelSuffix =
@":b";
236 channelSuffix =
@":a";
240 if (channelSuffix !=
nil)
name = [name stringByAppendingString:channelSuffix];
255#if GL_EXT_texture_lod_bias
256 if (
gOOTextureInfo.textureLODBiasAvailable)
OOGL(glTexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, _lodBias));
315#if OOTEXTURE_RELOADABLE
321 GLenum format, internalFormat, type;
333 glGetTexImage(GL_TEXTURE_2D, 0, format, type, px.
pixels);
335#if OO_TEXTURE_CUBE_MAP
340 uint8_t *pixels = px.
pixels;
343 for (i = 0; i < 6; i++)
345 glGetTexImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, format, type, pixels);
359#if GL_EXT_texture_rectangle
360 return _isRectTexture;
369#if OO_TEXTURE_CUBE_MAP
379#if GL_EXT_texture_rectangle
384 return NSMakeSize(1.0f, 1.0f);
396 return NSMakeSize(1.0f, 1.0f);
406 return NSMakeSize(1.0f, 1.0f);
421@implementation OOConcreteTexture (Private)
428 if ([_loader getResult:&pm format:&_format originalWidth:&_originalWidth originalHeight:&_originalHeight])
434#if OO_TEXTURE_CUBE_MAP
441#if !defined(NDEBUG) && OOTEXTURE_RELOADABLE
444 static unsigned dumpID = 0;
445 NSString *name = [
NSString stringWithFormat:@"tex dump %u \"%@\"", ++dumpID,[
self name]];
446 OOLog(
@"texture.trace.dump",
@"Dumped traced texture %@ to \'%@.png\'",
self, name);
477 OOGL(glGenTextures(1, &_textureName));
478 OOGL(glBindTexture(texTarget, _textureName));
485#if OO_TEXTURE_CUBE_MAP
486 if (texTarget == GL_TEXTURE_CUBE_MAP)
488 wrapS = wrapT = clampMode;
489 OOGL(glTexParameteri(texTarget, GL_TEXTURE_WRAP_R, clampMode));
493 OOGL(glTexParameteri(texTarget, GL_TEXTURE_WRAP_S, wrapS));
494 OOGL(glTexParameteri(texTarget, GL_TEXTURE_WRAP_T, wrapT));
502 filter = GL_LINEAR_MIPMAP_LINEAR;
504 else filter = GL_LINEAR;
505 OOGL(glTexParameteri(texTarget, GL_TEXTURE_MIN_FILTER, filter));
507#if GL_EXT_texture_filter_anisotropic
508 if (
gOOTextureInfo.anisotropyAvailable && mipMap && 1.0 < _anisotropy)
510 OOGL(glTexParameterf(texTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, _anisotropy));
517 else filter = GL_LINEAR;
518 OOGL(glTexParameteri(texTarget, GL_TEXTURE_MAG_FILTER, filter));
522 if (texTarget == GL_TEXTURE_2D)
525 OOLog(
@"texture.upload",
@"Uploaded texture %u (%ux%u pixels, %@)", _textureName, _width, _height, _key);
527#if OO_TEXTURE_CUBE_MAP
528 else if (texTarget == GL_TEXTURE_CUBE_MAP)
530 [
self uploadTextureCubeMapDataWithMipMap:mipMap format:_format];
531 OOLog(
@"texture.upload",
@"Uploaded cube map texture %u (%ux%ux6 pixels, %@)", _textureName, _width, _width, _key);
536 [
NSException raise:NSInternalInconsistencyException format:@"Unhandled texture target 0x%X.", texTarget];
542#if OOTEXTURE_RELOADABLE
555 GLenum glFormat = 0, internalFormat = 0, type = 0;
559 char *bytes = _bytes;
564 if (!
DecodeFormat(format, _options, &glFormat, &internalFormat, &type))
return;
566 while (0 < w && 0 < h)
568 OOGL(glTexImage2D(GL_TEXTURE_2D, level++, internalFormat, w, h, 0, glFormat, type, bytes));
570 bytes += w * components * h;
576 _mipLevels = level - 1;
581#if OO_TEXTURE_CUBE_MAP
586 GLenum glFormat = 0, internalFormat = 0, type = 0;
587 if (!
DecodeFormat(format, _options, &glFormat, &internalFormat, &type))
return;
591 size_t sideSize = _width * _width * components;
594 sideSize = sideSize * 4 / 3;
595 sideSize = (sideSize + 15) & ~15;
599 for (side = 0; side < 6; side++)
601 char *bytes = _bytes;
602 bytes += side * sideSize;
604 unsigned w = _width, level = 0;
608 OOGL(glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + side, level++, internalFormat, w, w, 0, glFormat, type, bytes));
610 bytes += w * w * components;
620 GLenum texTarget = GL_TEXTURE_2D;
621#if OO_TEXTURE_CUBE_MAP
624 texTarget = GL_TEXTURE_CUBE_MAP;
633 if (_loaded && _uploaded && _valid)
638 OOGL(glDeleteTextures(1, &_textureName));
641#if OOTEXTURE_RELOADABLE
644 OOLog(
@"texture.reload",
@"Reloading texture %@",
self);
659#if OOTEXTURE_RELOADABLE
673 NSCParameterAssert(outFormat != NULL && outInternalFormat != NULL && outType != NULL);
678 *outFormat = GL_RGBA;
679 *outInternalFormat = options &
kOOTextureSRGBA ? GL_SRGB_ALPHA : GL_RGBA;
680 *outType = RGBA_IMAGE_TYPE;
686 *outFormat = GL_ALPHA;
687 *outInternalFormat = GL_ALPHA8;
691 *outFormat = GL_LUMINANCE;
692 *outInternalFormat = GL_LUMINANCE8;
694 *outType = GL_UNSIGNED_BYTE;
698 *outFormat = GL_LUMINANCE_ALPHA;
699 *outInternalFormat = GL_LUMINANCE8_ALPHA8;
700 *outType = GL_UNSIGNED_BYTE;
static BOOL DecodeFormat(OOTextureDataFormat format, uint32_t options, GLenum *outFormat, GLenum *outInternalFormat, GLenum *outType)
#define OOLog(class, format,...)
NSString *const kOOLogParameterError
#define OO_ENTER_OPENGL()
void OODumpPixMap(OOPixMap pixMap, NSString *name)
unsigned short OOPixMapBytesPerPixelForFormat(OOPixMapFormat format) PURE_FUNC
const OOPixMap kOONullPixMap
OOPixMap OOAllocatePixMap(OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, size_t rowBytes, size_t bufferSize)
OOPixMap OOMakePixMap(void *pixels, OOPixMapDimension width, OOPixMapDimension height, OOPixMapFormat format, size_t rowBytes, size_t bufferSize)
BOOL OOIsValidPixMap(OOPixMap pixMap)
OOPixMap OODuplicatePixMap(OOPixMap srcPixMap, size_t desiredSize)
#define GL_TEXTURE_MAX_LEVEL
uint8_t OOTextureComponentsForFormat(OOTextureDataFormat format)
@ kOOTextureAllowRectTexture
@ kOOTextureExtractChannelA
@ kOOTextureExtractChannelB
@ kOOTextureMagFilterMask
@ kOOTextureExtractChannelMask
@ kOOTextureMinFilterMask
@ kOOTextureMinFilterMipMap
@ kOOTextureMagFilterNearest
@ kOOTextureExtractChannelG
@ kOOTextureExtractChannelR
@ kOOTextureMinFilterNearest
@ kOOTextureDataGrayscaleAlpha
@ kOOTextureDataGrayscale
OOPixMapFormat OOTextureDataFormat
OOTextureInfo gOOTextureInfo
OOTextureDataFormat _format
NSSize originalDimensions()
void ensureFinishedLoading()
NSString * descriptionComponents()
NSString * shortDescriptionComponents()
struct OOPixMap copyPixMapRepresentation()
BOOL isRectangleTexture()
OOTextureLoader * _loader
void uploadTextureDataWithMipMap:format:(BOOL mipMap,[format] OOTextureDataFormat format)
id loaderWithPath:options:(NSString *path,[options] uint32_t options)