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:
Jens Ayton 2007-04-14 00:07:32 +00:00
parent c66ebf27a0
commit bdbe1b72ff
27 changed files with 1039 additions and 413 deletions

View File

@ -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;
};

View File

@ -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;

View File

@ -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>

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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];
}
}

View File

@ -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

View File

@ -67,6 +67,12 @@ static OOMaterial *sActiveMaterial;
}
- (void)ensureFinishedLoading
{
}
- (void)unapply
{
// Do nothing.

View File

@ -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;
}

View File

@ -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.

View File

@ -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];
}
}

View File

@ -28,6 +28,7 @@ MA 02110-1301, USA.
#import "OOFunctionAttributes.h"
#import "OOStringParsing.h"
#import "ResourceManager.h"
#import "OOOpenGLExtensionManager.h"
static NSMutableDictionary *sShaderCache = nil;

View File

@ -29,6 +29,7 @@ MA 02110-1301, USA.
#import "OOFunctionAttributes.h"
#import <string.h>
#import "OOMaths.h"
#import "OOOpenGLExtensionManager.h"
typedef enum

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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"

View File

@ -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";

View File

@ -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

View 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

View 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

View File

@ -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);

View File

@ -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;

View File

@ -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];
}

View File

@ -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