New texture code (for models with shaders only). Somewhat buggy (notably, player ship is untextured after dying and respawning) but seems stable. Also removed a spurious assert from sound code.
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@929 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
c66ebf27a0
commit
bdbe1b72ff
@ -285,6 +285,10 @@
|
||||
1A3A04620BC547DC00B5E2D9 /* OOTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A3A04610BC547DC00B5E2D9 /* OOTypes.h */; };
|
||||
1A3AFF1F0BC4462200B5E2D9 /* OOJSVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A3AFF1D0BC4462200B5E2D9 /* OOJSVector.h */; };
|
||||
1A3AFF200BC4462200B5E2D9 /* OOJSVector.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A3AFF1E0BC4462200B5E2D9 /* OOJSVector.m */; };
|
||||
1A43234C0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A43234A0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h */; };
|
||||
1A43234D0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A43234B0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m */; };
|
||||
1A43234E0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A43234A0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h */; };
|
||||
1A43234F0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A43234B0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m */; };
|
||||
1A451D8D0BB1BD2A004CD72F /* OOMaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A9404920BAF4582005F6CF3 /* OOMaths.h */; };
|
||||
1A472917096B5454000E78D8 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A472916096B5454000E78D8 /* CoreAudio.framework */; };
|
||||
1A472921096B5468000E78D8 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A47291F096B5468000E78D8 /* AudioToolbox.framework */; };
|
||||
@ -357,7 +361,7 @@
|
||||
1A9406B40BAF67BF005F6CF3 /* OOTriangle.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A9406B20BAF67BF005F6CF3 /* OOTriangle.h */; };
|
||||
1A9406B50BAF67BF005F6CF3 /* OOTriangle.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A9406B30BAF67BF005F6CF3 /* OOTriangle.m */; settings = {COMPILER_FLAGS = "-O3 -falign-loops=32 -falign-loops-max-skip=31 -falign-functions=32"; }; };
|
||||
1AB01ABE0BB15AED00F1B949 /* OOTextureScaling.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB01ABC0BB15AED00F1B949 /* OOTextureScaling.h */; };
|
||||
1AB01B5F0BB1639600F1B949 /* OOTextureScaling.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AB01ABD0BB15AED00F1B949 /* OOTextureScaling.m */; settings = {COMPILER_FLAGS = "-O3 -falign-loops=32 -fstrict-aliasing -falign-loops-max-skip=31"; }; };
|
||||
1AB01B5F0BB1639600F1B949 /* OOTextureScaling.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AB01ABD0BB15AED00F1B949 /* OOTextureScaling.m */; };
|
||||
1AB01BBB0BB16A8A00F1B949 /* OOFastArithmetic.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB01BB90BB16A8A00F1B949 /* OOFastArithmetic.h */; };
|
||||
1AB01BBC0BB16A8A00F1B949 /* OOFastArithmetic.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AB01BBA0BB16A8A00F1B949 /* OOFastArithmetic.m */; settings = {COMPILER_FLAGS = "-O3 -falign-loops=32 -falign-loops-max-skip=31 -falign-functions=32"; }; };
|
||||
1ADF5CEC0B9DF59A00FDB2A3 /* OOCacheManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A231A170B9D8B1B00EF0852 /* OOCacheManager.m */; };
|
||||
@ -1078,6 +1082,8 @@
|
||||
1A3A04610BC547DC00B5E2D9 /* OOTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OOTypes.h; path = ../Core/OOTypes.h; sourceTree = "<group>"; };
|
||||
1A3AFF1D0BC4462200B5E2D9 /* OOJSVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOJSVector.h; sourceTree = "<group>"; };
|
||||
1A3AFF1E0BC4462200B5E2D9 /* OOJSVector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOJSVector.m; sourceTree = "<group>"; };
|
||||
1A43234A0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOOpenGLExtensionManager.h; sourceTree = "<group>"; };
|
||||
1A43234B0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOOpenGLExtensionManager.m; sourceTree = "<group>"; };
|
||||
1A472916096B5454000E78D8 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
|
||||
1A47291F096B5468000E78D8 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
|
||||
1A472920096B5468000E78D8 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = "<absolute>"; };
|
||||
@ -1628,6 +1634,29 @@
|
||||
path = Sounds;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1A26D1090BCFA8D40073F257 /* PlayerEntity */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1A26D08E0BCF9CF70073F257 /* PlayerEntity.h */,
|
||||
1A26D08D0BCF9CF70073F257 /* PlayerEntity.m */,
|
||||
1A26D0980BCF9CF70073F257 /* PlayerEntityContracts.h */,
|
||||
1A26D09B0BCF9CF70073F257 /* PlayerEntityContracts.m */,
|
||||
1A26D0A40BCF9CF70073F257 /* PlayerEntityControls.h */,
|
||||
1A26D09C0BCF9CF70073F257 /* PlayerEntityControls.m */,
|
||||
1A26D0AA0BCF9CF80073F257 /* PlayerEntityLegacyScriptEngine.h */,
|
||||
1A26D0880BCF9CF70073F257 /* PlayerEntityLegacyScriptEngine.m */,
|
||||
1A26D08C0BCF9CF70073F257 /* PlayerEntityLoadSave.m */,
|
||||
1A26D0AB0BCF9CF80073F257 /* PlayerEntityLoadSave.h */,
|
||||
1A26D0910BCF9CF70073F257 /* PlayerEntityScriptMethods.h */,
|
||||
1A26D08B0BCF9CF70073F257 /* PlayerEntityScriptMethods.m */,
|
||||
1A26D0A60BCF9CF70073F257 /* PlayerEntitySound.h */,
|
||||
1A26D0A50BCF9CF70073F257 /* PlayerEntitySound.m */,
|
||||
1A26D09F0BCF9CF70073F257 /* PlayerEntityStickMapper.h */,
|
||||
1A26D09E0BCF9CF70073F257 /* PlayerEntityStickMapper.m */,
|
||||
);
|
||||
name = PlayerEntity;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1A34912C0BC25EBC00802DA7 /* Scripts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1782,10 +1811,10 @@
|
||||
1A8A3BFB0B963F91007D20B8 /* Utilities */,
|
||||
1A8A3BF20B963F3C007D20B8 /* Mac-specific */,
|
||||
25161144099544390037C2E1 /* Universe.h */,
|
||||
25161116099544390037C2E1 /* OOSound.h */,
|
||||
25161143099544390037C2E1 /* Universe.m */,
|
||||
25161110099544390037C2E1 /* OOTrumble.h */,
|
||||
25161108099544390037C2E1 /* OOTrumble.m */,
|
||||
25161116099544390037C2E1 /* OOSound.h */,
|
||||
25161100099544380037C2E1 /* OpenGLSprite.h */,
|
||||
251610FF099544380037C2E1 /* OpenGLSprite.m */,
|
||||
1A71E5230BCD7C4E00CD5C13 /* Player refactoring */,
|
||||
@ -1844,6 +1873,8 @@
|
||||
1A3491AB0BC282DE00802DA7 /* ReleaseLockProxy.m */,
|
||||
1A2A8E010BC67CCC001E00FB /* OOWeakReference.h */,
|
||||
1A2A8E020BC67CCC001E00FB /* OOWeakReference.m */,
|
||||
1A43234A0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h */,
|
||||
1A43234B0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m */,
|
||||
);
|
||||
name = Utilities;
|
||||
sourceTree = "<group>";
|
||||
@ -1851,42 +1882,27 @@
|
||||
1A8A3C0C0B963FF8007D20B8 /* Entities */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1A26D0880BCF9CF70073F257 /* PlayerEntityLegacyScriptEngine.m */,
|
||||
1A26D0890BCF9CF70073F257 /* ShipEntityAI.m */,
|
||||
1A26D08A0BCF9CF70073F257 /* ShipEntityAI.h */,
|
||||
1A26D08B0BCF9CF70073F257 /* PlayerEntityScriptMethods.m */,
|
||||
1A26D08C0BCF9CF70073F257 /* PlayerEntityLoadSave.m */,
|
||||
1A26D08D0BCF9CF70073F257 /* PlayerEntity.m */,
|
||||
1A26D08E0BCF9CF70073F257 /* PlayerEntity.h */,
|
||||
1A26D08F0BCF9CF70073F257 /* ShipEntity.m */,
|
||||
1A26D0900BCF9CF70073F257 /* ShipEntity.h */,
|
||||
1A26D0910BCF9CF70073F257 /* PlayerEntityScriptMethods.h */,
|
||||
1A26D0920BCF9CF70073F257 /* SkyEntity.m */,
|
||||
1A26D0930BCF9CF70073F257 /* SkyEntity.h */,
|
||||
1A26D0940BCF9CF70073F257 /* RingEntity.m */,
|
||||
1A26D0950BCF9CF70073F257 /* RingEntity.h */,
|
||||
1A26D0960BCF9CF70073F257 /* ParticleEntity.m */,
|
||||
1A26D0970BCF9CF70073F257 /* ParticleEntity.h */,
|
||||
1A26D0980BCF9CF70073F257 /* PlayerEntityContracts.h */,
|
||||
1A26D0990BCF9CF70073F257 /* PlanetEntity.m */,
|
||||
1A26D09A0BCF9CF70073F257 /* PlanetEntity.h */,
|
||||
1A26D09B0BCF9CF70073F257 /* PlayerEntityContracts.m */,
|
||||
1A26D09C0BCF9CF70073F257 /* PlayerEntityControls.m */,
|
||||
1A26D09D0BCF9CF70073F257 /* Entity.h */,
|
||||
1A26D09E0BCF9CF70073F257 /* PlayerEntityStickMapper.m */,
|
||||
1A26D09F0BCF9CF70073F257 /* PlayerEntityStickMapper.h */,
|
||||
1A26D0A00BCF9CF70073F257 /* WormholeEntity.m */,
|
||||
1A26D0A10BCF9CF70073F257 /* WormholeEntity.h */,
|
||||
1A26D0A20BCF9CF70073F257 /* StationEntity.m */,
|
||||
1A26D0A30BCF9CF70073F257 /* StationEntity.h */,
|
||||
1A26D0A40BCF9CF70073F257 /* PlayerEntityControls.h */,
|
||||
1A26D0A50BCF9CF70073F257 /* PlayerEntitySound.m */,
|
||||
1A26D0A60BCF9CF70073F257 /* PlayerEntitySound.h */,
|
||||
1A26D0A70BCF9CF70073F257 /* DustEntity.h */,
|
||||
1A26D0A80BCF9CF70073F257 /* Entity.m */,
|
||||
1A26D0900BCF9CF70073F257 /* ShipEntity.h */,
|
||||
1A26D08F0BCF9CF70073F257 /* ShipEntity.m */,
|
||||
1A26D08A0BCF9CF70073F257 /* ShipEntityAI.h */,
|
||||
1A26D0890BCF9CF70073F257 /* ShipEntityAI.m */,
|
||||
1A26D0A30BCF9CF70073F257 /* StationEntity.h */,
|
||||
1A26D0A20BCF9CF70073F257 /* StationEntity.m */,
|
||||
1A26D1090BCFA8D40073F257 /* PlayerEntity */,
|
||||
1A26D0930BCF9CF70073F257 /* SkyEntity.h */,
|
||||
1A26D0920BCF9CF70073F257 /* SkyEntity.m */,
|
||||
1A26D0950BCF9CF70073F257 /* RingEntity.h */,
|
||||
1A26D0940BCF9CF70073F257 /* RingEntity.m */,
|
||||
1A26D0970BCF9CF70073F257 /* ParticleEntity.h */,
|
||||
1A26D0960BCF9CF70073F257 /* ParticleEntity.m */,
|
||||
1A26D09A0BCF9CF70073F257 /* PlanetEntity.h */,
|
||||
1A26D0990BCF9CF70073F257 /* PlanetEntity.m */,
|
||||
1A26D0A10BCF9CF70073F257 /* WormholeEntity.h */,
|
||||
1A26D0A00BCF9CF70073F257 /* WormholeEntity.m */,
|
||||
1A26D0A70BCF9CF70073F257 /* DustEntity.h */,
|
||||
1A26D0A90BCF9CF80073F257 /* DustEntity.m */,
|
||||
1A26D0AA0BCF9CF80073F257 /* PlayerEntityLegacyScriptEngine.h */,
|
||||
1A26D0AB0BCF9CF80073F257 /* PlayerEntityLoadSave.h */,
|
||||
);
|
||||
path = Entities;
|
||||
sourceTree = "<group>";
|
||||
@ -2250,6 +2266,7 @@
|
||||
1A26D0E90BCF9D3B0073F257 /* OOTextureLoader.h in Headers */,
|
||||
1A26D0EA0BCF9D3B0073F257 /* OOPNGTextureLoader.h in Headers */,
|
||||
1A26D0F50BCF9D8D0073F257 /* pngusr.h in Headers */,
|
||||
1A43234E0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -2260,6 +2277,7 @@
|
||||
1A71E7170BCE34CF00CD5C13 /* pngconf.h in Headers */,
|
||||
1A71E71B0BCE34CF00CD5C13 /* png.h in Headers */,
|
||||
1A26D0F60BCF9D8D0073F257 /* pngusr.h in Headers */,
|
||||
1A43234C0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -2473,6 +2491,7 @@
|
||||
1A26D0E60BCF9D3B0073F257 /* OOTexture.m in Sources */,
|
||||
1A26D0E80BCF9D3B0073F257 /* OOPNGTextureLoader.m in Sources */,
|
||||
1A26D0EB0BCF9D3B0073F257 /* OOTextureLoader.m in Sources */,
|
||||
1A43234F0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -2498,6 +2517,7 @@
|
||||
1A71E7280BCE34CF00CD5C13 /* pngrio.c in Sources */,
|
||||
1A71E7290BCE34CF00CD5C13 /* pngvcrd.c in Sources */,
|
||||
1A71E72A0BCE34CF00CD5C13 /* pngpread.c in Sources */,
|
||||
1A43234D0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -155,6 +155,9 @@ rendering.opengl.stateDump = $troubleShootingDump; // Dump of OpenGL state (d
|
||||
rendering.opengl.shader.uniform = $shaderDebugOn;
|
||||
|
||||
|
||||
resourceManager.foundFile = off; // Tells you where all assets (models, textures, sounds) are found. Very verbose!
|
||||
|
||||
|
||||
save.failed = yes;
|
||||
save.success = no;
|
||||
|
||||
|
@ -182,6 +182,8 @@
|
||||
<string>$troubleShootingDump</string>
|
||||
<key>rendering.opengl.version</key>
|
||||
<string>$troubleShootingDump</string>
|
||||
<key>resourceManager.foundFile</key>
|
||||
<string>off</string>
|
||||
<key>save.failed</key>
|
||||
<string>yes</string>
|
||||
<key>save.success</key>
|
||||
|
@ -238,8 +238,9 @@ static size_t sMaxBufferedSoundSize = 1 << 20; // 1 MB
|
||||
|
||||
- (void)decrementPlayingCount
|
||||
{
|
||||
assert(0 != _playingCount);
|
||||
--_playingCount;
|
||||
//assert(0 != _playingCount);
|
||||
if (EXPECT(_playingCount != 0)) --_playingCount;
|
||||
else OOLog(@"sound.playUnderflow", @"Playing count for %@ dropped below 0!", self);
|
||||
}
|
||||
|
||||
|
||||
|
@ -143,7 +143,8 @@ extern int debug;
|
||||
#if GL_APPLE_vertex_array_object
|
||||
usingVAR: 1,
|
||||
#endif
|
||||
throw_sparks: 1;
|
||||
throw_sparks: 1,
|
||||
materialsReady: 1;
|
||||
|
||||
OOScanClass scanClass;
|
||||
OOEntityStatus status;
|
||||
|
@ -867,7 +867,7 @@ BOOL global_testForVAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
[self initialiseTextures];
|
||||
if (!materialsReady) [self initialiseTextures];
|
||||
[self generateDisplayList];
|
||||
}
|
||||
}
|
||||
@ -951,7 +951,9 @@ BOOL global_testForVAR;
|
||||
// Force the entity to reload the textures for each face by clearing the face's texture name.
|
||||
for (fi = 0; fi < n_faces; fi++)
|
||||
faces[fi].texName = 0;
|
||||
|
||||
|
||||
materialsReady = NO;
|
||||
|
||||
// Force the display list to be regenerated next time a frame is drawn.
|
||||
[self regenerateDisplayList];
|
||||
#endif
|
||||
@ -980,6 +982,7 @@ BOOL global_testForVAR;
|
||||
texture_name[ti] = [TextureStore getTextureNameFor: [NSString stringWithUTF8String: (char*)texture_file[ti]]];
|
||||
}
|
||||
}
|
||||
materialsReady = YES;
|
||||
}
|
||||
|
||||
- (void) regenerateDisplayList
|
||||
|
@ -29,6 +29,7 @@ MA 02110-1301, USA.
|
||||
#import "Universe.h"
|
||||
#import "TextureStore.h"
|
||||
#import "OOShaderMaterial.h"
|
||||
#import "OOOpenGLExtensionManager.h"
|
||||
|
||||
#import "ResourceManager.h"
|
||||
#import "OOStringParsing.h"
|
||||
@ -58,28 +59,6 @@ MA 02110-1301, USA.
|
||||
extern NSString * const kOOLogNoteAddShips;
|
||||
extern NSString * const kOOLogSyntaxAddShips;
|
||||
static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.changed";
|
||||
static NSString * const kOOLogOpenGLVersion = @"rendering.opengl.version";
|
||||
static NSString * const kOOLogOpenGLShaderSupport = @"rendering.opengl.shader.support";
|
||||
|
||||
#ifdef GNUSTEP
|
||||
void loadOpenGLFunctions()
|
||||
{
|
||||
glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)wglGetProcAddress("glGetObjectParameterivARB");
|
||||
glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)wglGetProcAddress("glCreateShaderObjectARB");
|
||||
glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)wglGetProcAddress("glGetInfoLogARB");
|
||||
glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)wglGetProcAddress("glCreateProgramObjectARB");
|
||||
glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)wglGetProcAddress("glAttachObjectARB");
|
||||
glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)wglGetProcAddress("glDeleteObjectARB");
|
||||
glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)wglGetProcAddress("glLinkProgramARB");
|
||||
glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)wglGetProcAddress("glCompileShaderARB");
|
||||
glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)wglGetProcAddress("glShaderSourceARB");
|
||||
glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)wglGetProcAddress("glUseProgramObjectARB");
|
||||
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");
|
||||
glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)wglGetProcAddress("glGetUniformLocationARB");
|
||||
glUniform1iARB = (PFNGLUNIFORM1IARBPROC)wglGetProcAddress("glUniform1iARB");
|
||||
glUniform1fARB = (PFNGLUNIFORM1FARBPROC)wglGetProcAddress("glUniform1fARB");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if OLD_SHADERS
|
||||
@ -423,6 +402,8 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
|
||||
[self setCrew:[NSArray arrayWithObject:pilot]];
|
||||
}
|
||||
|
||||
[self initialiseTextures];
|
||||
|
||||
// unpiloted (like missiles asteroids etc.)
|
||||
if ([shipdict fuzzyBooleanForKey:@"unpiloted" defaultValue:0.0f]) [self setCrew:nil];
|
||||
}
|
||||
@ -2450,101 +2431,6 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
|
||||
return viewpoint;
|
||||
}
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
BOOL shaders_supported = YES;
|
||||
BOOL testForShaderSupport = YES;
|
||||
#else
|
||||
BOOL shaders_supported = NO;
|
||||
BOOL testForShaderSupport = NO;
|
||||
#endif
|
||||
|
||||
void testForShaders()
|
||||
{
|
||||
#ifndef NO_SHADERS
|
||||
testForShaderSupport = NO;
|
||||
NSString* version_info = [NSString stringWithCString: (const char *)glGetString(GL_VERSION)];
|
||||
NSScanner* vscan = [NSScanner scannerWithString:version_info];
|
||||
int major = 0;
|
||||
int minor = 0;
|
||||
NSString* temp;
|
||||
if ([vscan scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@". "] intoString:&temp])
|
||||
major = [temp intValue];
|
||||
[vscan scanCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@". "] intoString:(NSString**)nil];
|
||||
if ([vscan scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@". "] intoString:&temp])
|
||||
minor = [temp intValue];
|
||||
|
||||
OOLog(kOOLogOpenGLVersion, @"OpenGL renderer version: %d.%d ('%@')", major, minor, version_info);
|
||||
|
||||
if ((major < 2)&&(minor < 5))
|
||||
{
|
||||
shaders_supported = NO;
|
||||
NSLog(@"INFORMATION: Oolite does not use shaders for OpenGL drivers before OpenGL 1.5");
|
||||
return;
|
||||
}
|
||||
|
||||
// check for the necessary extensions
|
||||
NSString* extension_info = [NSString stringWithCString: (const char *)glGetString(GL_EXTENSIONS)];
|
||||
|
||||
OOLog(kOOLogOpenGLExtensions, @"OPENGL EXTENSIONS:\n%@", extension_info);
|
||||
|
||||
shaders_supported &= ([extension_info rangeOfString:@"GL_ARB_multitexture"].location != NSNotFound);
|
||||
if (!shaders_supported)
|
||||
{
|
||||
OOLog(kOOLogOpenGLShaderSupport, @"INFORMATION: shaders require the GL_ARB_multitexture OpenGL extension, which is not present.");
|
||||
return;
|
||||
}
|
||||
|
||||
shaders_supported &= ([extension_info rangeOfString:@"GL_ARB_shader_objects"].location != NSNotFound);
|
||||
if (!shaders_supported)
|
||||
{
|
||||
OOLog(kOOLogOpenGLShaderSupport, @"INFORMATION: shaders require the GL_ARB_multitexture OpenGL extension, which is not present.");
|
||||
return;
|
||||
}
|
||||
|
||||
shaders_supported &= ([extension_info rangeOfString:@"GL_ARB_shading_language_100"].location != NSNotFound);
|
||||
if (!shaders_supported)
|
||||
{
|
||||
OOLog(kOOLogOpenGLShaderSupport, @"INFORMATION: shaders require the GL_ARB_shading_language_100 OpenGL extension, which is not present.");
|
||||
return;
|
||||
}
|
||||
|
||||
shaders_supported &= ([extension_info rangeOfString:@"GL_ARB_fragment_program"].location != NSNotFound);
|
||||
if (!shaders_supported)
|
||||
{
|
||||
OOLog(kOOLogOpenGLShaderSupport, @"INFORMATION: shaders require the GL_ARB_fragment_program OpenGL extension, which is not present.");
|
||||
return;
|
||||
}
|
||||
|
||||
shaders_supported &= ([extension_info rangeOfString:@"GL_ARB_fragment_shader"].location != NSNotFound);
|
||||
if (!shaders_supported)
|
||||
{
|
||||
OOLog(kOOLogOpenGLShaderSupport, @"INFORMATION: shaders require the GL_ARB_fragment_shader OpenGL extension, which is not present.");
|
||||
return;
|
||||
}
|
||||
|
||||
shaders_supported &= ([extension_info rangeOfString:@"GL_ARB_vertex_program"].location != NSNotFound);
|
||||
if (!shaders_supported)
|
||||
{
|
||||
OOLog(kOOLogOpenGLShaderSupport, @"INFORMATION: shaders require the GL_ARB_vertex_program OpenGL extension, which is not present.");
|
||||
return;
|
||||
}
|
||||
|
||||
shaders_supported &= ([extension_info rangeOfString:@"GL_ARB_vertex_shader"].location != NSNotFound);
|
||||
if (!shaders_supported)
|
||||
{
|
||||
OOLog(kOOLogOpenGLShaderSupport, @"INFORMATION: shaders require the GL_ARB_vertex_shader OpenGL extension, which is not present.");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef GNUSTEP
|
||||
// I am assuming none of the extensions will be used before this call because they have only just been checked for.
|
||||
// Note this this won't be called unless everything required is available because all the checks about return immediately
|
||||
// if a required extension is not found.
|
||||
loadOpenGLFunctions();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
- (void) initialiseTextures
|
||||
{
|
||||
@ -2560,8 +2446,8 @@ void testForShaders()
|
||||
|
||||
[super initialiseTextures];
|
||||
|
||||
if (testForShaderSupport) testForShaders();
|
||||
if (!shaders_supported) return;
|
||||
// TODO: this won't do when we have non-shader OOMaterials.
|
||||
if (![[OOOpenGLExtensionManager sharedManager] shadersSupported]) return;
|
||||
|
||||
shaderDefs = [shipinfoDictionary objectForKey:@"shaders"];
|
||||
if (shaderDefs)
|
||||
@ -2608,7 +2494,8 @@ void testForShaders()
|
||||
}
|
||||
|
||||
OOLogOutdentIf(@"shader.vessel.init");
|
||||
}
|
||||
}
|
||||
materialsReady = YES;
|
||||
}
|
||||
|
||||
|
||||
@ -2619,6 +2506,18 @@ void testForShaders()
|
||||
}
|
||||
|
||||
|
||||
- (void)exerciseMaterials
|
||||
{
|
||||
NSEnumerator *materialEnum = nil;
|
||||
OOMaterial *material = nil;
|
||||
|
||||
for (materialEnum = [materials objectEnumerator]; (material = [materialEnum nextObject]); )
|
||||
{
|
||||
[material ensureFinishedLoading];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void) drawEntity:(BOOL) immediate :(BOOL) translucent
|
||||
{
|
||||
NSString *textureKey = nil;
|
||||
@ -2717,10 +2616,17 @@ void testForShaders()
|
||||
else
|
||||
{
|
||||
// Set up display list.
|
||||
[self initialiseTextures];
|
||||
if (!materialsReady) [self initialiseTextures];
|
||||
#if GL_APPLE_vertex_array_object
|
||||
if (usingVAR) glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
|
||||
#endif
|
||||
/* Apply all materials to ensure textures are loaded.
|
||||
This is needed because you can't create textures in a
|
||||
display list.
|
||||
*/
|
||||
[self exerciseMaterials];
|
||||
|
||||
// Do the display list.
|
||||
[self generateDisplayList];
|
||||
}
|
||||
}
|
||||
|
@ -39,9 +39,16 @@ MA 02110-1301, USA.
|
||||
// Make this the current material.
|
||||
- (void)apply;
|
||||
|
||||
// Make no material the current material, tearing down anything set up by the current material.
|
||||
/* Make no material the current material, tearing down anything set up by the
|
||||
current material.
|
||||
*/
|
||||
+ (void)applyNone;
|
||||
|
||||
/* Ensure material is ready to be used in a display list. This is not
|
||||
required before using a material directly.
|
||||
*/
|
||||
- (void)ensureFinishedLoading;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
@ -67,6 +67,12 @@ static OOMaterial *sActiveMaterial;
|
||||
}
|
||||
|
||||
|
||||
- (void)ensureFinishedLoading
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (void)unapply
|
||||
{
|
||||
// Do nothing.
|
||||
|
@ -37,6 +37,7 @@ static void PNGRead(png_structp png, png_bytep bytes, png_size_t size);
|
||||
|
||||
@interface OOPNGTextureLoader (OOPrivate)
|
||||
|
||||
- (void)doLoadTexture;
|
||||
- (void)readBytes:(png_bytep)bytes count:(png_size_t)count;
|
||||
|
||||
@end
|
||||
@ -46,18 +47,43 @@ static void PNGRead(png_structp png, png_bytep bytes, png_size_t size);
|
||||
|
||||
- (void)loadTexture
|
||||
{
|
||||
png_bytepp rows;
|
||||
// Get data from file
|
||||
fileData = [[NSData alloc] initWithContentsOfMappedFile:path];
|
||||
if (fileData == nil) return;
|
||||
length = [fileData length];
|
||||
|
||||
[self doLoadTexture];
|
||||
|
||||
[fileData release];
|
||||
fileData = nil;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[fileData release];
|
||||
if (png != NULL)
|
||||
{
|
||||
png_destroy_read_struct(&png, &pngInfo, &pngEndInfo);
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOPNGTextureLoader (OOPrivate)
|
||||
|
||||
- (void)doLoadTexture
|
||||
{
|
||||
png_bytepp rows = NULL;
|
||||
png_uint_32 pngWidth,
|
||||
pngHeight;
|
||||
int depth,
|
||||
colorType;
|
||||
uint32_t i;
|
||||
|
||||
// Get data from file
|
||||
fileData = [[NSData alloc] initWithContentsOfMappedFile:path];
|
||||
if (fileData == nil) return;
|
||||
length = [fileData length];
|
||||
|
||||
// Set up PNG decoding
|
||||
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, PNGError, PNGWarning);
|
||||
if (png == NULL)
|
||||
@ -93,74 +119,61 @@ static void PNGRead(png_structp png, png_bytep bytes, png_size_t size);
|
||||
|
||||
png_set_read_fn(png, self, PNGRead);
|
||||
|
||||
png_read_png(png, pngInfo, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_PACKING | PNG_TRANSFORM_SHIFT | PNG_TRANSFORM_SWAP_ALPHA, NULL);
|
||||
|
||||
// We're done with the file now.
|
||||
[fileData release];
|
||||
fileData = nil;
|
||||
|
||||
// Get format info and check that it meets our expectations.
|
||||
png_read_info(png, pngInfo);
|
||||
// Read header, get format info and check that it meets our expectations.
|
||||
if (EXPECT_NOT(!png_get_IHDR(png, pngInfo, &pngWidth, &pngHeight, &depth, &colorType, NULL, NULL, NULL)))
|
||||
{
|
||||
OOLog(@"texture.load.png.failed", @"Failed to get metadata from PNG %@", path);
|
||||
return;
|
||||
}
|
||||
OOLog(@"texture.load.png.info", @"Loaded PNG %@\n\twidth: %u\n\theight: %u\n\tdepth: %i\n\tcolorType: %i", path, width, height, depth, colorType);
|
||||
|
||||
// The png_read_png transformation options should have assured we got 8-bit ARGB.
|
||||
if (EXPECT_NOT(colorType != PNG_COLOR_TYPE_RGB_ALPHA || depth != 8))
|
||||
png_set_strip_16(png); // 16 bits per channel -> 8 bpc
|
||||
png_set_packing(png); // <8 bpc -> 8 bpc (is this needed with png_set_expand()?)
|
||||
if (depth < 8 || colorType == PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
OOLog(@"texture.load.png.failed", @"Unexpected PNG format (colour type %i, depth %i) for %@", colorType, depth, path);
|
||||
return;
|
||||
png_set_expand(png); // Paletted -> RGB, greyscale -> 8 bpc
|
||||
}
|
||||
// png_set_bgr for little-endian? If so, do we want png_set_swap_alpha in that case?
|
||||
png_set_bgr(png);
|
||||
png_set_swap_alpha(png); // RGBA->ARGB
|
||||
|
||||
// if ((colorType & PNG_COLOR_MASK_ALPHA) == 0)
|
||||
{
|
||||
png_set_filler(png, 0xFF, PNG_FILLER_BEFORE); // PNG_FILLER_AFTER for little-endian?
|
||||
}
|
||||
|
||||
// Data is good, allocate buffer and copy. TODO: avoid copying stage by using low-level PNG reading.
|
||||
png_read_update_info(png, pngInfo);
|
||||
|
||||
// Metadata is acceptable; load data.
|
||||
width = pngWidth;
|
||||
height = pngHeight;
|
||||
rowBytes = width * 4;
|
||||
rowBytes = png_get_rowbytes(png, pngInfo); // width * 4;
|
||||
|
||||
// png_read_png
|
||||
rows = malloc(sizeof *rows * height);
|
||||
data = malloc(rowBytes * height);
|
||||
if (EXPECT_NOT(data == NULL))
|
||||
if (EXPECT_NOT(rows == NULL || data == NULL))
|
||||
{
|
||||
if (rows != NULL) free(rows);
|
||||
if (data != NULL)
|
||||
{
|
||||
free(data);
|
||||
data = NULL;
|
||||
}
|
||||
OOLog(kOOLogAllocationFailure, @"Failed to allocate space (%u bytes) for texture %@", rowBytes * height, path);
|
||||
return;
|
||||
}
|
||||
|
||||
rows = png_get_rows(png, pngInfo);
|
||||
if (EXPECT_NOT(data == NULL))
|
||||
{
|
||||
OOLog(@"texture.load.png.failed", @"Failed to get image rows for PNG %@", path);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i != height; ++i) rows[i] = ((png_bytep)data) + i * rowBytes;
|
||||
png_set_rows(png, pngInfo, rows);
|
||||
png_read_image(png, rows);
|
||||
png_read_end(png, pngEndInfo);
|
||||
|
||||
for (i = 0; i != height; ++i)
|
||||
{
|
||||
memcpy(((uint8_t *)data) + height * rowBytes, rows[i], rowBytes);
|
||||
}
|
||||
free(rows);
|
||||
|
||||
if (png != NULL)
|
||||
{
|
||||
png_destroy_read_struct(&png, &pngInfo, &pngEndInfo);
|
||||
}
|
||||
png_destroy_read_struct(&png, &pngInfo, &pngEndInfo);
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (png != NULL)
|
||||
{
|
||||
png_destroy_read_struct(&png, &pngInfo, &pngEndInfo);
|
||||
}
|
||||
[fileData release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOPNGTextureLoader (OOPrivate)
|
||||
|
||||
- (void)readBytes:(png_bytep)bytes count:(png_size_t)count
|
||||
{
|
||||
// Check that we're within the file's bounds
|
||||
@ -172,10 +185,10 @@ static void PNGRead(png_structp png, png_bytep bytes, png_size_t size);
|
||||
|
||||
assert(bytes != NULL);
|
||||
|
||||
OOLog(@"texture.load.png.read", @"Reading %u bytes starting at offset %u", count, offset);
|
||||
// OOLog(@"texture.load.png.read", @"Reading %u bytes starting at offset %u", count, offset);
|
||||
|
||||
// Copy bytes
|
||||
memcpy(bytes, [fileData bytes], count);
|
||||
memcpy(bytes, [fileData bytes] + offset, count);
|
||||
offset += count;
|
||||
}
|
||||
|
||||
|
@ -31,15 +31,16 @@ MA 02110-1301, USA.
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
|
||||
@class OOShaderProgram;
|
||||
@class OOShaderProgram, OOTexture;
|
||||
|
||||
|
||||
@interface OOShaderMaterial: OOMaterial
|
||||
{
|
||||
OOShaderProgram *shaderProgram;
|
||||
NSMutableDictionary *uniforms;
|
||||
GLuint *textures;
|
||||
GLuint texCount;
|
||||
|
||||
uint32_t texCount;
|
||||
OOTexture **textures;
|
||||
}
|
||||
|
||||
/* Set up an OOShaderMaterial.
|
||||
|
@ -29,7 +29,8 @@ MA 02110-1301, USA.
|
||||
#import "OOFunctionAttributes.h"
|
||||
#import "OOCollectionExtractors.h"
|
||||
#import "OOShaderProgram.h"
|
||||
#import "TextureStore.h"
|
||||
#import "OOTexture.h"
|
||||
#import "OOOpenGLExtensionManager.h"
|
||||
|
||||
|
||||
static NSString *MacrosToString(NSDictionary *macros);
|
||||
@ -132,11 +133,22 @@ static NSString *MacrosToString(NSDictionary *macros);
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
[self willDealloc];
|
||||
|
||||
[shaderProgram release];
|
||||
[uniforms release];
|
||||
|
||||
if (textures != NULL)
|
||||
{
|
||||
for (i = 0; i != texCount; ++i)
|
||||
{
|
||||
[textures[i] release];
|
||||
}
|
||||
free(textures);
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@ -249,12 +261,19 @@ static NSString *MacrosToString(NSDictionary *macros);
|
||||
[self setUniform:name floatValue:floatValue];
|
||||
}
|
||||
}
|
||||
else if ([type isEqualToString:@"int"])
|
||||
else if ([type isEqualToString:@"int"] || [type isEqualToString:@"texture"])
|
||||
{
|
||||
/* "texture" is allowed as a synonym for "int" because shader#d
|
||||
uniforms are mapped to texture units by specifying an integer
|
||||
index.
|
||||
uniforms = { diffuseMap = { type = texture; value = 0; }; };
|
||||
means "bind uniform diffuseMap to texture unit 0" (which will
|
||||
have the first texture in the textures array).
|
||||
*/
|
||||
if ([value respondsToSelector:@selector(intValue)])
|
||||
{
|
||||
gotValue = YES;
|
||||
[self setUniform:name intValue:[value intValue]];
|
||||
gotValue = YES;
|
||||
}
|
||||
else gotValue = NO;
|
||||
}
|
||||
@ -263,9 +282,9 @@ static NSString *MacrosToString(NSDictionary *macros);
|
||||
selector = NSSelectorFromString(value);
|
||||
if (selector)
|
||||
{
|
||||
gotValue = YES;
|
||||
clamped = [definition boolForKey:@"clamped" defaultValue:NO];
|
||||
[self bindUniform:name toObject:target property:selector clamped:clamped];
|
||||
gotValue = YES;
|
||||
}
|
||||
else gotValue = NO;
|
||||
}
|
||||
@ -282,14 +301,15 @@ static NSString *MacrosToString(NSDictionary *macros);
|
||||
{
|
||||
NSEnumerator *uniformEnum = nil;
|
||||
OOShaderUniform *uniform = nil;
|
||||
GLint i;
|
||||
uint32_t i;
|
||||
|
||||
[shaderProgram apply];
|
||||
|
||||
for (i = 0; i != texCount; ++i)
|
||||
{
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + i);
|
||||
glBindTexture(GL_TEXTURE_2D, textures[i]);
|
||||
/*glBindTexture(GL_TEXTURE_2D, textures[i]);*/
|
||||
[textures[i] apply];
|
||||
}
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
|
||||
@ -309,6 +329,20 @@ static NSString *MacrosToString(NSDictionary *macros);
|
||||
}
|
||||
|
||||
|
||||
- (void)ensureFinishedLoading
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (textures != NULL)
|
||||
{
|
||||
for (i = 0; i != texCount; ++i)
|
||||
{
|
||||
[textures[i] ensureFinishedLoading];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)unapplyWithNext:(OOMaterial *)next
|
||||
{
|
||||
if (![next isKindOfClass:[OOShaderMaterial class]]) // Avoid redundant state change
|
||||
@ -324,7 +358,7 @@ static NSString *MacrosToString(NSDictionary *macros);
|
||||
|
||||
- (void)addTexturesFromArray:(NSArray *)textureNames unitCount:(GLint)max
|
||||
{
|
||||
NSString *name = nil;
|
||||
id textureDef = nil;
|
||||
unsigned i = 0;
|
||||
|
||||
// Allocate space for texture object name array
|
||||
@ -343,12 +377,8 @@ static NSString *MacrosToString(NSDictionary *macros);
|
||||
{
|
||||
[self setUniform:[NSString stringWithFormat:@"tex%u", i] intValue:i];
|
||||
|
||||
name = [textureNames objectAtIndex:i];
|
||||
if ([name isKindOfClass:[NSString class]])
|
||||
{
|
||||
OOLog(@"shader.temp.loadTexture", @"Getting texture %@", name);
|
||||
textures[i] = [TextureStore getTextureNameFor:name];
|
||||
}
|
||||
textureDef = [textureNames objectAtIndex:i];
|
||||
textures[i] = [[OOTexture textureWithConfiguration:textureDef] retain];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ MA 02110-1301, USA.
|
||||
#import "OOFunctionAttributes.h"
|
||||
#import "OOStringParsing.h"
|
||||
#import "ResourceManager.h"
|
||||
#import "OOOpenGLExtensionManager.h"
|
||||
|
||||
|
||||
static NSMutableDictionary *sShaderCache = nil;
|
||||
|
@ -29,6 +29,7 @@ MA 02110-1301, USA.
|
||||
#import "OOFunctionAttributes.h"
|
||||
#import <string.h>
|
||||
#import "OOMaths.h"
|
||||
#import "OOOpenGLExtensionManager.h"
|
||||
|
||||
|
||||
typedef enum
|
||||
|
@ -33,19 +33,30 @@ MA 02110-1301, USA.
|
||||
|
||||
enum
|
||||
{
|
||||
kOOTextureFilterDefault = 0x0000UL,
|
||||
kOOTextureFilterLinear = 0x0001UL,
|
||||
kOOTextureFilterNoMipMap = 0x0002UL,
|
||||
kOOTextureFilterForceMipMap = 0x0003UL,
|
||||
kOOTextureMinFilterDefault = 0x0000UL,
|
||||
kOOTextureMinFilterNearest = 0x0001UL,
|
||||
kOOTextureMinFilterLinear = 0x0002UL,
|
||||
kOOTextureMinFilterMipMap = 0x0003UL,
|
||||
|
||||
kOOTextureNoShrink = 0x0010UL,
|
||||
kOOTextureIsNormalMap = 0x0020UL,
|
||||
kOOTextureMagFilterNearest = 0x0010UL,
|
||||
kOOTextureMagFilterLinear = 0x0020UL,
|
||||
|
||||
kOOTextureFilterMask = 0x000FUL,
|
||||
kOOTextureFlagsMask = ~kOOTextureFilterMask
|
||||
kOOTextureNoShrink = 0x0100UL,
|
||||
kOOTextureRepeatS = 0x0200UL,
|
||||
kOOTextureRepeatT = 0x0200UL,
|
||||
|
||||
kOOTextureMinFilterMask = 0x000FUL,
|
||||
kOOTextureMagFilterMask = 0x00F0UL,
|
||||
kOOTextureFlagsMask = ~(kOOTextureMinFilterMask | kOOTextureMagFilterMask),
|
||||
|
||||
kOOTextureDefaultOptions = kOOTextureMinFilterDefault | kOOTextureMagFilterLinear,
|
||||
kOOTextureDefinedFlags = 0x0733UL
|
||||
};
|
||||
|
||||
|
||||
#define kOOTextureDefaultAnisotropy 0.5
|
||||
|
||||
|
||||
@interface OOTexture: NSObject
|
||||
{
|
||||
BOOL loaded;
|
||||
@ -56,35 +67,52 @@ enum
|
||||
{
|
||||
OOTextureLoader *loader;
|
||||
uint32_t options;
|
||||
#if GL_EXT_texture_filter_anisotropic
|
||||
float anisotropy;
|
||||
#endif
|
||||
} loading;
|
||||
struct
|
||||
{
|
||||
void *bytes;
|
||||
GLuint textureName;
|
||||
uint32_t width,
|
||||
height;
|
||||
} loaded;
|
||||
} data;
|
||||
uint32_t width,
|
||||
height;
|
||||
}
|
||||
|
||||
/* Load a texture, looking in Textures directories.
|
||||
|
||||
NOTE: anisotropy is normalized to the range [0, 1]. 1 means as high an
|
||||
anisotropy setting as the hardware supports.
|
||||
|
||||
This method may change; +textureWithConfiguration is generally more
|
||||
appropriate.
|
||||
*/
|
||||
+ (id)textureWithName:(NSString *)name options:(uint32_t)options;
|
||||
+ (id)textureWithName:(NSString *)name options:(uint32_t)options anisotropy:(float)anisotropy;
|
||||
|
||||
/* Load a texure, looking in Textures directories, using configuration
|
||||
dictionary.
|
||||
dictionary or name. (That is, configuration may be either an NSDictionary
|
||||
or an NSString.)
|
||||
|
||||
Supported keys:
|
||||
name (string, required)
|
||||
mipMap (string, optional, one of: "never", "default", "force")
|
||||
noFilter (boolean, optional)
|
||||
noShrink (boolean, optional)
|
||||
isNormalMap (boolean, optional)
|
||||
minFilter (string, one of "default", "nearest", "linear", "mipmap")
|
||||
maxFilter (string, one of "default", "nearest", "linear")
|
||||
noShrink (boolean)
|
||||
repeatS (boolean)
|
||||
repeatT (boolean)
|
||||
anisotropy (real)
|
||||
*/
|
||||
+ (id)textureWithConfiguration:(NSDictionary *)configuration;
|
||||
+ (id)textureWithConfiguration:(id)configuration;
|
||||
|
||||
/* Bind the texture to the current texture unit.
|
||||
*/
|
||||
- (void)apply;
|
||||
|
||||
/* Ensure texture is loaded. This is required because setting up textures
|
||||
inside display lists isn't allowed.
|
||||
*/
|
||||
- (void)ensureFinishedLoading;
|
||||
|
||||
@end
|
||||
|
@ -27,6 +27,14 @@ MA 02110-1301, USA.
|
||||
#import "OOCollectionExtractors.h"
|
||||
#import "Universe.h"
|
||||
#import "ResourceManager.h"
|
||||
#import "OOOpenGLExtensionManager.h"
|
||||
|
||||
|
||||
#if __BIG_ENDIAN__
|
||||
#define RGBA_IMAGE_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
|
||||
#else
|
||||
#define RGBA_IMAGE_TYPE GL_UNSIGNED_INT_8_8_8_8
|
||||
#endif
|
||||
|
||||
|
||||
static NSMutableDictionary *sInUseTextures = nil;
|
||||
@ -45,33 +53,84 @@ static NSMutableDictionary *sInUseTextures = nil;
|
||||
-- Ahruman
|
||||
*/
|
||||
|
||||
|
||||
static BOOL sCheckedExtensions = NO;
|
||||
|
||||
// Anisotropic filtering
|
||||
#if GL_EXT_texture_filter_anisotropic
|
||||
static BOOL sAnisotropyAvailable;
|
||||
static float sAnisotropyScale; // Scale of anisotropy values
|
||||
#else
|
||||
#warning GL_EXT_texture_filter_anisotropic unavialble -- are you using an up-to-date glext.h?
|
||||
#endif
|
||||
|
||||
|
||||
// CLAMP_TO_EDGE (OK, requiring OpenGL 1.2 wouln't be _that_ big a deal...)
|
||||
#if !defined(GL_CLAMP_TO_EDGE) && GL_SGIS_texture_edge_clamp
|
||||
#define GL_CLAMP_TO_EDGE GL_CLAMP_TO_EDGE_SGIS
|
||||
#endif
|
||||
|
||||
#ifdef GL_CLAMP_TO_EDGE
|
||||
static BOOL sClampToEdgeAvailable;
|
||||
#else
|
||||
#warning GL_CLAMP_TO_EDGE (OpenGL 1.2) and GL_SGIS_texture_edge_clamp are unavialble -- are you using an up-to-date gl.h?
|
||||
#define sClampToEdgeAvailable NO
|
||||
#define GL_CLAMP_TO_EDGE GL_CLAMP
|
||||
#endif
|
||||
|
||||
|
||||
// Client storage: reduce copying by requiring the app to keep data around
|
||||
#if GL_APPLE_client_storage
|
||||
#define OO_GL_CLIENT_STORAGE 1
|
||||
static inline void EnableClientStorage(void) { glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); }
|
||||
// #elif in any equivalents on other platforms here
|
||||
#else
|
||||
#define OO_GL_CLIENT_STORAGE 0
|
||||
#define sClientStorageAvialable NO
|
||||
#define EnableClientStorage() do {} while (0)
|
||||
#endif
|
||||
|
||||
#if OO_GL_CLIENT_STORAGE
|
||||
static BOOL sClientStorageAvialable;
|
||||
#endif
|
||||
|
||||
|
||||
@interface OOTexture (OOPrivate)
|
||||
|
||||
- (id)initWithPath:(NSString *)path key:(NSString *)key options:(uint32_t)options;
|
||||
- (id)initWithPath:(NSString *)path key:(NSString *)key options:(uint32_t)options anisotropy:(float)anisotropy;
|
||||
- (void)setUpTexture;
|
||||
- (void)uploadTextureDataWithMipMap:(BOOL)mipMap;
|
||||
|
||||
+ (void)checkExtensions;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOTexture
|
||||
|
||||
+ (id)textureWithName:(NSString *)name options:(uint32_t)options
|
||||
+ (id)textureWithName:(NSString *)name options:(uint32_t)options anisotropy:(float)anisotropy
|
||||
{
|
||||
NSString *key = nil;
|
||||
OOTexture *result = nil;
|
||||
NSString *path = nil;
|
||||
|
||||
// Work out whether we want mip-mapping.
|
||||
if ((options & kOOTextureFilterMask) == kOOTextureFilterDefault)
|
||||
options &= kOOTextureDefinedFlags;
|
||||
// Set default flags if needed
|
||||
if ((options & kOOTextureMinFilterMask) == kOOTextureMinFilterDefault)
|
||||
{
|
||||
if ([UNIVERSE reducedDetail])
|
||||
{
|
||||
options |= kOOTextureFilterNoMipMap;
|
||||
options |= kOOTextureMinFilterLinear;
|
||||
}
|
||||
else
|
||||
{
|
||||
options |= kOOTextureFilterForceMipMap;
|
||||
options |= kOOTextureMinFilterMipMap;
|
||||
}
|
||||
}
|
||||
if ((options & kOOTextureMagFilterMask) != kOOTextureMagFilterNearest)
|
||||
{
|
||||
options = (options & ~kOOTextureMagFilterMask) | kOOTextureMagFilterLinear;
|
||||
}
|
||||
|
||||
// Look for existing texture
|
||||
key = [NSString stringWithFormat:@"%@:0x%.4X", name, options];
|
||||
@ -85,8 +144,10 @@ static NSMutableDictionary *sInUseTextures = nil;
|
||||
return nil;
|
||||
}
|
||||
|
||||
if (!sCheckedExtensions) [self checkExtensions];
|
||||
|
||||
// No existing texture, load texture...
|
||||
result = [[[OOTexture alloc] initWithPath:path key:key options:options] autorelease];
|
||||
result = [[[OOTexture alloc] initWithPath:path key:key options:options anisotropy:anisotropy] autorelease];
|
||||
|
||||
if (result != nil)
|
||||
{
|
||||
@ -100,63 +161,50 @@ static NSMutableDictionary *sInUseTextures = nil;
|
||||
}
|
||||
|
||||
|
||||
+ (id)textureWithConfiguration:(NSDictionary *)configuration
|
||||
+ (id)textureWithConfiguration:(id)configuration
|
||||
{
|
||||
NSString *name = nil;
|
||||
NSString *useMipMapString = nil;
|
||||
NSString *filterString = nil;
|
||||
uint32_t options = 0;
|
||||
float anisotropy;
|
||||
|
||||
name = [configuration stringForKey:@"name" defaultValue:nil];
|
||||
if (name == nil)
|
||||
if ([configuration isKindOfClass:[NSString class]])
|
||||
{
|
||||
OOLog(@"texture.load", @"Invalid texture configuration dictionary (must specify name):\n%@", configuration);
|
||||
return nil;
|
||||
name = configuration;
|
||||
options = kOOTextureDefaultOptions;
|
||||
}
|
||||
|
||||
if ([configuration boolForKey:@"noFilter" defaultValue:NO])
|
||||
else if ([configuration isKindOfClass:[NSDictionary class]])
|
||||
{
|
||||
options |= kOOTextureFilterLinear;
|
||||
name = [configuration stringForKey:@"name" defaultValue:nil];
|
||||
if (name == nil)
|
||||
{
|
||||
OOLog(@"texture.load", @"Invalid texture configuration dictionary (must specify name):\n%@", configuration);
|
||||
return nil;
|
||||
}
|
||||
|
||||
filterString = [configuration stringForKey:@"minFilter" defaultValue:@"default"];
|
||||
if ([filterString isEqualToString:@"nearest"]) options |= kOOTextureMinFilterNearest;
|
||||
else if ([filterString isEqualToString:@"linear"]) options |= kOOTextureMinFilterLinear;
|
||||
else if ([filterString isEqualToString:@"mipMap"]) options |= kOOTextureMinFilterMipMap;
|
||||
else options |= kOOTextureMinFilterDefault; // Covers "default"
|
||||
|
||||
filterString = [configuration stringForKey:@"magFilter" defaultValue:@"default"];
|
||||
if ([filterString isEqualToString:@"nearest"]) options |= kOOTextureMagFilterNearest;
|
||||
else options |= kOOTextureMagFilterLinear; // Covers "default" and "linear"
|
||||
|
||||
if ([configuration boolForKey:@"noShrink" defaultValue:NO]) options |= kOOTextureNoShrink;
|
||||
if ([configuration boolForKey:@"repeatS" defaultValue:NO]) options |= kOOTextureRepeatS;
|
||||
if ([configuration boolForKey:@"repeatT" defaultValue:NO]) options |= kOOTextureRepeatT;
|
||||
anisotropy = [configuration floatForKey:@"anisotropy" defaultValue:kOOTextureDefaultAnisotropy];
|
||||
}
|
||||
else
|
||||
{
|
||||
useMipMapString = [configuration stringForKey:@"mipMap" defaultValue:nil];
|
||||
if (useMipMapString != nil)
|
||||
{
|
||||
if ([useMipMapString isEqualToString:@"never"]) options |= kOOTextureFilterNoMipMap;
|
||||
else if ([useMipMapString isEqualToString:@"force"]) options |= kOOTextureFilterForceMipMap;
|
||||
// Silently ignore other options; this covers "default"
|
||||
}
|
||||
}
|
||||
|
||||
if ([configuration boolForKey:@"noShrink" defaultValue:NO])
|
||||
{
|
||||
options |= kOOTextureNoShrink;
|
||||
}
|
||||
|
||||
if ([configuration boolForKey:@"isNormalMap" defaultValue:NO])
|
||||
{
|
||||
options |= kOOTextureIsNormalMap;
|
||||
}
|
||||
|
||||
return [self textureWithName:name options:options];
|
||||
}
|
||||
|
||||
|
||||
- (id)initWithPath:(NSString *)path key:(NSString *)inKey options:(uint32_t)options
|
||||
{
|
||||
self = [super init];
|
||||
if (EXPECT_NOT(self == nil)) return nil;
|
||||
|
||||
data.loading.loader = [OOTextureLoader loaderWithPath:path options:options];
|
||||
if (EXPECT_NOT(data.loading.loader == nil))
|
||||
{
|
||||
[self release];
|
||||
// Bad type
|
||||
OOLog(kOOLogParameterError, @"%s: expected string or dictionary, got %@.", __PRETTY_FUNCTION__, [configuration class]);
|
||||
return nil;
|
||||
}
|
||||
|
||||
key = [inKey copy];
|
||||
|
||||
return self;
|
||||
return [self textureWithName:name options:options anisotropy:anisotropy];
|
||||
}
|
||||
|
||||
|
||||
@ -166,8 +214,8 @@ static NSMutableDictionary *sInUseTextures = nil;
|
||||
|
||||
if (loaded)
|
||||
{
|
||||
if (data.loaded.bytes != NULL) free(data.loaded.bytes);
|
||||
if (data.loaded.textureName != 0) glDeleteTextures(1, &data.loaded.textureName);
|
||||
if (data.loaded.bytes != NULL) free(data.loaded.bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -186,7 +234,7 @@ static NSMutableDictionary *sInUseTextures = nil;
|
||||
{
|
||||
if (data.loaded.bytes != NULL)
|
||||
{
|
||||
stateDesc = [NSString stringWithFormat:@"%u x %u", width, height];
|
||||
stateDesc = [NSString stringWithFormat:@"%u x %u", data.loaded.width, data.loaded.height];
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -204,28 +252,162 @@ static NSMutableDictionary *sInUseTextures = nil;
|
||||
|
||||
- (void)apply
|
||||
{
|
||||
OOTextureLoader *loader = nil;
|
||||
uint32_t options;
|
||||
|
||||
if (EXPECT_NOT(!loaded))
|
||||
{
|
||||
loader = data.loading.loader;
|
||||
options = data.loading.options;
|
||||
|
||||
if ([loader getResult:&data.loaded.bytes width:&width height:&height])
|
||||
{
|
||||
// TODO: set up texture here
|
||||
}
|
||||
else
|
||||
{
|
||||
data.loaded.textureName = 0;
|
||||
}
|
||||
|
||||
[loader release];
|
||||
loaded = YES;
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, data.loaded.textureName);
|
||||
if (EXPECT_NOT(!loaded)) [self setUpTexture];
|
||||
else glBindTexture(GL_TEXTURE_2D, data.loaded.textureName);
|
||||
}
|
||||
|
||||
|
||||
- (void)ensureFinishedLoading
|
||||
{
|
||||
if (EXPECT_NOT(!loaded)) [self setUpTexture];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOTexture (OOPrivate)
|
||||
|
||||
- (id)initWithPath:(NSString *)path key:(NSString *)inKey options:(uint32_t)options anisotropy:(float)anisotropy
|
||||
{
|
||||
self = [super init];
|
||||
if (EXPECT_NOT(self == nil)) return nil;
|
||||
|
||||
data.loading.loader = [[OOTextureLoader loaderWithPath:path options:options] retain];
|
||||
if (EXPECT_NOT(data.loading.loader == nil))
|
||||
{
|
||||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
data.loading.options = options;
|
||||
#if GL_EXT_texture_filter_anisotropic
|
||||
data.loading.anisotropy = OOClamp_0_1_f(anisotropy) * sAnisotropyScale;
|
||||
#endif
|
||||
|
||||
key = [inKey copy];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)setUpTexture
|
||||
{
|
||||
OOTextureLoader *loader = nil;
|
||||
uint32_t options;
|
||||
GLint clampMode;
|
||||
GLint filter;
|
||||
float anisotropy;
|
||||
BOOL mipMap = NO;
|
||||
|
||||
loader = data.loading.loader;
|
||||
options = data.loading.options;
|
||||
anisotropy = data.loading.anisotropy;
|
||||
|
||||
loaded = YES;
|
||||
// data.loaded considered invalid beyond this point.
|
||||
|
||||
if ([loader getResult:&data.loaded.bytes width:&data.loaded.width height:&data.loaded.height])
|
||||
{
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // FIXME: this is probably not needed. Remove it once stuff works and see if anything changes. (Should probably be 4 if we need to keep it.)
|
||||
glGenTextures(1, &data.loaded.textureName);
|
||||
glBindTexture(GL_TEXTURE_2D, data.loaded.textureName);
|
||||
|
||||
// Select wrap mode
|
||||
clampMode = sClampToEdgeAvailable ? GL_CLAMP_TO_EDGE : GL_CLAMP;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (options & kOOTextureRepeatS) ? GL_REPEAT : clampMode);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (options & kOOTextureRepeatT) ? GL_REPEAT : clampMode);
|
||||
|
||||
// Select min filter
|
||||
filter = options & kOOTextureMinFilterMask;
|
||||
if (filter == kOOTextureMinFilterNearest) filter = GL_NEAREST;
|
||||
else if (filter == kOOTextureMinFilterMipMap)
|
||||
{
|
||||
mipMap = YES;
|
||||
filter = GL_LINEAR_MIPMAP_LINEAR;
|
||||
}
|
||||
else filter = GL_LINEAR;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
|
||||
#if GL_EXT_texture_filter_anisotropic
|
||||
if (sAnisotropyAvailable && mipMap && 1.0 < anisotropy)
|
||||
{
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 4.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Select mag filter
|
||||
filter = options & kOOTextureMagFilterMask;
|
||||
if (filter == kOOTextureMagFilterNearest) filter = GL_NEAREST;
|
||||
else filter = GL_LINEAR;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
|
||||
if (sClientStorageAvialable) EnableClientStorage();
|
||||
|
||||
[self uploadTextureDataWithMipMap:mipMap];
|
||||
|
||||
if (!sClientStorageAvialable)
|
||||
{
|
||||
free(data.loaded.bytes);
|
||||
data.loaded.bytes = NULL;
|
||||
}
|
||||
|
||||
OOLog(@"texture.setUp", @"Set up texture %u (%ux%u pixels, %@)", data.loaded.textureName, data.loaded.width, data.loaded.height, key);
|
||||
}
|
||||
else
|
||||
{
|
||||
data.loaded.textureName = 0;
|
||||
}
|
||||
|
||||
[loader release];
|
||||
}
|
||||
|
||||
|
||||
- (void)uploadTextureDataWithMipMap:(BOOL)mipMap
|
||||
{
|
||||
if (!mipMap)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, data.loaded.width, data.loaded.height, 0, GL_RGBA, RGBA_IMAGE_TYPE, data.loaded.bytes);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned w = data.loaded.width,
|
||||
h = data.loaded.height,
|
||||
level = 0;
|
||||
uint32_t *bytes = data.loaded.bytes;
|
||||
|
||||
while (1 < w && 1 < h)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, level++, GL_RGBA, w, h, 0, GL_RGBA, RGBA_IMAGE_TYPE, bytes);
|
||||
bytes += w * h;
|
||||
w >>= 1;
|
||||
h >>= 1;
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+ (void)checkExtensions
|
||||
{
|
||||
sCheckedExtensions = YES;
|
||||
|
||||
OOOpenGLExtensionManager *extMgr = [OOOpenGLExtensionManager sharedManager];
|
||||
|
||||
#if GL_EXT_texture_filter_anisotropic
|
||||
sAnisotropyAvailable = [extMgr haveExtension:@"GL_EXT_texture_filter_anisotropic"];
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &sAnisotropyScale);
|
||||
sAnisotropyScale *= OOClamp_0_1_f([[NSUserDefaults standardUserDefaults] floatForKey:@"texture-anisotropy-bias" defaultValue:1.0]);
|
||||
#endif
|
||||
|
||||
#ifdef GL_CLAMP_TO_EDGE
|
||||
// GL_CLAMP_TO_EDGE requires OpenGL 1.2 or later
|
||||
sClampToEdgeAvailable = (2 < [extMgr minorVersionNumber]) || [extMgr haveExtension:@"GL_SGIS_texture_edge_clamp"];
|
||||
#endif
|
||||
|
||||
#if GL_APPLE_client_storage
|
||||
sClientStorageAvialable = [extMgr haveExtension:@"GL_APPLE_client_storage"];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -97,7 +97,7 @@ enum
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &sGLMaxSize);
|
||||
if (sGLMaxSize < 64) sGLMaxSize = 64;
|
||||
|
||||
sUserMaxSize = [[NSUserDefaults standardUserDefaults] unsignedIntForKey:@"max-texture-size" defaultValue:UINT_MAX];
|
||||
sUserMaxSize = [[NSUserDefaults standardUserDefaults] unsignedIntForKey:@"max-texture-size" defaultValue:0x80000000];
|
||||
sUserMaxSize = OORoundUpToPowerOf2(sUserMaxSize);
|
||||
if (sUserMaxSize < 64) sUserMaxSize = 64;
|
||||
}
|
||||
@ -138,8 +138,7 @@ enum
|
||||
|
||||
[completionLock lock]; // Will be unlocked when loading is done.
|
||||
|
||||
generateMipMaps = (options & kOOTextureFilterMask) == kOOTextureFilterDefault;
|
||||
scaleAsNormalMap = (options & kOOTextureIsNormalMap) != 0;
|
||||
generateMipMaps = (options & kOOTextureMinFilterMask) == kOOTextureMinFilterMipMap;
|
||||
avoidShrinking = (options & kOOTextureNoShrink) != 0;
|
||||
|
||||
return self;
|
||||
@ -184,9 +183,12 @@ enum
|
||||
if (!ready)
|
||||
{
|
||||
priority = YES;
|
||||
OOLog(@"textureLoader.block", @"Blocking for completion of loading of %@", [path lastPathComponent]);
|
||||
[completionLock lock]; // Block until ready
|
||||
[completionLock unlock];
|
||||
[completionLock release];
|
||||
completionLock = nil;
|
||||
OOLog(@"textureLoader.block.done", @"Finished waiting around.");
|
||||
}
|
||||
|
||||
if (EXPECT(outData != NULL)) *outData = data;
|
||||
@ -275,7 +277,9 @@ enum
|
||||
if (sQueueTail == loader) sQueueTail = nil;
|
||||
[sQueueLock unlockWithCondition:(sQueueHead != nil) ? kConditionQueuedData : kConditionNoData];
|
||||
|
||||
OOLog(@"textureLoader.asyncLoad", @"Loading texture %@", [loader->path lastPathComponent]);
|
||||
[loader performLoad];
|
||||
OOLog(@"textureLoader.asyncLoad.done", @"Loading complete.");
|
||||
[loader release]; // Was retained in -queue.
|
||||
}
|
||||
else
|
||||
@ -352,7 +356,7 @@ enum
|
||||
rescale = (width != desiredWidth || height != desiredHeight);
|
||||
if (rescale)
|
||||
{
|
||||
newSize = desiredWidth * desiredHeight;
|
||||
newSize = desiredWidth * 4 * desiredHeight;
|
||||
if (generateMipMaps) newSize = (newSize * 4) / 3;
|
||||
|
||||
newData = malloc(newSize);
|
||||
@ -360,7 +364,7 @@ enum
|
||||
{
|
||||
// Try again without space for mipmaps
|
||||
generateMipMaps = NO;
|
||||
newSize = desiredWidth * desiredHeight;
|
||||
newSize = desiredWidth * 4 * desiredHeight;
|
||||
newData = malloc(newSize);
|
||||
}
|
||||
if (newData == NULL)
|
||||
@ -370,14 +374,7 @@ enum
|
||||
return;
|
||||
}
|
||||
|
||||
if (!scaleAsNormalMap)
|
||||
{
|
||||
ScalePixMap(data, width, height, rowBytes, newData, desiredWidth, desiredHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScaleNormalMap(data, width, height, rowBytes, newData, desiredWidth, desiredHeight);
|
||||
}
|
||||
ScalePixMap(data, width, height, rowBytes, newData, desiredWidth, desiredHeight);
|
||||
|
||||
// Replace data with new, scaled data.
|
||||
free(data);
|
||||
@ -390,20 +387,15 @@ enum
|
||||
if (generateMipMaps && !rescale)
|
||||
{
|
||||
// Make space...
|
||||
newData = realloc(data, (width * height * 4) / 3);
|
||||
newSize = desiredWidth * 4 * desiredHeight;
|
||||
newSize = (newSize * 4) / 3;
|
||||
newData = realloc(data, newSize);
|
||||
if (newData != nil) data = newData;
|
||||
else generateMipMaps = NO;
|
||||
}
|
||||
if (generateMipMaps)
|
||||
{
|
||||
if (!scaleAsNormalMap)
|
||||
{
|
||||
GenerateMipMaps(data, width, height);
|
||||
}
|
||||
else
|
||||
{
|
||||
GenerateNormalMapMipMaps(data, width, height);
|
||||
}
|
||||
GenerateMipMaps(data, width, height);
|
||||
}
|
||||
|
||||
// All done.
|
||||
|
@ -11,13 +11,12 @@
|
||||
|
||||
/* Read transformations we don't use */
|
||||
#define PNG_NO_READ_STRIP_ALPHA
|
||||
#define PNG_NO_READ_BGR
|
||||
// #define PNG_NO_READ_BGR
|
||||
#define PNG_NO_READ_SWAP
|
||||
#define PNG_NO_READ_PACKSWAP
|
||||
#define PNG_NO_READ_INVERT
|
||||
#define PNG_NO_READ_DITHER
|
||||
#define PNG_NO_READ_GAMMA
|
||||
#define PNG_NO_READ_SWAP_ALPHA
|
||||
#define PNG_NO_READ_INVERT_ALPHA
|
||||
#define PNG_NO_READ_STRIP_ALPHA
|
||||
#define PNG_NO_READ_USER_TRANSFORM
|
||||
|
@ -125,7 +125,6 @@ extern NSString * const kOOLogFileNotFound; // @"files.notfound"
|
||||
extern NSString * const kOOLogFileNotLoaded; // @"files.notloaded"
|
||||
|
||||
extern NSString * const kOOLogOpenGLError; // @"rendering.opengl.error"
|
||||
extern NSString * const kOOLogOpenGLExtensions; // @"rendering.opengl.extensions"
|
||||
|
||||
// Don't use. However, #defining it as @"unclassified.module" can be used as a stepping stone to OOLog support.
|
||||
extern NSString * const kOOLogUnconvertedNSLog; // @"unclassified"
|
||||
|
@ -390,7 +390,6 @@ NSString * const kOOLogException = @"exception";
|
||||
NSString * const kOOLogFileNotFound = @"files.notFound";
|
||||
NSString * const kOOLogFileNotLoaded = @"files.notLoaded";
|
||||
NSString * const kOOLogOpenGLError = @"rendering.opengl.error";
|
||||
NSString * const kOOLogOpenGLExtensions = @"rendering.opengl.extensions";
|
||||
NSString * const kOOLogUnconvertedNSLog = @"unclassified";
|
||||
|
||||
|
||||
|
@ -53,27 +53,6 @@ typedef CGLContextObj OOOpenGLContext;
|
||||
#include <GL/glext.h>
|
||||
|
||||
|
||||
#if OOLITE_WINDOWS
|
||||
/* Define the function pointers for the OpenGL extensions used in the game -
|
||||
this is not required on the Mac, but is on at least Windows.
|
||||
*/
|
||||
PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
|
||||
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
|
||||
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
|
||||
PFNGLUNIFORM1IARBPROC glUniform1iARB;
|
||||
PFNGLUNIFORM1FARBPROC glUniform1fARB;
|
||||
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
|
||||
PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
|
||||
PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
|
||||
PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
|
||||
PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
|
||||
PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
|
||||
PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
|
||||
PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
|
||||
PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
|
||||
#endif // OOLITE_WINDOWS
|
||||
|
||||
|
||||
/* FIXME: should probably use glXCopyContext() and glXMakeCurrent() on Linux;
|
||||
there should be an equivalent for Windows. This isn't very urgent since
|
||||
Oolite doesnt' use distinct contexts, though. I can't see an obvious SDL
|
||||
|
119
src/Core/OOOpenGLExtensionManager.h
Normal file
119
src/Core/OOOpenGLExtensionManager.h
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
|
||||
OOOpenGLExtensionManager.h
|
||||
|
||||
Handles checking for and using OpenGL extensions and related information.
|
||||
|
||||
This is thread safe, except for initialization; that is, +sharedManager should
|
||||
be called from the main thread at an early point. The OpenGL context must be
|
||||
set up by then.
|
||||
|
||||
Oolite
|
||||
Copyright (C) 2004-2007 Giles C Williams and contributors
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOCocoa.h"
|
||||
#import "OOOpenGL.h"
|
||||
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
|
||||
// Certain extensions are required for shader support.
|
||||
#ifndef GL_ARB_multitexture
|
||||
#warning NO_SHADERS not defined and GL_ARB_multitexture not defined.
|
||||
#endif
|
||||
|
||||
#ifndef GL_ARB_shader_objects
|
||||
#warning NO_SHADERS not defined and GL_ARB_shader_objects not defined.
|
||||
#endif
|
||||
|
||||
#ifndef GL_ARB_shading_language_100
|
||||
#warning NO_SHADERS not defined and GL_ARB_shading_language_100 not defined.
|
||||
#endif
|
||||
|
||||
#ifndef GL_ARB_fragment_shader
|
||||
#warning NO_SHADERS not defined and GL_ARB_fragment_shader not defined.
|
||||
#endif
|
||||
|
||||
#ifndef GL_ARB_vertex_shader
|
||||
#warning NO_SHADERS not defined and GL_ARB_vertex_shader not defined.
|
||||
#endif
|
||||
|
||||
// FIXME: are these last two relevant? Aren't they for the older "assembly-style" shaders?
|
||||
#ifndef GL_ARB_fragment_program
|
||||
#warning NO_SHADERS not defined and GL_ARB_fragment_program not defined.
|
||||
#endif
|
||||
|
||||
#ifndef GL_ARB_vertex_program
|
||||
#warning NO_SHADERS not defined and GL_ARB_vertex_program not defined.
|
||||
#endif
|
||||
|
||||
#endif NO_SHADERS
|
||||
|
||||
|
||||
@interface OOOpenGLExtensionManager: NSObject
|
||||
{
|
||||
NSLock *lock;
|
||||
NSSet *extensions;
|
||||
|
||||
NSString *vendor;
|
||||
NSString *renderer;
|
||||
|
||||
unsigned major, minor, release;
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
BOOL testedForShaders;
|
||||
BOOL shadersAvailable;
|
||||
#endif
|
||||
}
|
||||
|
||||
+ (id)sharedManager;
|
||||
|
||||
- (BOOL)haveExtension:(NSString *)extension;
|
||||
|
||||
- (BOOL)shadersSupported;
|
||||
|
||||
- (unsigned)majorVersionNumber;
|
||||
- (unsigned)minorVersionNumber;
|
||||
- (unsigned)releaseVersionNumber;
|
||||
- (void)getVersionMajor:(unsigned *)outMajor minor:(unsigned *)outMinor release:(unsigned *)outRelease;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#if OOLITE_WINDOWS && !defined(NO_SHADERS)
|
||||
/* Define the function pointers for the OpenGL extensions used in the game
|
||||
(required for Windows only)
|
||||
These are set up by -[OOOpenGLExtensionManager shadersSupported]
|
||||
*/
|
||||
PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
|
||||
PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
|
||||
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
|
||||
PFNGLUNIFORM1IARBPROC glUniform1iARB;
|
||||
PFNGLUNIFORM1FARBPROC glUniform1fARB;
|
||||
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
|
||||
PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
|
||||
PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
|
||||
PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
|
||||
PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
|
||||
PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
|
||||
PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
|
||||
PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
|
||||
PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
|
||||
#endif // OOLITE_WINDOWS
|
271
src/Core/OOOpenGLExtensionManager.m
Normal file
271
src/Core/OOOpenGLExtensionManager.m
Normal file
@ -0,0 +1,271 @@
|
||||
/*
|
||||
|
||||
OOOpenGLExtensionManager.m
|
||||
|
||||
Oolite
|
||||
Copyright (C) 2004-2007 Giles C Williams and contributors
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOOpenGLExtensionManager.h"
|
||||
#import "OOLogging.h"
|
||||
#import "OOFunctionAttributes.h"
|
||||
|
||||
|
||||
static NSString * const kOOLogOpenGLShaderSupport = @"rendering.opengl.shader.support";
|
||||
|
||||
|
||||
static OOOpenGLExtensionManager *sSingleton = nil;
|
||||
|
||||
|
||||
// Read integer from string, advancing string to end of read data.
|
||||
static unsigned IntegerFromString(const GLubyte **ioString);
|
||||
|
||||
|
||||
@implementation OOOpenGLExtensionManager
|
||||
|
||||
- (id)init
|
||||
{
|
||||
NSString *extensionString = nil;
|
||||
NSArray *components = nil;
|
||||
const GLubyte *versionString = nil, *curr = nil;
|
||||
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
lock = [[NSLock alloc] init];
|
||||
|
||||
extensionString = [NSString stringWithUTF8String:(char *)glGetString(GL_EXTENSIONS)];
|
||||
components = [extensionString componentsSeparatedByString:@" "];
|
||||
extensions = [[NSSet alloc] initWithArray:components];
|
||||
|
||||
vendor = [[NSString alloc] initWithUTF8String:(const char *)glGetString(GL_VENDOR)];
|
||||
renderer = [[NSString alloc] initWithUTF8String:(const char *)glGetString(GL_RENDERER)];
|
||||
|
||||
versionString = glGetString(GL_VERSION);
|
||||
if (versionString != NULL)
|
||||
{
|
||||
/* String is supposed to be "major.minorFOO" or
|
||||
"major.minor.releaseFOO" where FOO is an empty string or
|
||||
a string beginning with space.
|
||||
*/
|
||||
curr = versionString;
|
||||
major = IntegerFromString(&curr);
|
||||
if (*curr == '.')
|
||||
{
|
||||
curr++;
|
||||
minor = IntegerFromString(&curr);
|
||||
}
|
||||
if (*curr == '.')
|
||||
{
|
||||
curr++;
|
||||
release = IntegerFromString(&curr);
|
||||
}
|
||||
}
|
||||
|
||||
OOLog(@"rendering.opengl.version", @"OpenGL renderer version: %u.%u.%u (\"%s\")\nVendor: %@\nRenderer: %@", major, minor, release, versionString, vendor, renderer);
|
||||
OOLog(@"rendering.opengl.extensions", @"OpenGL extensions (%u):\n%@", [extensions count], extensionString);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[extensions release];
|
||||
[lock release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
+ (id)sharedManager
|
||||
{
|
||||
// NOTE: assumes single-threaded first access. See header.
|
||||
if (sSingleton == nil) [[self alloc] init];
|
||||
return sSingleton;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)haveExtension:(NSString *)extension
|
||||
{
|
||||
[lock lock];
|
||||
BOOL result = [extensions containsObject:extension];
|
||||
[lock unlock];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)shadersSupported
|
||||
{
|
||||
#ifndef NO_SHADERS
|
||||
if (EXPECT(testedForShaders)) return shadersAvailable;
|
||||
|
||||
[lock lock];
|
||||
testedForShaders = YES;
|
||||
|
||||
if (major == 1 && minor < 5)
|
||||
{
|
||||
OOLog(kOOLogOpenGLShaderSupport, @"Shaders will not be used (OpenGL version < 1.5).");
|
||||
goto END;
|
||||
}
|
||||
|
||||
const NSString *requiredExtension[] =
|
||||
{
|
||||
@"GL_ARB_multitexture",
|
||||
@"GL_ARB_shader_objects",
|
||||
@"GL_ARB_shading_language_100",
|
||||
@"GL_ARB_fragment_shader",
|
||||
@"GL_ARB_vertex_shader",
|
||||
@"GL_ARB_fragment_program",
|
||||
@"GL_ARB_vertex_program",
|
||||
nil // sentinel - don't remove!
|
||||
};
|
||||
NSString **required = NULL;
|
||||
|
||||
for (required = requiredExtension; *required != nil; ++required)
|
||||
{
|
||||
if (![extensions containsObject:*required]) // Note to people cleaning up: can't use haveExtension: because we've already got the lock.
|
||||
{
|
||||
OOLog(kOOLogOpenGLShaderSupport, @"Shaders will not be used (OpenGL extension %@ is not available).", *required);
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
|
||||
#if OOLITE_WINDOWS
|
||||
glGetObjectParameterivARB = (PFNGLGETOBJECTPARAMETERIVARBPROC)wglGetProcAddress("glGetObjectParameterivARB");
|
||||
glCreateShaderObjectARB = (PFNGLCREATESHADEROBJECTARBPROC)wglGetProcAddress("glCreateShaderObjectARB");
|
||||
glGetInfoLogARB = (PFNGLGETINFOLOGARBPROC)wglGetProcAddress("glGetInfoLogARB");
|
||||
glCreateProgramObjectARB = (PFNGLCREATEPROGRAMOBJECTARBPROC)wglGetProcAddress("glCreateProgramObjectARB");
|
||||
glAttachObjectARB = (PFNGLATTACHOBJECTARBPROC)wglGetProcAddress("glAttachObjectARB");
|
||||
glDeleteObjectARB = (PFNGLDELETEOBJECTARBPROC)wglGetProcAddress("glDeleteObjectARB");
|
||||
glLinkProgramARB = (PFNGLLINKPROGRAMARBPROC)wglGetProcAddress("glLinkProgramARB");
|
||||
glCompileShaderARB = (PFNGLCOMPILESHADERARBPROC)wglGetProcAddress("glCompileShaderARB");
|
||||
glShaderSourceARB = (PFNGLSHADERSOURCEARBPROC)wglGetProcAddress("glShaderSourceARB");
|
||||
glUseProgramObjectARB = (PFNGLUSEPROGRAMOBJECTARBPROC)wglGetProcAddress("glUseProgramObjectARB");
|
||||
glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)wglGetProcAddress("glActiveTextureARB");
|
||||
glGetUniformLocationARB = (PFNGLGETUNIFORMLOCATIONARBPROC)wglGetProcAddress("glGetUniformLocationARB");
|
||||
glUniform1iARB = (PFNGLUNIFORM1IARBPROC)wglGetProcAddress("glUniform1iARB");
|
||||
glUniform1fARB = (PFNGLUNIFORM1FARBPROC)wglGetProcAddress("glUniform1fARB");
|
||||
#endif
|
||||
|
||||
shadersAvailable = YES;
|
||||
|
||||
END:
|
||||
[lock unlock];
|
||||
return shadersAvailable;
|
||||
#else
|
||||
// NO_SHADERS
|
||||
return NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
- (unsigned)majorVersionNumber
|
||||
{
|
||||
return major;
|
||||
}
|
||||
|
||||
|
||||
- (unsigned)minorVersionNumber
|
||||
{
|
||||
return minor;
|
||||
}
|
||||
|
||||
|
||||
- (unsigned)releaseVersionNumber
|
||||
{
|
||||
return release;
|
||||
}
|
||||
|
||||
|
||||
- (void)getVersionMajor:(unsigned *)outMajor minor:(unsigned *)outMinor release:(unsigned *)outRelease
|
||||
{
|
||||
if (outMajor != NULL) *outMajor = major;
|
||||
if (outMinor != NULL) *outMinor = minor;
|
||||
if (outRelease != NULL) *outRelease = release;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static unsigned IntegerFromString(const GLubyte **ioString)
|
||||
{
|
||||
if (EXPECT_NOT(ioString == NULL)) return 0;
|
||||
|
||||
unsigned result = 0;
|
||||
const GLubyte *curr = *ioString;
|
||||
|
||||
while ('0' <= *curr && *curr <= '9')
|
||||
{
|
||||
result = result * 10 + *curr++ - '0';
|
||||
}
|
||||
|
||||
*ioString = curr;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@implementation OOOpenGLExtensionManager (Singleton)
|
||||
|
||||
/* Canonical singleton boilerplate.
|
||||
See Cocoa Fundamentals Guide: Creating a Singleton Instance.
|
||||
See also +sharedManager above.
|
||||
|
||||
// NOTE: assumes single-threaded first access.
|
||||
*/
|
||||
|
||||
+ (id)allocWithZone:(NSZone *)inZone
|
||||
{
|
||||
if (sSingleton == nil)
|
||||
{
|
||||
sSingleton = [super allocWithZone:inZone];
|
||||
return sSingleton;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (id)copyWithZone:(NSZone *)inZone
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (id)retain
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (unsigned)retainCount
|
||||
{
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
|
||||
- (void)release
|
||||
{}
|
||||
|
||||
|
||||
- (id)autorelease
|
||||
{
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
@ -38,21 +38,8 @@ uint8_t *ScaleUpPixMap(uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight
|
||||
*/
|
||||
void ScalePixMap(void *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, void *dstPixels, unsigned dstWidth, unsigned dstHeight);
|
||||
|
||||
/* Assumes 4 planes, 8 bits per sample, interleaved, with the first three
|
||||
forming a normalized vector.
|
||||
dstPixels must have space for dstWidth * dstHeight pixels (no row padding
|
||||
is generated).
|
||||
*/
|
||||
void ScaleNormalMap(void *srcTexels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, void *dstTexels, unsigned dstWidth, unsigned dstHeight);
|
||||
|
||||
|
||||
/* Assumes 4 planes, 8 bits per sample, interleaved.
|
||||
Buffer must have space for (4 * width * height) / 3 pixels.
|
||||
*/
|
||||
void GenerateMipMaps(void *textureBytes, unsigned width, unsigned height);
|
||||
|
||||
|
||||
/* Assumes 4 planes, 8 bits per sample, interleaved.
|
||||
Buffer must have space for (4 * width * height) / 3 pixels.
|
||||
*/
|
||||
void GenerateNormalMapMipMaps(void *textureBytes, unsigned width, unsigned height);
|
||||
|
@ -23,11 +23,14 @@ MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
|
||||
// Temporarily disabled build flags: -O3 -falign-loops=32 -falign-loops-max-skip=31
|
||||
|
||||
|
||||
#import "OOTextureScaling.h"
|
||||
#import "OOFunctionAttributes.h"
|
||||
#import <math.h>
|
||||
#import <stdlib.h>
|
||||
#import "OOLogging.h"
|
||||
#import "OOMaths.h"
|
||||
|
||||
|
||||
uint8_t *ScaleUpPixMap(uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcBytesPerRow, unsigned planes, unsigned dstWidth, unsigned dstHeight)
|
||||
@ -101,11 +104,11 @@ uint8_t *ScaleUpPixMap(uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight
|
||||
}
|
||||
|
||||
|
||||
static void ScaleUpHorizontally(const uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstWidth);
|
||||
static void ScaleDownHorizontally(const uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstWidth);
|
||||
static void ScaleUpVertically(const uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstHeight);
|
||||
static void ScaleDownVertically(const uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstHeight);
|
||||
static void CopyRows(const uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels);
|
||||
static void ScaleUpHorizontally(const char *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstWidth);
|
||||
static void ScaleDownHorizontally(const char *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstWidth);
|
||||
static void ScaleUpVertically(const char *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstHeight);
|
||||
static void ScaleDownVertically(const char *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstHeight);
|
||||
static void CopyRows(const char *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels);
|
||||
|
||||
|
||||
void ScalePixMap(void *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, void *dstPixels, unsigned dstWidth, unsigned dstHeight)
|
||||
@ -160,49 +163,120 @@ void ScalePixMap(void *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigne
|
||||
}
|
||||
|
||||
|
||||
void ScaleNormalMap(void *srcTexels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, void *dstTexels, unsigned dstWidth, unsigned dstHeight)
|
||||
{
|
||||
ScalePixMap(srcTexels, srcWidth, srcHeight, srcRowBytes, dstTexels, dstWidth, dstHeight);
|
||||
}
|
||||
|
||||
|
||||
void GenerateMipMaps(void *textureBytes, unsigned width, unsigned height)
|
||||
{
|
||||
if (EXPECT_NOT(width != OORoundUpToPowerOf2(width) || height != OORoundUpToPowerOf2(height)))
|
||||
{
|
||||
OOLog(@"texture.generateMipMaps.skip", @"Non-power-of-two dimensions (%ux%u) passed to GenerateMipMaps() - ignoring, data will be junk.", width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GenerateNormalMapMipMaps(void *textureBytes, unsigned width, unsigned height)
|
||||
{
|
||||
uint_fast32_t w = width, h = height, x, y;
|
||||
uint32_t *src0, *src1, *dst, *next;
|
||||
uint_fast32_t px00, px01, px10, px11;
|
||||
uint_fast32_t ag, rb; // red and blue channel, green and alpha channel.
|
||||
|
||||
next = textureBytes;
|
||||
|
||||
#define DUMP_MIP_MAPS
|
||||
#ifdef DUMP_MIP_MAPS
|
||||
static unsigned ID = -1;
|
||||
++ID;
|
||||
uint32_t *start;
|
||||
unsigned level = 0;
|
||||
#endif
|
||||
|
||||
while (1 < w && 1 < h)
|
||||
{
|
||||
src0 = next;
|
||||
next = src0 + w * h;
|
||||
src1 = src0 + w;
|
||||
dst = next;
|
||||
|
||||
#ifdef DUMP_MIP_MAPS
|
||||
start = src0;
|
||||
#endif
|
||||
|
||||
w >>= 1;
|
||||
h >>= 1;
|
||||
|
||||
y = h;
|
||||
do
|
||||
{
|
||||
x = w;
|
||||
do
|
||||
{
|
||||
// Read four pixels in a square...
|
||||
px00 = *src0++;
|
||||
px01 = *src0++;
|
||||
px10 = *src1++;
|
||||
px11 = *src1++;
|
||||
|
||||
// ...and add them together, channel by channel.
|
||||
ag = (px00 & 0xFF00FF00) >> 8;
|
||||
rb = (px00 & 0x00FF00FF);
|
||||
ag += (px01 & 0xFF00FF00) >> 8;
|
||||
rb += (px01 & 0x00FF00FF);
|
||||
ag += (px10 & 0xFF00FF00) >> 8;
|
||||
rb += (px10 & 0x00FF00FF);
|
||||
ag += (px11 & 0xFF00FF00) >> 8;
|
||||
rb += (px11 & 0x00FF00FF);
|
||||
|
||||
// ...shift the sums into place...
|
||||
ag <<= 6;
|
||||
rb >>= 2;
|
||||
|
||||
// ...and write output pixel.
|
||||
*dst++ = (ag & 0xFF00FF00) | (rb & 0x00FF00FF);
|
||||
} while (--x);
|
||||
|
||||
// Skip a row for each source row
|
||||
src0 = src1;
|
||||
src1 += w << 1;
|
||||
} while (--y);
|
||||
|
||||
#ifdef DUMP_MIP_MAPS
|
||||
NSString *name = [NSString stringWithFormat:@"/Users/jayton/Desktop/tex-debug/dump-%u-%u.raw", ID, level++];
|
||||
FILE *dump = fopen([name UTF8String], "w");
|
||||
if (dump != NULL)
|
||||
{
|
||||
fwrite(start, w, h * 16, dump);
|
||||
fclose(dump);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void ScaleUpHorizontally(const uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstWidth)
|
||||
static void ScaleUpHorizontally(const char *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstWidth)
|
||||
{
|
||||
// TODO
|
||||
OOLog(@"scale.unimplemented", @"Attempt to scale texture, currently unsupported - expect noise.");
|
||||
}
|
||||
|
||||
|
||||
static void ScaleDownHorizontally(const uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstWidth)
|
||||
static void ScaleDownHorizontally(const char *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstWidth)
|
||||
{
|
||||
// TODO
|
||||
OOLog(@"scale.unimplemented", @"Attempt to scale texture, currently unsupported - expect noise.");
|
||||
}
|
||||
|
||||
|
||||
static void ScaleUpVertically(const uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstHeight)
|
||||
static void ScaleUpVertically(const char *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstHeight)
|
||||
{
|
||||
// TODO
|
||||
OOLog(@"scale.unimplemented", @"Attempt to scale texture, currently unsupported - expect noise.");
|
||||
}
|
||||
|
||||
|
||||
static void ScaleDownVertically(const uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstHeight)
|
||||
static void ScaleDownVertically(const char *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels, unsigned dstHeight)
|
||||
{
|
||||
// TODO
|
||||
OOLog(@"scale.unimplemented", @"Attempt to scale texture, currently unsupported - expect noise.");
|
||||
}
|
||||
|
||||
|
||||
static void CopyRows(const uint8_t *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels)
|
||||
static void CopyRows(const char *srcPixels, unsigned srcWidth, unsigned srcHeight, unsigned srcRowBytes, uint8_t *dstPixels)
|
||||
{
|
||||
unsigned y;
|
||||
unsigned rowBytes;
|
||||
|
@ -492,19 +492,20 @@ static NSMutableDictionary* surface_cache;
|
||||
if ([fmgr fileExistsAtPath:filePath])
|
||||
{
|
||||
result = filePath;
|
||||
break;
|
||||
// break;
|
||||
}
|
||||
|
||||
filePath = [path stringByAppendingPathComponent:fileName];
|
||||
if ([fmgr fileExistsAtPath:filePath])
|
||||
{
|
||||
result = filePath;
|
||||
break;
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
if (result != nil)
|
||||
{
|
||||
OOLog(@"resourceManager.foundFile", @"Found %@/%@ at %@", folderName, fileName, filePath);
|
||||
if (genericPathCache == nil) genericPathCache = [[NSMutableDictionary alloc] init];
|
||||
[genericPathCache setObject:result forKey:key];
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ MA 02110-1301, USA.
|
||||
#import "OOStringParsing.h"
|
||||
#import "OOCollectionExtractors.h"
|
||||
#import "OOConstToString.h"
|
||||
#import "OOOpenGLExtensionManager.h"
|
||||
|
||||
#import "Octree.h"
|
||||
#import "CollisionRegion.h"
|
||||
@ -101,22 +102,22 @@ static BOOL MaintainLinkedLists(Universe* uni);
|
||||
|
||||
no_update = NO;
|
||||
|
||||
// init OpenGL extension manager (must be done before any other threads might use it)
|
||||
[OOOpenGLExtensionManager sharedManager];
|
||||
|
||||
// init the Resource Manager
|
||||
[ResourceManager paths];
|
||||
|
||||
reducedDetail = NO;
|
||||
|
||||
#ifndef GNUSTEP
|
||||
#if OOLITE_MAC_OS_X
|
||||
//// speech stuff
|
||||
|
||||
speechSynthesizer = [[NSSpeechSynthesizer alloc] init];
|
||||
|
||||
//Jester Speech Begin
|
||||
speechArray = [[ResourceManager arrayFromFilesNamed:@"speech_pronunciation_guide.plist" inFolder:@"Config" andMerge:YES] retain];
|
||||
//Jester Speech End
|
||||
|
||||
////
|
||||
#endif
|
||||
#endif
|
||||
|
||||
dumpCollisionInfo = NO;
|
||||
next_universal_id = 100; // start arbitrarily above zero
|
||||
|
Loading…
x
Reference in New Issue
Block a user