Rewrite of shader code.
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@923 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
e1d5ba7272
commit
73aafb43e1
@ -21,7 +21,7 @@ endif
|
||||
OBJC_PROGRAM_NAME = oolite
|
||||
|
||||
oolite_C_FILES = legacy_random.c strlcpy.c
|
||||
oolite_OBJC_FILES = Comparison.m AI.m DustEntity.m Entity.m GameController.m GuiDisplayGen.m HeadUpDisplay.m main.m MyOpenGLView.m OpenGLSprite.m ParticleEntity.m PlanetEntity.m PlayerEntityLegacyScriptEngine.m PlayerEntityContracts.m PlayerEntityControls.m PlayerEntityLoadSave.m PlayerEntitySound.m PlayerEntity.m ResourceManager.m RingEntity.m ShipEntityAI.m ShipEntity.m SkyEntity.m StationEntity.m TextureStore.m Universe.m OOSound.m SDLMusic.m SDLImage.m NSFileManagerOOExtensions.m JoystickHandler.m PlayerEntityStickMapper.m OOBasicSoundReferencePoint.m OOBasicSoundSource.m OOCharacter.m OOTrumble.m WormholeEntity.m NSScannerOOExtensions.m OOXMLExtensions.m NSMutableDictionaryOOExtensions.m Geometry.m Octree.m CollisionRegion.m OOColor.m OOLogging.m OOCacheManager.m OOCache.m OOStringParsing.m OOCollectionExtractors.m OOVector.m OOMatrix.m OOQuaternion.m OOVoxel.m OOTriangle.m OOPListParsing.m OOFastArithmetic.m OOTextureScaling.m OOConstToString.m OOScript.m OOJSScript.m OOJavaScriptEngine.m OOPListScript.m OOSCompiler.m OOSTokenizer.m NSStringOOExtensions.m PlayerEntityScriptMethods.m OOWeakReference.m OOJSEntity.m EntityOOJavaScriptExtensions.m OOJSQuaternion.m
|
||||
oolite_OBJC_FILES = Comparison.m AI.m DustEntity.m Entity.m GameController.m GuiDisplayGen.m HeadUpDisplay.m main.m MyOpenGLView.m OpenGLSprite.m ParticleEntity.m PlanetEntity.m PlayerEntityLegacyScriptEngine.m PlayerEntityContracts.m PlayerEntityControls.m PlayerEntityLoadSave.m PlayerEntitySound.m PlayerEntity.m ResourceManager.m RingEntity.m ShipEntityAI.m ShipEntity.m SkyEntity.m StationEntity.m TextureStore.m Universe.m OOSound.m SDLMusic.m SDLImage.m NSFileManagerOOExtensions.m JoystickHandler.m PlayerEntityStickMapper.m OOBasicSoundReferencePoint.m OOBasicSoundSource.m OOCharacter.m OOTrumble.m WormholeEntity.m NSScannerOOExtensions.m OOXMLExtensions.m NSMutableDictionaryOOExtensions.m Geometry.m Octree.m CollisionRegion.m OOColor.m OOLogging.m OOCacheManager.m OOCache.m OOStringParsing.m OOCollectionExtractors.m OOVector.m OOMatrix.m OOQuaternion.m OOVoxel.m OOTriangle.m OOPListParsing.m OOFastArithmetic.m OOTextureScaling.m OOConstToString.m OOScript.m OOJSScript.m OOJavaScriptEngine.m OOPListScript.m OOSCompiler.m OOSTokenizer.m NSStringOOExtensions.m PlayerEntityScriptMethods.m OOWeakReference.m OOJSEntity.m EntityOOJavaScriptExtensions.m OOJSQuaternion.m OOMaterial.m OOShaderMaterial.m OOShaderProgram.m OOShaderUniform.m
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/objc.make
|
||||
include GNUmakefile.postamble
|
||||
|
@ -258,10 +258,15 @@
|
||||
1A5DBAB00BC000DC00D57389 /* OOSTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A5DBAA40BC000DC00D57389 /* OOSTokenizer.m */; };
|
||||
1A5DBD580BC17F0900D57389 /* NSStringOOExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5DBD560BC17F0900D57389 /* NSStringOOExtensions.h */; };
|
||||
1A5DBD590BC17F0900D57389 /* NSStringOOExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A5DBD570BC17F0900D57389 /* NSStringOOExtensions.m */; };
|
||||
1A71D85C0BCA88AA00CD5C13 /* OOPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A71D85A0BCA88AA00CD5C13 /* OOPlayer.h */; };
|
||||
1A71D85D0BCA88AA00CD5C13 /* OOPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A71D85B0BCA88AA00CD5C13 /* OOPlayer.m */; };
|
||||
1A71D8A10BCA8B6500CD5C13 /* OOLocalPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A71D89F0BCA8B6500CD5C13 /* OOLocalPlayer.h */; };
|
||||
1A71D8A20BCA8B6500CD5C13 /* OOLocalPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A71D8A00BCA8B6500CD5C13 /* OOLocalPlayer.m */; };
|
||||
1A71DC350BCBA17000CD5C13 /* OOShaderMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A71DC330BCBA17000CD5C13 /* OOShaderMaterial.h */; };
|
||||
1A71DC360BCBA17000CD5C13 /* OOShaderMaterial.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A71DC340BCBA17000CD5C13 /* OOShaderMaterial.m */; };
|
||||
1A71DDD80BCC0F0400CD5C13 /* OOShaderProgram.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A71DDD60BCC0F0400CD5C13 /* OOShaderProgram.h */; };
|
||||
1A71DDD90BCC0F0400CD5C13 /* OOShaderProgram.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A71DDD70BCC0F0400CD5C13 /* OOShaderProgram.m */; };
|
||||
1A71DF0B0BCC3DED00CD5C13 /* OOMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A71DF090BCC3DED00CD5C13 /* OOMaterial.h */; };
|
||||
1A71DF0C0BCC3DED00CD5C13 /* OOMaterial.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A71DF0A0BCC3DED00CD5C13 /* OOMaterial.m */; };
|
||||
1A71DF610BCC46F300CD5C13 /* OOShaderUniform.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A71DF5F0BCC46F300CD5C13 /* OOShaderUniform.h */; };
|
||||
1A71DF620BCC46F300CD5C13 /* OOShaderUniform.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A71DF600BCC46F300CD5C13 /* OOShaderUniform.m */; };
|
||||
1A71E44A0BCD5C4200CD5C13 /* material-defaults.plist in Copy Config */ = {isa = PBXBuildFile; fileRef = 1A71E4490BCD5C4200CD5C13 /* material-defaults.plist */; };
|
||||
1A81F7090A7BAC4D006580AD /* OOCAMusic.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A81F7070A7BAC4D006580AD /* OOCAMusic.m */; };
|
||||
1A81F70A0A7BAC4D006580AD /* OOCAMusic.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A81F7080A7BAC4D006580AD /* OOCAMusic.h */; };
|
||||
1A8A37040B95CADD007D20B8 /* PlayerEntityLoadSave.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A8A37020B95CADD007D20B8 /* PlayerEntityLoadSave.m */; };
|
||||
@ -478,6 +483,7 @@
|
||||
dstPath = Config;
|
||||
dstSubfolderSpec = 7;
|
||||
files = (
|
||||
1A71E44A0BCD5C4200CD5C13 /* material-defaults.plist in Copy Config */,
|
||||
1A34912A0BC25EAA00802DA7 /* world-scripts.plist in Copy Config */,
|
||||
1A2316EE0B9CFAD700EF0852 /* characters.plist in Copy Config */,
|
||||
1A2316EF0B9CFAD700EF0852 /* commodities.plist in Copy Config */,
|
||||
@ -1011,6 +1017,15 @@
|
||||
1A71D85B0BCA88AA00CD5C13 /* OOPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOPlayer.m; sourceTree = "<group>"; };
|
||||
1A71D89F0BCA8B6500CD5C13 /* OOLocalPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOLocalPlayer.h; sourceTree = "<group>"; };
|
||||
1A71D8A00BCA8B6500CD5C13 /* OOLocalPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOLocalPlayer.m; sourceTree = "<group>"; };
|
||||
1A71DC330BCBA17000CD5C13 /* OOShaderMaterial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOShaderMaterial.h; sourceTree = "<group>"; };
|
||||
1A71DC340BCBA17000CD5C13 /* OOShaderMaterial.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOShaderMaterial.m; sourceTree = "<group>"; };
|
||||
1A71DDD60BCC0F0400CD5C13 /* OOShaderProgram.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOShaderProgram.h; sourceTree = "<group>"; };
|
||||
1A71DDD70BCC0F0400CD5C13 /* OOShaderProgram.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOShaderProgram.m; sourceTree = "<group>"; };
|
||||
1A71DF090BCC3DED00CD5C13 /* OOMaterial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOMaterial.h; sourceTree = "<group>"; };
|
||||
1A71DF0A0BCC3DED00CD5C13 /* OOMaterial.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOMaterial.m; sourceTree = "<group>"; };
|
||||
1A71DF5F0BCC46F300CD5C13 /* OOShaderUniform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOShaderUniform.h; sourceTree = "<group>"; };
|
||||
1A71DF600BCC46F300CD5C13 /* OOShaderUniform.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOShaderUniform.m; sourceTree = "<group>"; };
|
||||
1A71E4490BCD5C4200CD5C13 /* material-defaults.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = "material-defaults.plist"; sourceTree = "<group>"; };
|
||||
1A81F7070A7BAC4D006580AD /* OOCAMusic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOCAMusic.m; sourceTree = "<group>"; };
|
||||
1A81F7080A7BAC4D006580AD /* OOCAMusic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOCAMusic.h; sourceTree = "<group>"; };
|
||||
1A8A37020B95CADD007D20B8 /* PlayerEntityLoadSave.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlayerEntityLoadSave.m; sourceTree = "<group>"; };
|
||||
@ -1310,6 +1325,7 @@
|
||||
1A2316E70B9CFAD700EF0852 /* keyconfig.plist */,
|
||||
1A2316E80B9CFAD700EF0852 /* logcontrol.plist */,
|
||||
1AED74C70BBA3CAA009410CD /* logcontrol.plist.xml */,
|
||||
1A71E4490BCD5C4200CD5C13 /* material-defaults.plist */,
|
||||
1A2316E90B9CFAD700EF0852 /* missiontext.plist */,
|
||||
1A2316EB0B9CFAD700EF0852 /* shipdata.plist */,
|
||||
1A2316EC0B9CFAD700EF0852 /* shipyard.plist */,
|
||||
@ -1600,6 +1616,32 @@
|
||||
name = "PList & OOS scripting";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1A71DDD30BCC0EEF00CD5C13 /* Materials */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1A71DF090BCC3DED00CD5C13 /* OOMaterial.h */,
|
||||
1A71DF0A0BCC3DED00CD5C13 /* OOMaterial.m */,
|
||||
1A71DC330BCBA17000CD5C13 /* OOShaderMaterial.h */,
|
||||
1A71DC340BCBA17000CD5C13 /* OOShaderMaterial.m */,
|
||||
1A71DDD60BCC0F0400CD5C13 /* OOShaderProgram.h */,
|
||||
1A71DDD70BCC0F0400CD5C13 /* OOShaderProgram.m */,
|
||||
1A71DF5F0BCC46F300CD5C13 /* OOShaderUniform.h */,
|
||||
1A71DF600BCC46F300CD5C13 /* OOShaderUniform.m */,
|
||||
);
|
||||
name = Materials;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1A71E5230BCD7C4E00CD5C13 /* Player refactoring */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1A71D85A0BCA88AA00CD5C13 /* OOPlayer.h */,
|
||||
1A71D85B0BCA88AA00CD5C13 /* OOPlayer.m */,
|
||||
1A71D89F0BCA8B6500CD5C13 /* OOLocalPlayer.h */,
|
||||
1A71D8A00BCA8B6500CD5C13 /* OOLocalPlayer.m */,
|
||||
);
|
||||
name = "Player refactoring";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
1A8A3BE90B963F02007D20B8 /* Source */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1617,10 +1659,8 @@
|
||||
25161116099544390037C2E1 /* OOSound.h */,
|
||||
25161100099544380037C2E1 /* OpenGLSprite.h */,
|
||||
251610FF099544380037C2E1 /* OpenGLSprite.m */,
|
||||
1A71D85A0BCA88AA00CD5C13 /* OOPlayer.h */,
|
||||
1A71D85B0BCA88AA00CD5C13 /* OOPlayer.m */,
|
||||
1A71D89F0BCA8B6500CD5C13 /* OOLocalPlayer.h */,
|
||||
1A71D8A00BCA8B6500CD5C13 /* OOLocalPlayer.m */,
|
||||
1A71E5230BCD7C4E00CD5C13 /* Player refactoring */,
|
||||
1A71DDD30BCC0EEF00CD5C13 /* Materials */,
|
||||
1A5DBA980BC000DC00D57389 /* Scripting */,
|
||||
);
|
||||
name = Source;
|
||||
@ -2069,8 +2109,10 @@
|
||||
1A2A8D3A0BC6765F001E00FB /* EntityOOJavaScriptExtensions.h in Headers */,
|
||||
1A2A8E030BC67CCC001E00FB /* OOWeakReference.h in Headers */,
|
||||
1A2A91520BC6BC66001E00FB /* OOJSQuaternion.h in Headers */,
|
||||
1A71D85C0BCA88AA00CD5C13 /* OOPlayer.h in Headers */,
|
||||
1A71D8A10BCA8B6500CD5C13 /* OOLocalPlayer.h in Headers */,
|
||||
1A71DC350BCBA17000CD5C13 /* OOShaderMaterial.h in Headers */,
|
||||
1A71DDD80BCC0F0400CD5C13 /* OOShaderProgram.h in Headers */,
|
||||
1A71DF0B0BCC3DED00CD5C13 /* OOMaterial.h in Headers */,
|
||||
1A71DF610BCC46F300CD5C13 /* OOShaderUniform.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -2258,8 +2300,10 @@
|
||||
1A2A8D3B0BC6765F001E00FB /* EntityOOJavaScriptExtensions.m in Sources */,
|
||||
1A2A8E040BC67CCC001E00FB /* OOWeakReference.m in Sources */,
|
||||
1A2A91530BC6BC66001E00FB /* OOJSQuaternion.m in Sources */,
|
||||
1A71D85D0BCA88AA00CD5C13 /* OOPlayer.m in Sources */,
|
||||
1A71D8A20BCA8B6500CD5C13 /* OOLocalPlayer.m in Sources */,
|
||||
1A71DC360BCBA17000CD5C13 /* OOShaderMaterial.m in Sources */,
|
||||
1A71DDD90BCC0F0400CD5C13 /* OOShaderProgram.m in Sources */,
|
||||
1A71DF0C0BCC3DED00CD5C13 /* OOMaterial.m in Sources */,
|
||||
1A71DF620BCC46F300CD5C13 /* OOShaderUniform.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -78,6 +78,7 @@ dataCache.rebuild = inherit;
|
||||
dataCache.write.success = inherit;
|
||||
dataCache.write.failed = $error;
|
||||
dataCache.rebuild.octree = no;
|
||||
dataCache.willWrite = no;
|
||||
|
||||
$dataCacheStatus = yes;
|
||||
$dataCacheError = $error;
|
||||
@ -150,14 +151,6 @@ rendering.opengl.error = $error; // Test for and display OpenGL errors
|
||||
rendering.opengl.version = $troubleShootingDump; // Display renderer version information at startup
|
||||
rendering.opengl.extensions = $troubleShootingDump; // List OpenGL extensions at startup
|
||||
rendering.opengl.shader.support = $troubleShootingDump; // Messages about factors influencing availability of OpenGL shaders
|
||||
rendering.opengl.shader.init = inherit;
|
||||
rendering.opengl.shader.init.dump = $troubleShootingDump;
|
||||
rendering.opengl.shader.init.dump.shader = inherit;
|
||||
rendering.opengl.shader.init.dump.texture = inherit;
|
||||
rendering.opengl.shader.init.dump.shaderInfo = inherit;
|
||||
rendering.opengl.shader.init.success = inherit;
|
||||
rendering.opengl.shader.init.failed = $shaderError;
|
||||
rendering.opengl.shader.texNameMissing = $shaderError;
|
||||
rendering.opengl.stateDump = $troubleShootingDump; // Dump of OpenGL state (debug tool, currently unused)
|
||||
rendering.opengl.shader.uniform = $shaderDebugOn;
|
||||
|
||||
@ -241,6 +234,20 @@ script.trace.javaScript.call = inherit; // Prints selector and parameter st
|
||||
searchPaths.dumpAll = $troubleShootingDump;
|
||||
|
||||
|
||||
$shaderDebug = no;
|
||||
$shaderError = $error;
|
||||
shader.load.noShader = $error;
|
||||
shader.uniform = $shaderDebug;
|
||||
shader.uniform.set = inherit; // Successfully set a uniform.
|
||||
shader.uniform.unSet = inherit; // A uniform went unset or was cleared (either because there was no matching uniform in the shader, or the new uniform could not be set up).
|
||||
shader.uniform.badDescription = inherit; // A uniform specified in shipdata.plist could not be set up, because the configuration could not be understood.
|
||||
shader.uniform.bind.failed = inherit; // Problem setting up uniform bound to an object property.
|
||||
shader.vessel.init = $shaderDebug;
|
||||
shader.compile.vertex.failure = $shaderError;
|
||||
shader.compile.fragment.failure = $shaderError;
|
||||
shader.link.failure = $shaderError;
|
||||
|
||||
|
||||
strings.conversion = $scriptError; // Conversion of text to values (vectors, quaternions etc)
|
||||
strings.conversion.vector = inherit;
|
||||
strings.conversion.quaternion = inherit;
|
||||
|
@ -20,10 +20,12 @@
|
||||
<string>no</string>
|
||||
<key>$scriptError</key>
|
||||
<string>yes</string>
|
||||
<key>$shaderDebug</key>
|
||||
<string>no</string>
|
||||
<key>$shaderDebugOn</key>
|
||||
<string>no</string>
|
||||
<key>$shaderError</key>
|
||||
<string>$scriptError</string>
|
||||
<string>$error</string>
|
||||
<key>$soundDebug</key>
|
||||
<string>no</string>
|
||||
<key>$soundDebugVerbose</key>
|
||||
@ -84,6 +86,8 @@
|
||||
<string>$dataCacheDebug</string>
|
||||
<key>dataCache.upToDate</key>
|
||||
<string>$dataCacheStatus</string>
|
||||
<key>dataCache.willWrite</key>
|
||||
<string>no</string>
|
||||
<key>dataCache.write.buildPath.failed</key>
|
||||
<string>$dataCacheError</string>
|
||||
<key>dataCache.write.failed</key>
|
||||
@ -170,24 +174,8 @@
|
||||
<string>$error</string>
|
||||
<key>rendering.opengl.extensions</key>
|
||||
<string>$troubleShootingDump</string>
|
||||
<key>rendering.opengl.shader.init</key>
|
||||
<string>inherit</string>
|
||||
<key>rendering.opengl.shader.init.dump</key>
|
||||
<string>$troubleShootingDump</string>
|
||||
<key>rendering.opengl.shader.init.dump.shader</key>
|
||||
<string>inherit</string>
|
||||
<key>rendering.opengl.shader.init.dump.shaderInfo</key>
|
||||
<string>inherit</string>
|
||||
<key>rendering.opengl.shader.init.dump.texture</key>
|
||||
<string>inherit</string>
|
||||
<key>rendering.opengl.shader.init.failed</key>
|
||||
<string>$shaderError</string>
|
||||
<key>rendering.opengl.shader.init.success</key>
|
||||
<string>inherit</string>
|
||||
<key>rendering.opengl.shader.support</key>
|
||||
<string>$troubleShootingDump</string>
|
||||
<key>rendering.opengl.shader.texNameMissing</key>
|
||||
<string>$shaderError</string>
|
||||
<key>rendering.opengl.shader.uniform</key>
|
||||
<string>$shaderDebugOn</string>
|
||||
<key>rendering.opengl.stateDump</key>
|
||||
@ -326,6 +314,26 @@
|
||||
<string>$troubleShootingDump</string>
|
||||
<key>setup.ship.badEntry.subentities</key>
|
||||
<string>inherit</string>
|
||||
<key>shader.compile.fragment.failure</key>
|
||||
<string>$shaderError</string>
|
||||
<key>shader.compile.vertex.failure</key>
|
||||
<string>$shaderError</string>
|
||||
<key>shader.link.failure</key>
|
||||
<string>$shaderError</string>
|
||||
<key>shader.load.noShader</key>
|
||||
<string>$error</string>
|
||||
<key>shader.uniform</key>
|
||||
<string>$shaderDebug</string>
|
||||
<key>shader.uniform.badDescription</key>
|
||||
<string>inherit</string>
|
||||
<key>shader.uniform.bind.failed</key>
|
||||
<string>inherit</string>
|
||||
<key>shader.uniform.set</key>
|
||||
<string>inherit</string>
|
||||
<key>shader.uniform.unSet</key>
|
||||
<string>inherit</string>
|
||||
<key>shader.vessel.init</key>
|
||||
<string>$shaderDebug</string>
|
||||
<key>sound.channel.cleanup.failed</key>
|
||||
<string>$soundError</string>
|
||||
<key>sound.channel.cleanup.failed.badState</key>
|
||||
|
24
Resources/Config/material-defaults.plist
Normal file
24
Resources/Config/material-defaults.plist
Normal file
@ -0,0 +1,24 @@
|
||||
/* Settings for shader system.
|
||||
|
||||
While it is possible to override this in the usual fashion, it would not
|
||||
be a very good idea.
|
||||
*/
|
||||
|
||||
"ship-default-bindings" =
|
||||
{
|
||||
"engine_level" = { type = "binding"; value = "speedFactor"; };
|
||||
"laser_heat_level" = { type = "binding"; value = "laserHeatLevel"; clamped = "YES"; };
|
||||
"hull_heat_level" = { type = "binding"; value = "hullHeatLevel"; };
|
||||
"entity_personality" = { type = "binding"; value = "entityPersonality"; };
|
||||
"entity_personality_int" = { type = "binding"; value = "entityPersonalityInt"; };
|
||||
};
|
||||
|
||||
"ship-prefix-macros" =
|
||||
{
|
||||
"OO_ENGINE_LEVEL" = 1;
|
||||
"OO_ENTITY_PERSONALITY" = 1;
|
||||
"OO_ENTITY_PERSONALITY_INT" = 1;
|
||||
"OO_ENTITY_LASER_HEAT_LEVEL" = 1;
|
||||
"OO_HULL_HEAT_LEVEL" = 1;
|
||||
"OO_TIME" = 1;
|
||||
};
|
@ -256,7 +256,10 @@ static NSString * kOOLogKeyDown = @"input.keyMapping.keyPress.keyDown";
|
||||
|
||||
|
||||
// world's simplest OpenGL optimisations...
|
||||
#if GL_APPLE_transform_hint
|
||||
glHint(GL_TRANSFORM_HINT_APPLE, GL_FASTEST);
|
||||
#endif
|
||||
|
||||
glDisable(GL_NORMALIZE);
|
||||
glDisable(GL_RESCALE_NORMAL);
|
||||
|
||||
|
@ -140,8 +140,10 @@ extern int debug;
|
||||
isSunlit: 1,
|
||||
collisionTestFilter: 1,
|
||||
isSmoothShaded: 1,
|
||||
throw_sparks: 1,
|
||||
usingVAR: 1;
|
||||
#if GL_APPLE_vertex_array_object
|
||||
usingVAR: 1,
|
||||
#endif
|
||||
throw_sparks: 1;
|
||||
|
||||
OOScanClass scanClass;
|
||||
OOEntityStatus status;
|
||||
@ -217,8 +219,10 @@ extern int debug;
|
||||
GLuint texture_name[MAX_TEXTURES_PER_ENTITY];
|
||||
|
||||
// COMMON OGL STUFF
|
||||
#if GL_APPLE_vertex_array_object
|
||||
GLuint gVertexArrayRangeObjects[NUM_VERTEX_ARRAY_RANGES]; // OpenGL's VAR object references
|
||||
VertexArrayRangeType gVertexArrayRangeData[NUM_VERTEX_ARRAY_RANGES]; // our info about each VAR block
|
||||
#endif
|
||||
|
||||
OOWeakReference *weakSelf;
|
||||
}
|
||||
@ -340,13 +344,12 @@ extern int debug;
|
||||
- (void)dumpState; // General "describe situtation verbosely in log" command.
|
||||
- (void)dumpSelfState; // Subclasses should override this, not -dumpState, and call throught to super first.
|
||||
|
||||
#if GL_APPLE_vertex_array_object
|
||||
// COMMON OGL ROUTINES
|
||||
|
||||
- (BOOL) OGL_InitVAR;
|
||||
|
||||
- (void) OGL_AssignVARMemory:(long) size :(void *) data :(Byte) whichVAR;
|
||||
|
||||
- (void) OGL_UpdateVAR;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
|
@ -53,9 +53,11 @@ static NSString * const kOOLogEntityTooManyVertices = @"entity.loadMesh.error.
|
||||
static NSString * const kOOLogEntityTooManyFaces = @"entity.loadMesh.error.tooManyFaces";
|
||||
|
||||
|
||||
#if GL_APPLE_vertex_array_object
|
||||
// global flag for VAR
|
||||
BOOL global_usingVAR;
|
||||
BOOL global_testForVAR;
|
||||
#endif
|
||||
|
||||
|
||||
@interface Entity (Private)
|
||||
@ -827,11 +829,8 @@ BOOL global_testForVAR;
|
||||
if (immediate)
|
||||
{
|
||||
|
||||
#ifdef GNUSTEP
|
||||
// TODO: Find out what these APPLE functions can be replaced with
|
||||
#else
|
||||
if (usingVAR)
|
||||
glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
|
||||
#if GL_APPLE_vertex_array_object
|
||||
if (usingVAR) glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
|
||||
#endif
|
||||
|
||||
//
|
||||
@ -875,7 +874,7 @@ BOOL global_testForVAR;
|
||||
}
|
||||
else
|
||||
{
|
||||
OOLog(kOOLogFileNotLoaded, @"ERROR no basefile for entity %@");
|
||||
OOLog(kOOLogFileNotLoaded, @"ERROR no basefile for entity %@", self);
|
||||
}
|
||||
}
|
||||
if (!isSmoothShaded) glShadeModel(GL_SMOOTH);
|
||||
@ -963,10 +962,7 @@ BOOL global_testForVAR;
|
||||
{
|
||||
// roll out each face and texture in turn
|
||||
//
|
||||
int fi,ti ;
|
||||
|
||||
if (!UNIVERSE)
|
||||
return;
|
||||
int fi,ti;
|
||||
|
||||
for (fi = 0; fi < n_faces; fi++)
|
||||
{
|
||||
@ -2308,8 +2304,9 @@ BOOL global_testForVAR;
|
||||
}
|
||||
|
||||
|
||||
// COMMON OGL STUFF
|
||||
#if GL_APPLE_vertex_array_object
|
||||
|
||||
// COMMON OGL STUFF
|
||||
- (BOOL) OGL_InitVAR
|
||||
{
|
||||
short i;
|
||||
@ -2337,11 +2334,7 @@ BOOL global_testForVAR;
|
||||
|
||||
if (!global_usingVAR)
|
||||
return NO;
|
||||
#ifdef GNUSTEP
|
||||
// TODO: Find out what these APPLE functions do
|
||||
#else
|
||||
glGenVertexArraysAPPLE(NUM_VERTEX_ARRAY_RANGES, &gVertexArrayRangeObjects[0]);
|
||||
#endif
|
||||
|
||||
// INIT OUR DATA
|
||||
//
|
||||
@ -2393,9 +2386,6 @@ BOOL global_testForVAR;
|
||||
if (!gVertexArrayRangeData[i].forceUpdate)
|
||||
continue;
|
||||
|
||||
#ifdef GNUSTEP
|
||||
// TODO: find out what non-AAPL OpenGL stuff is equivalent
|
||||
#else
|
||||
// BIND THIS VAR OBJECT SO WE CAN DO STUFF TO IT
|
||||
|
||||
glBindVertexArrayAPPLE(gVertexArrayRangeObjects[i]);
|
||||
@ -2420,12 +2410,14 @@ BOOL global_testForVAR;
|
||||
{
|
||||
glFlushVertexArrayRangeAPPLE(size, gVertexArrayRangeData[i].dataBlockPtr);
|
||||
}
|
||||
#endif
|
||||
|
||||
gVertexArrayRangeData[i].forceUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// log a list of current states
|
||||
//
|
||||
// we need to report on the material properties
|
||||
|
@ -354,11 +354,16 @@ static OOCacheManager *sSingleton = nil;
|
||||
|
||||
if (caches == nil) return;
|
||||
|
||||
OOLog(@"dataCache.willWrite", @"About to write data cache."); // Added for 1.69 to detect possible write-related crash. -- Ahruman
|
||||
ooliteVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:kCacheKeyVersion];
|
||||
endianTag = [NSData dataWithBytes:&endianTagValue length:sizeof endianTagValue];
|
||||
formatVersion = [NSNumber numberWithUnsignedInt:kFormatVersionValue];
|
||||
pListRep = [self dictionaryOfCaches];
|
||||
if (ooliteVersion == nil || endianTag == nil || formatVersion == nil || pListRep == nil) return;
|
||||
if (ooliteVersion == nil || endianTag == nil || formatVersion == nil || pListRep == nil)
|
||||
{
|
||||
OOLog(@"dataCache.cantWrite", @"Failed to write data cache -- prerequisites not fulfilled. (This is an internal error, please report it.)");
|
||||
return;
|
||||
}
|
||||
|
||||
newCache = [NSMutableDictionary dictionaryWithCapacity:4];
|
||||
[newCache setObject:ooliteVersion forKey:kCacheKeyVersion];
|
||||
|
57
src/Core/OOMaterial.h
Normal file
57
src/Core/OOMaterial.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
|
||||
OOMaterial.h
|
||||
|
||||
A material which can be applied to an OpenGL object, or more accurately, to
|
||||
the current OpenGL render state.
|
||||
|
||||
This is an abstract class; actual materials should be subclasses.
|
||||
|
||||
Currently, only shader materials are supported. Direct use of textures should
|
||||
also be replaced with an OOMaterial subclass.
|
||||
|
||||
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 <Foundation/Foundation.h>
|
||||
#import "OOOpenGL.h"
|
||||
|
||||
|
||||
@interface OOMaterial: NSObject
|
||||
|
||||
// Make this the current material.
|
||||
- (void)apply;
|
||||
|
||||
// Make no material the current material, tearing down anything set up by the current material.
|
||||
+ (void)applyNone;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface OOMaterial (OOSubclassInterface)
|
||||
|
||||
// Subclass responsibilities - don't call directly.
|
||||
- (BOOL)doApply; // Override instead of -apply
|
||||
- (void)unapplyWithNext:(OOMaterial *)next;
|
||||
|
||||
// Call at top of dealloc
|
||||
- (void)willDealloc;
|
||||
|
||||
@end
|
75
src/Core/OOMaterial.m
Normal file
75
src/Core/OOMaterial.m
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
|
||||
OOMaterial.m
|
||||
|
||||
This is an abstract class; actual materials should be subclasses.
|
||||
|
||||
Currently, only shader materials are supported. Direct use of textures should
|
||||
also be replaced with an OOMaterial subclass.
|
||||
|
||||
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 "OOMaterial.h"
|
||||
|
||||
static OOMaterial *sActiveMaterial;
|
||||
|
||||
|
||||
@implementation OOMaterial
|
||||
|
||||
- (void)willDealloc
|
||||
{
|
||||
if (sActiveMaterial == self)
|
||||
{
|
||||
OOLog(@"shader.dealloc.imbalance", @"***** Material deallocated while active, indicating a retain/release imbalance. Expect imminent crash.");
|
||||
[self unapplyWithNext:nil];
|
||||
sActiveMaterial = nil;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Make this the current GL shader program.
|
||||
- (void)apply
|
||||
{
|
||||
[sActiveMaterial unapplyWithNext:self];
|
||||
[sActiveMaterial release];
|
||||
sActiveMaterial = nil;
|
||||
|
||||
if ([self doApply])
|
||||
{
|
||||
sActiveMaterial = [self retain];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+ (void)applyNone
|
||||
{
|
||||
[sActiveMaterial unapplyWithNext:nil];
|
||||
[sActiveMaterial release];
|
||||
sActiveMaterial = nil;
|
||||
}
|
||||
|
||||
|
||||
- (void)unapply
|
||||
{
|
||||
// Do nothing.
|
||||
}
|
||||
|
||||
@end
|
@ -24,7 +24,10 @@ MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef GNUSTEP
|
||||
#import "OOCocoa.h"
|
||||
|
||||
|
||||
#if OOLITE_MAC_OS_X
|
||||
|
||||
// Apple OpenGL includes...
|
||||
#include <OpenGL/OpenGL.h>
|
||||
@ -32,7 +35,11 @@ MA 02110-1301, USA.
|
||||
#include <OpenGL/glu.h>
|
||||
#include <OpenGL/glext.h>
|
||||
|
||||
#else
|
||||
typedef CGLContextObj OOOpenGLContext;
|
||||
#define OOOpenGLGetCurrentContext CGLGetCurrentContext
|
||||
#define OOOpenGLSetCurrentContext(ctx) (CGLSetCurrentContext(ctx) == kCGLNoError)
|
||||
|
||||
#elif OOLITE_SDL
|
||||
|
||||
// SDL OpenGL includes...
|
||||
|
||||
@ -45,7 +52,11 @@ MA 02110-1301, USA.
|
||||
// include an up-to-date version of glext.h
|
||||
#include <GL/glext.h>
|
||||
|
||||
// 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.
|
||||
|
||||
#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;
|
||||
@ -60,6 +71,25 @@ 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
|
||||
version, unfortunately.
|
||||
*/
|
||||
|
||||
typedef uintptr_t OOOpenGLContext; // Opaque context identifier
|
||||
// OOOpenGLContext OOOpenGLGetCurrentContext(void)
|
||||
#define OOOpenGLGetCurrentContext() ((OOOpenGLContextID)1UL)
|
||||
// BOOL OOOpenGLSetCurrentContext(OOOpenGLContext context)
|
||||
#define OOOpenGLSetCurrentContext(ctx) ((ctx) == 1UL)
|
||||
|
||||
|
||||
#else // Not OS X or SDL
|
||||
|
||||
#error OOOpenGL.h: unknown target!
|
||||
|
||||
#endif
|
||||
|
||||
|
103
src/Core/OOShaderMaterial.h
Normal file
103
src/Core/OOShaderMaterial.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
|
||||
OOShaderMaterial.h
|
||||
|
||||
Managers a combination of a shader program, textures and uniforms. Ought to be
|
||||
a subclass of a hypothetical OOMaterial.
|
||||
|
||||
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 "OOMaterial.h"
|
||||
#import "OOWeakReference.h"
|
||||
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
|
||||
@class OOShaderProgram;
|
||||
|
||||
|
||||
@interface OOShaderMaterial: OOMaterial
|
||||
{
|
||||
OOShaderProgram *shaderProgram;
|
||||
NSMutableDictionary *uniforms;
|
||||
GLuint *textures;
|
||||
GLuint texCount;
|
||||
}
|
||||
|
||||
/* Set up an OOShaderMaterial.
|
||||
|
||||
Configuration should be a dictionary equivalent to an entry in a
|
||||
shipdata.plist "shaders" dictionary. Specifically, keys OOShaderMaterial
|
||||
will look for are currently:
|
||||
textures array of texture file names.
|
||||
vertex_shader name of vertex shader file.
|
||||
glsl-vertex vertex shader source (if no vertex_shader).
|
||||
fragment_shader name of fragment shader file.
|
||||
glsl-fragment fragment shader source (if no fragment_shader).
|
||||
glsl fragment shader source (if no glsl-fragment).
|
||||
uniforms dictionary of uniforms. Values are either reals or
|
||||
dictionaries containing:
|
||||
type "int" or "float"
|
||||
value number
|
||||
|
||||
Macros is a dictionary which is converted to macro definitions and
|
||||
prepended to shader source code. It should be used to specify the
|
||||
availability if uniforms you tend to register, and other macros such as
|
||||
bug fix identifiers. For example, the
|
||||
dictionary:
|
||||
{ "OO_ENGINE_LEVEL" = 1; }
|
||||
|
||||
will be transformed into:
|
||||
#define OO_ENGINE_LEVEL 1
|
||||
*/
|
||||
+ (id)shaderWithConfiguration:(NSDictionary *)configuration macros:(NSDictionary *)macros bindingTarget:(id<OOWeakReferenceSupport>)object;
|
||||
- (id)initWithConfiguration:(NSDictionary *)configuration macros:(NSDictionary *)macros bindingTarget:(id<OOWeakReferenceSupport>)object;
|
||||
|
||||
/* Bind a uniform to a property of an object.
|
||||
|
||||
SelectorName should specify a method of source which returns the desired
|
||||
value; it will be called every time -apply is, assuming uniformName is
|
||||
used in the shader. (If not, OOShaderMaterial will not track the binding.)
|
||||
|
||||
A bound method must return a (signed or unsigned) char, short, int, long,
|
||||
float or double, and not take any parameters. It will be set as a (signed)
|
||||
int or a float as appropriate. TODO: support GLSL vector types, and
|
||||
binding of Vectors and Quaternions.
|
||||
*/
|
||||
- (void)bindUniform:(NSString *)uniformName
|
||||
toObject:(id<OOWeakReferenceSupport>)target
|
||||
property:(SEL)selector
|
||||
clamped:(BOOL)clamped;
|
||||
|
||||
/* Set a uniform value.
|
||||
*/
|
||||
- (void)setUniform:(NSString *)uniformName intValue:(int)value;
|
||||
- (void)setUniform:(NSString *)uniformName floatValue:(float)value;
|
||||
|
||||
/* Add constant uniforms. Same format as uniforms dictionary of configuration
|
||||
parameter to -initWithConfiguration:macros:. The target parameter is used
|
||||
for bindings.
|
||||
*/
|
||||
-(void)addUniformsFromDictionary:(NSDictionary *)uniformDefs withBindingTarget:(id<OOWeakReferenceSupport>)target;
|
||||
|
||||
@end
|
||||
|
||||
#endif // NO_SHADERS
|
380
src/Core/OOShaderMaterial.m
Normal file
380
src/Core/OOShaderMaterial.m
Normal file
@ -0,0 +1,380 @@
|
||||
/*
|
||||
|
||||
OOShaderMaterial.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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
|
||||
#import "OOShaderMaterial.h"
|
||||
#import "OOShaderUniform.h"
|
||||
#import "OOFunctionAttributes.h"
|
||||
#import "OOCollectionExtractors.h"
|
||||
#import "OOShaderProgram.h"
|
||||
#import "TextureStore.h"
|
||||
|
||||
|
||||
static NSString *MacrosToString(NSDictionary *macros);
|
||||
|
||||
|
||||
@interface OOShaderMaterial (OOPrivate)
|
||||
|
||||
- (void)addTexturesFromArray:(NSArray *)textureNames unitCount:(GLint)max;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOShaderMaterial
|
||||
|
||||
+ (id)shaderWithConfiguration:(NSDictionary *)configuration macros:(NSDictionary *)macros bindingTarget:(id<OOWeakReferenceSupport>)target
|
||||
{
|
||||
return [[[self alloc] initWithConfiguration:configuration macros:macros bindingTarget:target] autorelease];
|
||||
}
|
||||
|
||||
|
||||
- (id)initWithConfiguration:(NSDictionary *)configuration macros:(NSDictionary *)macros bindingTarget:(id<OOWeakReferenceSupport>)target
|
||||
{
|
||||
BOOL OK = YES;
|
||||
NSDictionary *uniformDefs = nil;
|
||||
NSArray *textureDefs = nil;
|
||||
NSString *macroString = nil;
|
||||
NSString *vertexShader = nil;
|
||||
NSString *fragmentShader = nil;
|
||||
GLint textureUnits;
|
||||
NSMutableDictionary *modifiedMacros = nil;
|
||||
|
||||
if (configuration == nil) OK = NO;
|
||||
|
||||
self = [super init];
|
||||
if (self == nil) OK = NO;
|
||||
|
||||
if (OK && configuration == nil) OK = NO;
|
||||
if (OK)
|
||||
{
|
||||
modifiedMacros = macros ? [macros mutableCopy] : [[NSMutableDictionary alloc] init];
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &textureUnits);
|
||||
[modifiedMacros setObject:[NSNumber numberWithInt:textureUnits] forKey:@"OO_TEXTURE_UNIT_COUNT"];
|
||||
|
||||
macroString = MacrosToString(modifiedMacros);
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
vertexShader = [configuration stringForKey:@"vertex_shader" defaultValue:nil];
|
||||
fragmentShader = [configuration stringForKey:@"fragment_shader" defaultValue:nil];
|
||||
|
||||
if (vertexShader != nil || fragmentShader != nil)
|
||||
{
|
||||
// If either shader is in an external file, use external-file-based shader (more efficient due to instance sharing)
|
||||
shaderProgram = [OOShaderProgram shaderProgramWithVertexShaderName:vertexShader fragmentShaderName:fragmentShader prefix:macroString];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, look for inline source
|
||||
vertexShader = [configuration stringForKey:@"glsl-vertex" defaultValue:nil];
|
||||
fragmentShader = [configuration stringForKey:@"glsl-fragment" defaultValue:nil];
|
||||
if (fragmentShader == nil) fragmentShader = [configuration stringForKey:@"glsl" defaultValue:nil];
|
||||
|
||||
if (vertexShader != nil || fragmentShader != nil)
|
||||
{
|
||||
shaderProgram = [OOShaderProgram shaderProgramWithVertexShaderSource:vertexShader fragmentShaderSource:fragmentShader prefix:macroString];
|
||||
}
|
||||
else
|
||||
{
|
||||
OOLog(@"shader.load.noShader", @"***** Error: no vertex or fragment shader specified specified in shader dictionary:\n%@", configuration);
|
||||
}
|
||||
}
|
||||
|
||||
OK = (shaderProgram != nil);
|
||||
if (OK) [shaderProgram retain];
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
// Load uniforms
|
||||
uniformDefs = [configuration dictionaryForKey:@"uniforms" defaultValue:nil];
|
||||
textureDefs = [configuration arrayForKey:@"textures" defaultValue:nil];
|
||||
|
||||
uniforms = [[NSMutableDictionary alloc] initWithCapacity:[uniformDefs count] + [textureDefs count]];
|
||||
[self addUniformsFromDictionary:uniformDefs withBindingTarget:target];
|
||||
|
||||
// ...and textures, which are a flavour of uniform four our purpose.
|
||||
[self addTexturesFromArray:textureDefs unitCount:textureUnits];
|
||||
}
|
||||
|
||||
if (!OK)
|
||||
{
|
||||
[self release];
|
||||
self = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self willDealloc];
|
||||
|
||||
[shaderProgram release];
|
||||
[uniforms release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (void)bindUniform:(NSString *)uniformName
|
||||
toObject:(id<OOWeakReferenceSupport>)source
|
||||
property:(SEL)selector
|
||||
clamped:(BOOL)clamped
|
||||
{
|
||||
OOShaderUniform *uniform = nil;
|
||||
|
||||
if (uniformName == nil) return;
|
||||
|
||||
uniform = [[OOShaderUniform alloc] initWithName:uniformName shaderProgram:shaderProgram boundToObject:source property:selector clamped:clamped];
|
||||
if (uniform != nil)
|
||||
{
|
||||
OOLog(@"shader.uniform.set", @"Set up uniform %@", uniform);
|
||||
[uniforms setObject:uniform forKey:uniformName];
|
||||
[uniform release];
|
||||
}
|
||||
else
|
||||
{
|
||||
OOLog(@"shader.uniform.unSet", @"Did not set uniform \"%@\"", uniformName);
|
||||
[uniforms removeObjectForKey:uniformName];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)setUniform:(NSString *)uniformName intValue:(int)value
|
||||
{
|
||||
OOShaderUniform *uniform = nil;
|
||||
|
||||
if (uniformName == nil) return;
|
||||
|
||||
uniform = [[OOShaderUniform alloc] initWithName:uniformName shaderProgram:shaderProgram intValue:value];
|
||||
if (uniform != nil)
|
||||
{
|
||||
OOLog(@"shader.uniform.set", @"Set up uniform %@", uniform);
|
||||
[uniforms setObject:uniform forKey:uniformName];
|
||||
[uniform release];
|
||||
}
|
||||
else
|
||||
{
|
||||
OOLog(@"shader.uniform.unSet", @"Did not set uniform \"%@\"", uniformName);
|
||||
[uniforms removeObjectForKey:uniformName];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)setUniform:(NSString *)uniformName floatValue:(float)value
|
||||
{
|
||||
OOShaderUniform *uniform = nil;
|
||||
|
||||
if (uniformName == nil) return;
|
||||
|
||||
uniform = [[OOShaderUniform alloc] initWithName:uniformName shaderProgram:shaderProgram floatValue:value];
|
||||
if (uniform != nil)
|
||||
{
|
||||
OOLog(@"shader.uniform.set", @"Set up uniform %@", uniform);
|
||||
[uniforms setObject:uniform forKey:uniformName];
|
||||
[uniform release];
|
||||
}
|
||||
else
|
||||
{
|
||||
OOLog(@"shader.uniform.unSet", @"Did not set uniform \"%@\"", uniformName);
|
||||
[uniforms removeObjectForKey:uniformName];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-(void)addUniformsFromDictionary:(NSDictionary *)uniformDefs withBindingTarget:(id<OOWeakReferenceSupport>)target
|
||||
{
|
||||
NSEnumerator *uniformEnum = nil;
|
||||
NSString *name = nil;
|
||||
id definition = nil;
|
||||
id value = nil;
|
||||
NSString *type = nil;
|
||||
GLfloat floatValue;
|
||||
BOOL gotValue;
|
||||
OOShaderUniform *uniform = nil;
|
||||
BOOL clamped;
|
||||
SEL selector = NULL;
|
||||
|
||||
for (uniformEnum = [uniformDefs keyEnumerator]; (name = [uniformEnum nextObject]); )
|
||||
{
|
||||
uniform = nil;
|
||||
definition = [uniformDefs objectForKey:name];
|
||||
|
||||
if ([definition isKindOfClass:[NSDictionary class]])
|
||||
{
|
||||
value = [definition objectForKey:@"value"];
|
||||
type = [definition objectForKey:@"type"];
|
||||
}
|
||||
else
|
||||
{
|
||||
value = definition;
|
||||
type = @"float";
|
||||
}
|
||||
|
||||
if ([type isEqualToString:@"float"])
|
||||
{
|
||||
gotValue = YES;
|
||||
if ([value respondsToSelector:@selector(floatValue)]) floatValue = [value floatValue];
|
||||
else if ([value respondsToSelector:@selector(doubleValue)]) floatValue = [value doubleValue];
|
||||
else if ([value respondsToSelector:@selector(intValue)]) floatValue = [value intValue];
|
||||
else gotValue = NO;
|
||||
|
||||
if (gotValue)
|
||||
{
|
||||
[self setUniform:name floatValue:floatValue];
|
||||
}
|
||||
}
|
||||
else if ([type isEqualToString:@"int"])
|
||||
{
|
||||
if ([value respondsToSelector:@selector(intValue)])
|
||||
{
|
||||
gotValue = YES;
|
||||
[self setUniform:name intValue:[value intValue]];
|
||||
}
|
||||
else gotValue = NO;
|
||||
}
|
||||
else if (target != nil && [type isEqualToString:@"binding"])
|
||||
{
|
||||
selector = NSSelectorFromString(value);
|
||||
if (selector)
|
||||
{
|
||||
gotValue = YES;
|
||||
clamped = [definition boolForKey:@"clamped" defaultValue:NO];
|
||||
[self bindUniform:name toObject:target property:selector clamped:clamped];
|
||||
}
|
||||
else gotValue = NO;
|
||||
}
|
||||
|
||||
if (!gotValue)
|
||||
{
|
||||
OOLog(@"shader.uniform.badDescription", @"----- Warning: could not bind uniform \"%@\" -- could not interpret definition:\n", name, definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)doApply
|
||||
{
|
||||
NSEnumerator *uniformEnum = nil;
|
||||
OOShaderUniform *uniform = nil;
|
||||
GLint i;
|
||||
|
||||
[shaderProgram apply];
|
||||
|
||||
for (i = 0; i != texCount; ++i)
|
||||
{
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + i);
|
||||
glBindTexture(GL_TEXTURE_2D, textures[i]);
|
||||
}
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
|
||||
NS_DURING
|
||||
for (uniformEnum = [uniforms objectEnumerator]; (uniform = [uniformEnum nextObject]); )
|
||||
{
|
||||
[uniform apply];
|
||||
}
|
||||
NS_HANDLER
|
||||
/* Supress exceptions during application of bound uniforms. We use a
|
||||
single exception handler around all uniforms because ObjC
|
||||
exceptions have some overhead.
|
||||
*/
|
||||
NS_ENDHANDLER
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (void)unapplyWithNext:(OOMaterial *)next
|
||||
{
|
||||
if (![next isKindOfClass:[OOShaderMaterial class]]) // Avoid redundant state change
|
||||
{
|
||||
[OOShaderProgram applyNone];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOShaderMaterial (OOPrivate)
|
||||
|
||||
- (void)addTexturesFromArray:(NSArray *)textureNames unitCount:(GLint)max
|
||||
{
|
||||
NSString *name = nil;
|
||||
unsigned i = 0;
|
||||
|
||||
// Allocate space for texture object name array
|
||||
texCount = MAX(MIN(max, [textureNames count]), 0);
|
||||
if (texCount == 0) return;
|
||||
|
||||
textures = malloc(texCount * sizeof *textures);
|
||||
if (textures == NULL)
|
||||
{
|
||||
texCount = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up texture object names and appropriate uniforms
|
||||
for (i = 0; i != texCount; ++i)
|
||||
{
|
||||
[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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
static NSString *MacrosToString(NSDictionary *macros)
|
||||
{
|
||||
NSMutableString *result = nil;
|
||||
NSEnumerator *macroEnum = nil;
|
||||
id key = nil, value = nil;
|
||||
|
||||
if (macros == nil) return nil;
|
||||
|
||||
result = [NSMutableString string];
|
||||
for (macroEnum = [macros keyEnumerator]; (key = [macroEnum nextObject]); )
|
||||
{
|
||||
if (![key isKindOfClass:[NSString class]]) continue;
|
||||
value = [macros objectForKey:key];
|
||||
|
||||
[result appendFormat:@"#define %@ %@\n", key, value];
|
||||
}
|
||||
|
||||
if ([result length] == 0) return nil;
|
||||
[result appendString:@"\n\n"];
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // NO_SHADERS
|
61
src/Core/OOShaderProgram.h
Normal file
61
src/Core/OOShaderProgram.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
|
||||
OOShaderProgram.h
|
||||
|
||||
Encapsulates a vertex + fragment shader combo. In general, this should only be
|
||||
used though OOShaderMaterial. The point of this separation is that more than
|
||||
one OOShaderMaterial can use the same OOShaderProgram (as long as the shaders
|
||||
are defined in external files, not strings).
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "OOOpenGL.h"
|
||||
|
||||
|
||||
@interface OOShaderProgram: NSObject
|
||||
{
|
||||
GLhandleARB program;
|
||||
GLhandleARB vertexShader;
|
||||
GLhandleARB fragmentShader;
|
||||
NSString *key;
|
||||
}
|
||||
|
||||
// Loads a shader from a file, caching and sharing shader program instances.
|
||||
+ (id)shaderProgramWithVertexShaderName:(NSString *)vertexShaderName
|
||||
fragmentShaderName:(NSString *)fragmentShaderName
|
||||
prefix:(NSString *)prefixString;
|
||||
|
||||
// Loads a shader from memory, always generating a new instance.
|
||||
+ (id)shaderProgramWithVertexShaderSource:(NSString *)vertexShaderSource
|
||||
fragmentShaderSource:(NSString *)fragmentShaderSource
|
||||
prefix:(NSString *)prefixString;
|
||||
|
||||
- (void)apply;
|
||||
+ (void)applyNone;
|
||||
|
||||
- (GLhandleARB)program;
|
||||
|
||||
@end
|
||||
|
||||
#endif // NO_SHADERS
|
313
src/Core/OOShaderProgram.m
Normal file
313
src/Core/OOShaderProgram.m
Normal file
@ -0,0 +1,313 @@
|
||||
/*
|
||||
|
||||
OOShaderProgram.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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
|
||||
#import "OOShaderProgram.h"
|
||||
#import "OOFunctionAttributes.h"
|
||||
#import "OOStringParsing.h"
|
||||
#import "ResourceManager.h"
|
||||
|
||||
|
||||
static NSMutableDictionary *sShaderCache = nil;
|
||||
static OOShaderProgram *sActiveProgram = nil;
|
||||
|
||||
|
||||
static BOOL GetShaderSource(NSString *fileName, NSString *shaderType, NSString *prefix, NSString **outResult);
|
||||
static NSString *GetGLSLInfoLog(GLhandleARB shaderObject);
|
||||
|
||||
|
||||
@interface OOShaderProgram (OOPrivate)
|
||||
|
||||
- (id)initWithVertexShaderSource:(NSString *)vertexSource fragmentShaderSource:(NSString *)fragmentSource key:(NSString *)key;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOShaderProgram
|
||||
|
||||
+ (id)shaderProgramWithVertexShaderName:(NSString *)vertexShaderName
|
||||
fragmentShaderName:(NSString *)fragmentShaderName
|
||||
prefix:(NSString *)prefixString
|
||||
{
|
||||
NSString *key = nil;
|
||||
OOShaderProgram *program = nil;
|
||||
NSString *vertexSource = nil;
|
||||
NSString *fragmentSource = nil;
|
||||
|
||||
if ([prefixString length] == 0) prefixString = nil;
|
||||
|
||||
// Use cache to avoid creating duplicate shader programs -- saves on GPU resources and potentially state changes.
|
||||
key = [NSString stringWithFormat:@"vertex:%@\nfragment:%@\n----\n%@", vertexShaderName, fragmentShaderName, prefixString ?: @""];
|
||||
program = [[sShaderCache objectForKey:key] pointerValue];
|
||||
|
||||
if (program == nil)
|
||||
{
|
||||
// No cached program; create one...
|
||||
if (!GetShaderSource(vertexShaderName, @"vertex", prefixString, &vertexSource)) return nil;
|
||||
if (!GetShaderSource(fragmentShaderName, @"fragment", prefixString, &fragmentSource)) return nil;
|
||||
program = [[OOShaderProgram alloc] initWithVertexShaderSource:vertexSource fragmentShaderSource:fragmentSource key:key];
|
||||
|
||||
if (program != nil)
|
||||
{
|
||||
// ...and add it to the cache
|
||||
[program autorelease];
|
||||
if (sShaderCache == nil) sShaderCache = [[NSMutableDictionary alloc] init];
|
||||
[sShaderCache setObject:[NSValue valueWithPointer:program] forKey:key]; // Use NSValue so dictionary doesn't retain program
|
||||
}
|
||||
}
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
|
||||
+ (id)shaderProgramWithVertexShaderSource:(NSString *)vertexShaderSource
|
||||
fragmentShaderSource:(NSString *)fragmentShaderSource
|
||||
prefix:(NSString *)prefixString
|
||||
{
|
||||
if (prefixString != nil)
|
||||
{
|
||||
if (vertexShaderSource != nil) vertexShaderSource = [prefixString stringByAppendingString:vertexShaderSource];
|
||||
if (fragmentShaderSource != nil) fragmentShaderSource = [prefixString stringByAppendingString:fragmentShaderSource];
|
||||
}
|
||||
|
||||
return [[[self alloc] initWithVertexShaderSource:vertexShaderSource fragmentShaderSource:fragmentShaderSource key:nil] autorelease];
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
if (EXPECT_NOT(sActiveProgram == self))
|
||||
{
|
||||
OOLog(@"shader.dealloc.imbalance", @"***** OOShaderProgram deallocated while active, indicating a retain/release imbalance. Expect imminent crash.");
|
||||
[OOShaderProgram applyNone];
|
||||
}
|
||||
|
||||
if (key != nil)
|
||||
{
|
||||
[sShaderCache removeObjectForKey:key];
|
||||
[key release];
|
||||
}
|
||||
|
||||
glDeleteObjectARB(program);
|
||||
glDeleteObjectARB(vertexShader);
|
||||
glDeleteObjectARB(fragmentShader);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (void)apply
|
||||
{
|
||||
if (sActiveProgram != self)
|
||||
{
|
||||
[sActiveProgram release];
|
||||
sActiveProgram = [self retain];
|
||||
glUseProgramObjectARB(program);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+ (void)applyNone
|
||||
{
|
||||
if (sActiveProgram != nil)
|
||||
{
|
||||
[sActiveProgram release];
|
||||
sActiveProgram = nil;
|
||||
glUseProgramObjectARB(NULL_SHADER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (GLhandleARB)program
|
||||
{
|
||||
return program;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOShaderProgram (OOPrivate)
|
||||
|
||||
- (id)initWithVertexShaderSource:(NSString *)vertexSource fragmentShaderSource:(NSString *)fragmentSource key:(NSString *)inKey
|
||||
{
|
||||
BOOL OK = YES;
|
||||
const GLcharARB *sourceString = nil;
|
||||
GLint compileStatus;
|
||||
|
||||
self = [super init];
|
||||
if (self == nil) OK = NO;
|
||||
|
||||
if (OK && vertexSource == nil && fragmentSource == nil) OK = NO; // Must have at least one shader!
|
||||
|
||||
if (OK && vertexSource != nil)
|
||||
{
|
||||
// Compile vertex shader.
|
||||
vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
|
||||
if (vertexShader != NULL_SHADER)
|
||||
{
|
||||
sourceString = [vertexSource lossyCString];
|
||||
glShaderSourceARB(vertexShader, 1, &sourceString, NULL);
|
||||
glCompileShaderARB(vertexShader);
|
||||
|
||||
glGetObjectParameterivARB(vertexShader, GL_OBJECT_COMPILE_STATUS_ARB, &compileStatus);
|
||||
if (compileStatus != GL_TRUE)
|
||||
{
|
||||
OOLog(@"shader.compile.vertex.failure", @"***** GLSL %s shader compilation failed:\n>>>>> GLSL log:\n%@\n\n>>>>> GLSL source code:\n%@\n", "vertex", GetGLSLInfoLog(vertexShader), vertexSource);
|
||||
OK = NO;
|
||||
}
|
||||
}
|
||||
else OK = NO;
|
||||
}
|
||||
|
||||
if (OK && fragmentSource != nil)
|
||||
{
|
||||
// Compile fragment shader.
|
||||
fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
|
||||
if (fragmentShader != NULL_SHADER)
|
||||
{
|
||||
sourceString = [fragmentSource lossyCString];
|
||||
glShaderSourceARB(fragmentShader, 1, &sourceString, NULL);
|
||||
glCompileShaderARB(fragmentShader);
|
||||
|
||||
glGetObjectParameterivARB(fragmentShader, GL_OBJECT_COMPILE_STATUS_ARB, &compileStatus);
|
||||
if (compileStatus != GL_TRUE)
|
||||
{
|
||||
OOLog(@"shader.compile.fragment.failure", @"***** GLSL %s shader compilation failed:\n>>>>> GLSL log:\n%@\n\n>>>>> GLSL source code:\n%@\n", "fragment", GetGLSLInfoLog(fragmentShader), fragmentSource);
|
||||
OK = NO;
|
||||
}
|
||||
}
|
||||
else OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
// Link shader.
|
||||
program = glCreateProgramObjectARB();
|
||||
if (program != NULL_SHADER)
|
||||
{
|
||||
if (vertexShader != NULL_SHADER) glAttachObjectARB(program, vertexShader);
|
||||
if (fragmentShader != NULL_SHADER) glAttachObjectARB(program, fragmentShader);
|
||||
glLinkProgramARB(program);
|
||||
|
||||
glGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &compileStatus);
|
||||
if (compileStatus != GL_TRUE)
|
||||
{
|
||||
OOLog(@"shader.link.failure", @"***** GLSL shader linking failed:\n>>>>> GLSL log:\n%@\n", GetGLSLInfoLog(program));
|
||||
OK = NO;
|
||||
}
|
||||
}
|
||||
else OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
key = [inKey copy];
|
||||
}
|
||||
|
||||
if (!OK)
|
||||
{
|
||||
if (vertexShader) glDeleteObjectARB(vertexShader);
|
||||
if (fragmentShader) glDeleteObjectARB(fragmentShader);
|
||||
if (program) glDeleteObjectARB(program);
|
||||
|
||||
[self release];
|
||||
self = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/* Attempt to load fragment or vertex shader source from a file.
|
||||
Returns YES if source was loaded or no shader was specified, and NO if an
|
||||
external shader was specified but could not be found.
|
||||
*/
|
||||
static BOOL GetShaderSource(NSString *fileName, NSString *shaderType, NSString *prefix, NSString **outResult)
|
||||
{
|
||||
NSString *result = nil;
|
||||
NSString *shaderName = nil;
|
||||
NSArray *extensions = nil;
|
||||
NSEnumerator *extEnum = nil;
|
||||
NSString *extension = nil;
|
||||
NSString *nameWithExtension = nil;
|
||||
|
||||
result = [ResourceManager stringFromFilesNamed:fileName inFolder:@"Shaders"];
|
||||
if (result == nil)
|
||||
{
|
||||
extensions = [NSArray arrayWithObjects:shaderType, [shaderType substringToIndex:4], nil]; // vertex and vert, or fragment and frag
|
||||
|
||||
// Futureproofing -- in future, we may wish to support automatic selection between supported shader languages.
|
||||
if (![shaderName pathHasExtensionInArray:extensions])
|
||||
{
|
||||
for (extEnum = [extensions objectEnumerator]; (extension = [extEnum nextObject]); )
|
||||
{
|
||||
nameWithExtension = [fileName stringByAppendingPathExtension:extension];
|
||||
result = [ResourceManager stringFromFilesNamed:nameWithExtension
|
||||
inFolder:@"Shaders"];
|
||||
if (result != nil) break;
|
||||
}
|
||||
}
|
||||
if (result == nil)
|
||||
{
|
||||
OOLog(kOOLogFileNotFound, @"GLSL ERROR: failed to find fragment program %@.", shaderName);
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (result != nil && prefix != nil)
|
||||
{
|
||||
result = [prefix stringByAppendingString:result];
|
||||
}
|
||||
|
||||
if (outResult != NULL) *outResult = result;
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
static NSString *GetGLSLInfoLog(GLhandleARB shaderObject)
|
||||
{
|
||||
GLint length;
|
||||
GLcharARB *log = nil;
|
||||
NSString *result = nil;
|
||||
|
||||
if (shaderObject == NULL_SHADER) return nil;
|
||||
|
||||
glGetObjectParameterivARB(shaderObject, GL_OBJECT_INFO_LOG_LENGTH_ARB, &length);
|
||||
log = malloc(length);
|
||||
if (log == NULL)
|
||||
{
|
||||
length = 1024;
|
||||
log = malloc(length);
|
||||
if (log == NULL) return @"<out of memory>";
|
||||
}
|
||||
glGetInfoLogARB(shaderObject, length, NULL, log);
|
||||
|
||||
result = [NSString stringWithUTF8String:log];
|
||||
if (result == nil) result = [[[NSString alloc] initWithBytes:log length:length - 1 encoding:NSISOLatin1StringEncoding] autorelease];
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // NO_SHADERS
|
60
src/Core/OOShaderUniform.h
Normal file
60
src/Core/OOShaderUniform.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
|
||||
OOShaderUniform.h
|
||||
|
||||
Manages a uniform variable for OOShaderMaterial.
|
||||
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
|
||||
#import "OOShaderMaterial.h"
|
||||
|
||||
|
||||
@interface OOShaderUniform: NSObject
|
||||
{
|
||||
NSString *name;
|
||||
GLint location;
|
||||
BOOL isBinding;
|
||||
uint8_t type;
|
||||
union
|
||||
{
|
||||
GLint constInt;
|
||||
GLfloat constFloat;
|
||||
struct
|
||||
{
|
||||
OOWeakReference *object;
|
||||
SEL selector;
|
||||
IMP method;
|
||||
BOOL clamped;
|
||||
} binding;
|
||||
} value;
|
||||
}
|
||||
|
||||
- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram intValue:(int)constValue;
|
||||
- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram floatValue:(int)constValue;
|
||||
- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram boundToObject:(id<OOWeakReferenceSupport>)source property:(SEL)selector clamped:(BOOL)clamped;
|
||||
|
||||
- (void)apply;
|
||||
|
||||
@end
|
||||
|
||||
#endif // NO_SHADERS
|
394
src/Core/OOShaderUniform.m
Normal file
394
src/Core/OOShaderUniform.m
Normal file
@ -0,0 +1,394 @@
|
||||
/*
|
||||
|
||||
OOShaderUniform.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.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
|
||||
#import "OOShaderUniform.h"
|
||||
#import "OOShaderProgram.h"
|
||||
#import "OOFunctionAttributes.h"
|
||||
#import <string.h>
|
||||
#import "OOMaths.h"
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
kOOShaderUniformTypeChar,
|
||||
kOOShaderUniformTypeShort,
|
||||
kOOShaderUniformTypeInt,
|
||||
kOOShaderUniformTypeLong,
|
||||
kOOShaderUniformTypeFloat,
|
||||
kOOShaderUniformTypeDouble
|
||||
// Vector and matrix types may be added in future.
|
||||
} OOShaderUniformType;
|
||||
|
||||
|
||||
typedef char (*CharReturnMsgSend)(id, SEL);
|
||||
typedef short (*ShortReturnMsgSend)(id, SEL);
|
||||
typedef int (*IntReturnMsgSend)(id, SEL);
|
||||
typedef long (*LongReturnMsgSend)(id, SEL);
|
||||
typedef float (*FloatReturnMsgSend)(id, SEL);
|
||||
typedef double (*DoubleReturnMsgSend)(id, SEL);
|
||||
|
||||
|
||||
OOINLINE BOOL ValidBindingType(OOShaderUniformType type)
|
||||
{
|
||||
return kOOShaderUniformTypeInt <= type && type <= kOOShaderUniformTypeDouble;
|
||||
}
|
||||
|
||||
|
||||
@interface OOShaderUniform (OOPrivate)
|
||||
|
||||
- (void)applySimple;
|
||||
- (void)applyBinding;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOShaderUniform
|
||||
|
||||
- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram intValue:(int)constValue
|
||||
{
|
||||
BOOL OK = YES;
|
||||
|
||||
if (EXPECT_NOT(uniformName == NULL || shaderProgram == NULL)) OK = NO;
|
||||
|
||||
if (OK)
|
||||
{
|
||||
self = [super init];
|
||||
if (self == nil) OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
location = glGetUniformLocationARB([shaderProgram program], [uniformName lossyCString]);
|
||||
if (location == -1) OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
name = [uniformName retain];
|
||||
type = kOOShaderUniformTypeInt;
|
||||
value.constInt = constValue;
|
||||
}
|
||||
|
||||
if (!OK)
|
||||
{
|
||||
[self release];
|
||||
self = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram floatValue:(int)constValue
|
||||
{
|
||||
BOOL OK = YES;
|
||||
|
||||
if (EXPECT_NOT(uniformName == NULL || shaderProgram == NULL)) OK = NO;
|
||||
|
||||
if (OK)
|
||||
{
|
||||
self = [super init];
|
||||
if (self == nil) OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
location = glGetUniformLocationARB([shaderProgram program], [uniformName lossyCString]);
|
||||
if (location == -1) OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
name = [uniformName retain];
|
||||
type = kOOShaderUniformTypeFloat;
|
||||
value.constFloat = constValue;
|
||||
}
|
||||
|
||||
if (!OK)
|
||||
{
|
||||
[self release];
|
||||
self = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (id)initWithName:(NSString *)uniformName shaderProgram:(OOShaderProgram *)shaderProgram boundToObject:(id<OOWeakReferenceSupport>)source property:(SEL)selector clamped:(BOOL)clamped
|
||||
{
|
||||
BOOL OK = YES;
|
||||
NSMethodSignature *sig = nil;
|
||||
unsigned argCount;
|
||||
NSString *methodProblem = nil;
|
||||
const char *typeCode = nil;
|
||||
|
||||
if (EXPECT_NOT(uniformName == NULL || shaderProgram == NULL || source == nil || selector == NULL)) OK = NO;
|
||||
|
||||
if (OK)
|
||||
{
|
||||
self = [super init];
|
||||
if (self == nil) OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
location = glGetUniformLocationARB([shaderProgram program], [uniformName lossyCString]);
|
||||
if (location == -1) OK = NO;
|
||||
}
|
||||
|
||||
// Check to see if it's a valid method.
|
||||
if (OK)
|
||||
{
|
||||
if (![source respondsToSelector:selector])
|
||||
{
|
||||
methodProblem = @"target does not respond to selector";
|
||||
OK = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
value.binding.method = [(id)source methodForSelector:selector];
|
||||
if (value.binding.method == NULL)
|
||||
{
|
||||
methodProblem = @"could not retrieve method implementation";
|
||||
OK = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
sig = [(id)source methodSignatureForSelector:selector];
|
||||
if (sig == nil)
|
||||
{
|
||||
methodProblem = @"could not retrieve method signature";
|
||||
OK = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
argCount = [sig numberOfArguments];
|
||||
if (argCount != 2) // "no-arguments" methods actually take two arguments, self and _msg.
|
||||
{
|
||||
methodProblem = @"only methods which do not require arguments may be bound to";
|
||||
OK = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
typeCode = [sig methodReturnType];
|
||||
if (0 == strcmp("f", typeCode)) type = kOOShaderUniformTypeFloat;
|
||||
else if (0 == strcmp("d", typeCode)) type = kOOShaderUniformTypeDouble;
|
||||
else if (0 == strcmp("c", typeCode) || 0 == strcmp("C", typeCode)) type = kOOShaderUniformTypeChar; // Signed or unsigned
|
||||
else if (0 == strcmp("s", typeCode) || 0 == strcmp("S", typeCode)) type = kOOShaderUniformTypeShort;
|
||||
else if (0 == strcmp("i", typeCode) || 0 == strcmp("I", typeCode)) type = kOOShaderUniformTypeInt;
|
||||
else if (0 == strcmp("l", typeCode) || 0 == strcmp("L", typeCode)) type = kOOShaderUniformTypeLong;
|
||||
else
|
||||
{
|
||||
methodProblem = [NSString stringWithFormat:@"unsupported type \"%s\"", typeCode];
|
||||
}
|
||||
}
|
||||
|
||||
// If we're still OK, it's a bindable method.
|
||||
if (OK)
|
||||
{
|
||||
name = [uniformName retain];
|
||||
isBinding = YES;
|
||||
value.binding.object = [source weakRetain];
|
||||
value.binding.selector = selector;
|
||||
value.binding.clamped = clamped;
|
||||
}
|
||||
|
||||
if (!OK)
|
||||
{
|
||||
if (methodProblem != nil)
|
||||
{
|
||||
OOLog(@"shader.uniform.bind.failed", @"***** Shader error: could not bind uniform \"%@\" to -[%@ %s] (%@).", uniformName, [source class], selector, methodProblem);
|
||||
}
|
||||
|
||||
[self release];
|
||||
self = nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[name release];
|
||||
if (isBinding) [value.binding.object release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
NSString *valueDesc = nil;
|
||||
NSString *valueType = nil;
|
||||
id object;
|
||||
|
||||
if (isBinding)
|
||||
{
|
||||
object = [value.binding.object weakRefUnderlyingObject];
|
||||
if (object != nil)
|
||||
{
|
||||
valueDesc = [NSString stringWithFormat:@"[<%@ %p> %@]", [object class], value.binding.object, NSStringFromSelector(value.binding.selector)];
|
||||
}
|
||||
else
|
||||
{
|
||||
valueDesc = @"0";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case kOOShaderUniformTypeInt:
|
||||
valueDesc = [NSString stringWithFormat:@"%i", value.constInt];
|
||||
break;
|
||||
|
||||
case kOOShaderUniformTypeFloat:
|
||||
valueDesc = [NSString stringWithFormat:@"%g", value.constFloat];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case kOOShaderUniformTypeChar:
|
||||
case kOOShaderUniformTypeShort:
|
||||
case kOOShaderUniformTypeInt:
|
||||
case kOOShaderUniformTypeLong:
|
||||
valueType = @"int";
|
||||
break;
|
||||
|
||||
case kOOShaderUniformTypeFloat:
|
||||
case kOOShaderUniformTypeDouble:
|
||||
valueType = @"float";
|
||||
break;
|
||||
}
|
||||
if (valueType == nil) valueDesc = @"INVALID";
|
||||
if (valueDesc == nil) valueDesc = @"INVALID";
|
||||
|
||||
/* Examples:
|
||||
<OOShaderUniform 0xf00>{1: int tex1 = 1;}
|
||||
<OOShaderUniform 0xf00>{3: float laser_heat_level = [<ShipEntity 0xba8> laserHeatLevel];}
|
||||
*/
|
||||
return [NSString stringWithFormat:@"<%@ %p>{%i: %@ %@ = %@;}", [self class], self, location, valueType, name, valueDesc];
|
||||
}
|
||||
|
||||
|
||||
- (void)apply
|
||||
{
|
||||
|
||||
if (isBinding) [self applyBinding];
|
||||
else [self applySimple];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation OOShaderUniform (OOPrivate)
|
||||
|
||||
- (void)applySimple
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case kOOShaderUniformTypeInt:
|
||||
glUniform1iARB(location, value.constInt);
|
||||
break;
|
||||
|
||||
case kOOShaderUniformTypeFloat:
|
||||
glUniform1fARB(location, value.constFloat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)applyBinding
|
||||
{
|
||||
|
||||
id object = nil;
|
||||
int iVal;
|
||||
float fVal;
|
||||
BOOL fp = NO;
|
||||
|
||||
/* Design note: if the object has been dealloced, or an exception occurs,
|
||||
do nothing. Shaders can specify a default value for uniforms, which
|
||||
will be used when no setting has been provided by the host program.
|
||||
|
||||
I considered clearing value.binding.object if the underlying object is
|
||||
gone, but adding code to save a small amount of spacein a case that
|
||||
shouldn't occur in normal usage is silly.
|
||||
*/
|
||||
object = [value.binding.object weakRefUnderlyingObject];
|
||||
if (object == nil) return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case kOOShaderUniformTypeChar:
|
||||
iVal = ((CharReturnMsgSend)value.binding.method)(object, value.binding.selector);
|
||||
break;
|
||||
|
||||
case kOOShaderUniformTypeShort:
|
||||
iVal = ((ShortReturnMsgSend)value.binding.method)(object, value.binding.selector);
|
||||
break;
|
||||
|
||||
case kOOShaderUniformTypeInt:
|
||||
iVal = ((IntReturnMsgSend)value.binding.method)(object, value.binding.selector);
|
||||
break;
|
||||
|
||||
case kOOShaderUniformTypeLong:
|
||||
iVal = ((LongReturnMsgSend)value.binding.method)(object, value.binding.selector);
|
||||
break;
|
||||
|
||||
case kOOShaderUniformTypeFloat:
|
||||
fVal = ((FloatReturnMsgSend)value.binding.method)(object, value.binding.selector);
|
||||
fp = YES;
|
||||
break;
|
||||
|
||||
case kOOShaderUniformTypeDouble:
|
||||
fVal = ((DoubleReturnMsgSend)value.binding.method)(object, value.binding.selector);
|
||||
fp = YES;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!fp)
|
||||
{
|
||||
if (EXPECT_NOT(value.binding.clamped)) iVal = iVal ? 1 : 0;
|
||||
glUniform1iARB(location, iVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (EXPECT_NOT(value.binding.clamped)) fVal = OOClamp_0_1_f(fVal);
|
||||
glUniform1fARB(location, fVal);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif // NO_SHADERS
|
@ -14,7 +14,9 @@ Client use is extremely simple: to get a weak reference to the object, call
|
||||
-weakRetain and use the returned proxy instead of the actual object. When
|
||||
finished, release the proxy. Messages sent to the proxy will be forwarded as
|
||||
long as the underlying object exists; beyond that, they will act exactly like
|
||||
messages to nil. Example:
|
||||
messages to nil. (IMPORTANT: this means messages returning floating-point or
|
||||
struct values have undefined return values, so use -weakRefObjectStillExists
|
||||
or -weakRefUnderlyingObject in such cases.) Example:
|
||||
|
||||
@interface ThingWatcher: NSObject
|
||||
{
|
||||
|
@ -1304,7 +1304,7 @@ static Vector circleVertex[65]; // holds vector coordinates for a unit circle
|
||||
Frame zero;
|
||||
zero.q_rotation = shipQrotation;
|
||||
int dam = [ship damage];
|
||||
GLfloat flare_length = [ship speed_factor];
|
||||
GLfloat flare_length = [ship speedFactor];
|
||||
|
||||
if (!flare_length) // don't draw if there's no fire!
|
||||
return;
|
||||
@ -1824,7 +1824,7 @@ GLuint tfan2[10] = { 33, 25, 26, 27, 28, 29, 30, 31, 32, 25}; // final fan 64..7
|
||||
if (!ship)
|
||||
return;
|
||||
|
||||
if ([ship speed_factor] <= 0.0) // don't draw if there's no fire!
|
||||
if ([ship speedFactor] <= 0.0) // don't draw if there's no fire!
|
||||
return;
|
||||
|
||||
glPopMatrix(); // restore absolute positioning
|
||||
|
@ -532,7 +532,7 @@ void setUpSinTable()
|
||||
isTextured = (textureName != 0);
|
||||
isShadered = NO;
|
||||
#ifndef NO_SHADERS
|
||||
|
||||
#if OLD_SHADERS
|
||||
if (UNIVERSE)
|
||||
{
|
||||
NSDictionary* shader_info = [[UNIVERSE descriptions] objectForKey:@"planet-surface-shader"];
|
||||
@ -545,6 +545,7 @@ void setUpSinTable()
|
||||
NSLog(@"TESTING: planet-surface-shader: %d normalMapTextureName: %d", (int)shader_program, (int)normalMapTextureName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
else
|
||||
@ -1786,11 +1787,8 @@ void drawActiveCorona (double inner_radius, double outer_radius, int step, doubl
|
||||
|
||||
- (void) drawModelWithVertexArraysAndSubdivision: (int) subdivide
|
||||
{
|
||||
#ifdef GNUSTEP
|
||||
// TODO: Find a suitable replacement fn for APPLE
|
||||
#else
|
||||
if (usingVAR)
|
||||
glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
|
||||
#if GL_APPLE_vertex_array_object
|
||||
if (usingVAR) glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
|
||||
#endif
|
||||
|
||||
glDrawElements( GL_TRIANGLES, 3 * n_triangles[subdivide], GL_UNSIGNED_INT, &vertexdata.index_array[triangle_start[subdivide]]);
|
||||
|
@ -128,11 +128,8 @@ Ringdata ringentity;
|
||||
{
|
||||
if (immediate)
|
||||
{
|
||||
#ifdef GNUSTEP
|
||||
// TODO: replace APPLE function call
|
||||
#else
|
||||
if (usingVAR)
|
||||
glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
|
||||
#if GL_APPLE_vertex_array_object
|
||||
if (usingVAR) glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
|
||||
#endif
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
@ -280,8 +280,12 @@ MA 02110-1301, USA.
|
||||
int debug_flag;
|
||||
int debug_condition;
|
||||
|
||||
#ifdef OLD_SHADERS
|
||||
// shaders
|
||||
NSMutableDictionary *shader_info;
|
||||
#else
|
||||
NSMutableDictionary *materials;
|
||||
#endif
|
||||
|
||||
uint16_t entity_personality; // Per-entity random number. Used for shaders, maybe scripting at some point.
|
||||
}
|
||||
@ -469,7 +473,7 @@ MA 02110-1301, USA.
|
||||
- (GLfloat) flight_yaw;
|
||||
- (GLfloat) flight_speed;
|
||||
- (GLfloat) max_flight_speed;
|
||||
- (GLfloat) speed_factor;
|
||||
- (GLfloat) speedFactor;
|
||||
|
||||
- (void) setTemperature:(GLfloat) value;
|
||||
- (void) setHeatInsulation:(GLfloat) value;
|
||||
@ -506,8 +510,10 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other);
|
||||
|
||||
- (NSComparisonResult) compareBeaconCodeWith:(ShipEntity*) other;
|
||||
|
||||
- (GLfloat)laserHeatLevel;
|
||||
- (GLfloat)hullHeatLevel;
|
||||
- (float)laserHeatLevel;
|
||||
- (float)hullHeatLevel;
|
||||
- (float)entityPersonality;
|
||||
- (int)entityPersonalityInt;
|
||||
|
||||
- (void)setSuppressExplosion:(BOOL)suppress;
|
||||
|
||||
@ -640,17 +646,14 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role);
|
||||
- (void) sendCoordinatesToPilot;
|
||||
- (void) pilotArrived;
|
||||
|
||||
/****************************************************************
|
||||
|
||||
straight c stuff
|
||||
|
||||
****************************************************************/
|
||||
|
||||
BOOL ship_canCollide (ShipEntity* ship);
|
||||
- (Entity *)entityForShaderProperties;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
BOOL ship_canCollide (ShipEntity* ship);
|
||||
|
||||
|
||||
@interface OOCacheManager (Octree)
|
||||
|
||||
+ (Octree *)octreeForModel:(NSString *)inKey;
|
||||
|
@ -28,9 +28,13 @@ MA 02110-1301, USA.
|
||||
#import "OOMaths.h"
|
||||
#import "Universe.h"
|
||||
#import "TextureStore.h"
|
||||
#import "OOShaderMaterial.h"
|
||||
|
||||
#import "ResourceManager.h"
|
||||
#import "OOStringParsing.h"
|
||||
#import "OOCollectionExtractors.h"
|
||||
#import "OOConstToString.h"
|
||||
#import "NSScannerOOExtensions.h"
|
||||
|
||||
#import "OOCharacter.h"
|
||||
#import "OOBrain.h"
|
||||
@ -38,7 +42,6 @@ MA 02110-1301, USA.
|
||||
|
||||
#import "Geometry.h"
|
||||
#import "Octree.h"
|
||||
#import "NSScannerOOExtensions.h"
|
||||
#import "OOColor.h"
|
||||
|
||||
#import "ParticleEntity.h"
|
||||
@ -57,11 +60,6 @@ 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";
|
||||
static NSString * const kOOLogShaderInit = @"rendering.opengl.shader.init";
|
||||
static NSString * const kOOLogShaderInitDumpShader = @"rendering.opengl.shader.init.dump.shader";
|
||||
static NSString * const kOOLogShaderInitDumpTexture = @"rendering.opengl.shader.init.dump.texture";
|
||||
static NSString * const kOOLogShaderInitDumpShaderInfo = @"rendering.opengl.shader.init.dump.shaderInfo";
|
||||
static NSString * const kOOLogShaderTextureNameMissing = @"rendering.opengl.shader.texNameMissing";
|
||||
|
||||
#ifdef GNUSTEP
|
||||
void loadOpenGLFunctions()
|
||||
@ -84,7 +82,9 @@ void loadOpenGLFunctions()
|
||||
#endif
|
||||
|
||||
|
||||
#if OLD_SHADERS
|
||||
static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProgram);
|
||||
#endif
|
||||
|
||||
|
||||
@implementation ShipEntity
|
||||
@ -454,7 +454,12 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
|
||||
|
||||
[octree autorelease];
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
#if OLD_SHADERS
|
||||
[shader_info release];
|
||||
#endif
|
||||
#endif
|
||||
[materials release];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
@ -2709,331 +2714,227 @@ void testForShaders()
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
- (void) initialiseTextures
|
||||
{
|
||||
[super initialiseTextures];
|
||||
NSDictionary *shaderDefs = nil;
|
||||
NSEnumerator *shaderEnum = nil;
|
||||
NSString *shaderKey = nil;
|
||||
NSDictionary *shaderConfig = nil;
|
||||
OOShaderMaterial *shader = nil;
|
||||
static NSDictionary *macros = nil;
|
||||
static NSDictionary *defaultBindings = nil;
|
||||
Entity *propertyEntity = nil;
|
||||
NSDictionary *materialDefaults = nil;
|
||||
|
||||
if (testForShaderSupport)
|
||||
testForShaders();
|
||||
if ([shipinfoDictionary objectForKey:@"shaders"] && shaders_supported)
|
||||
[super initialiseTextures];
|
||||
|
||||
if (testForShaderSupport) testForShaders();
|
||||
if (!shaders_supported) return;
|
||||
|
||||
shaderDefs = [shipinfoDictionary objectForKey:@"shaders"];
|
||||
if (shaderDefs)
|
||||
{
|
||||
#ifndef NO_SHADERS
|
||||
// initialise textures in shaders
|
||||
|
||||
if (!shader_info)
|
||||
shader_info = [[NSMutableDictionary dictionary] retain];
|
||||
|
||||
OOLog(kOOLogShaderInit, @"Initialising shaders for %@", self);
|
||||
OOLogIndentIf(kOOLogShaderInit);
|
||||
|
||||
NSDictionary *shaders = [shipinfoDictionary objectForKey:@"shaders"];
|
||||
NSEnumerator *shaderEnum = nil;
|
||||
NSString *shaderKey = nil;
|
||||
|
||||
for (shaderEnum = [shaders keyEnumerator]; (shaderKey = [shaderEnum nextObject]); )
|
||||
if (materials)
|
||||
{
|
||||
NSDictionary* shader = [shaders objectForKey:shaderKey];
|
||||
NSArray* shader_textures = [shader objectForKey:@"textures"];
|
||||
NSMutableArray* textureNames = [NSMutableArray array];
|
||||
|
||||
OOLog(kOOLogShaderInitDumpShader, @"Shader: initialising shader for %@ : %@", shaderKey, shader);
|
||||
int ti;
|
||||
for (ti = 0; ti < [shader_textures count]; ti ++)
|
||||
OOLog(@"shipEntity.squashRecycling", @"Hmm, shaders is non-nil for %@.", self);
|
||||
[materials release];
|
||||
}
|
||||
|
||||
materials = [[NSMutableDictionary alloc] init];
|
||||
|
||||
OOLog(@"shader.vessel.init", @"Initialising shaders for %@", self);
|
||||
OOLogIndentIf(@"shader.vessel.init");
|
||||
|
||||
if (macros == nil)
|
||||
{
|
||||
// Set up macros and bindings used for all ship shaders
|
||||
materialDefaults = [ResourceManager dictionaryFromFilesNamed:@"material-defaults.plist" inFolder:@"Config" andMerge:YES];
|
||||
macros = [[materialDefaults dictionaryForKey:@"ship-prefix-macros" defaultValue:[NSDictionary dictionary]] retain];
|
||||
defaultBindings = [[materialDefaults dictionaryForKey:@"ship-default-bindings" defaultValue:[NSDictionary dictionary]] retain];
|
||||
}
|
||||
|
||||
propertyEntity = [self entityForShaderProperties];
|
||||
|
||||
for (shaderEnum = [shaderDefs keyEnumerator]; (shaderKey = [shaderEnum nextObject]); )
|
||||
{
|
||||
shaderConfig = [shaderDefs dictionaryForKey:shaderKey defaultValue:nil];
|
||||
if (shaderConfig != nil)
|
||||
{
|
||||
GLuint tn = [TextureStore getTextureNameFor: (NSString*)[shader_textures objectAtIndex:ti]];
|
||||
[textureNames addObject:[NSNumber numberWithUnsignedInt:tn]];
|
||||
OOLog(kOOLogShaderInitDumpTexture, @"Shader: initialised texture: %@", [shader_textures objectAtIndex:ti]);
|
||||
}
|
||||
|
||||
GLhandleARB shaderProgram = [TextureStore shaderProgramFromDictionary:shader];
|
||||
if (shaderProgram)
|
||||
{
|
||||
[shader_info setObject:[NSDictionary dictionaryWithObjectsAndKeys:
|
||||
textureNames, @"textureNames",
|
||||
[NSValue valueWithPointer:shaderProgram], @"shaderProgram",
|
||||
[shader objectForKey:@"uniforms"], @"uniforms",
|
||||
nil]
|
||||
forKey: shaderKey];
|
||||
shader = [OOShaderMaterial shaderWithConfiguration:shaderConfig macros:macros bindingTarget:propertyEntity];
|
||||
if (shader != nil)
|
||||
{
|
||||
[materials setObject:shader forKey:shaderKey];
|
||||
|
||||
[shader addUniformsFromDictionary:defaultBindings withBindingTarget:propertyEntity];
|
||||
|
||||
[shader bindUniform:@"time"
|
||||
toObject:UNIVERSE
|
||||
property:@selector(getTime)
|
||||
clamped:NO];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OOLog(kOOLogShaderInitDumpShaderInfo, @"TESTING: shader_info = %@", shader_info);
|
||||
OOLogOutdentIf(kOOLogShaderInit);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (shader_info)
|
||||
[shader_info release];
|
||||
shader_info = nil;
|
||||
}
|
||||
OOLogOutdentIf(@"shader.vessel.init");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (Entity *)entityForShaderProperties
|
||||
{
|
||||
if (!isSubentity) return self;
|
||||
else return [self owner];
|
||||
}
|
||||
|
||||
|
||||
- (void) drawEntity:(BOOL) immediate :(BOOL) translucent
|
||||
{
|
||||
if (testForShaderSupport)
|
||||
testForShaders();
|
||||
NSString *textureKey = nil;
|
||||
unsigned i;
|
||||
OOMaterial *material = nil;
|
||||
NSEnumerator *subEntityEnum = nil;
|
||||
Entity *subEntity = nil;
|
||||
|
||||
if (zero_distance > no_draw_distance) return; // TOO FAR AWAY
|
||||
|
||||
if ([UNIVERSE breakPatternHide]) return; // DON'T DRAW
|
||||
|
||||
if (cloaking_device_active && (randf() > 0.10)) return; // DON'T DRAW
|
||||
|
||||
if (!translucent)
|
||||
if (no_draw_distance < zero_distance ||
|
||||
[UNIVERSE breakPatternHide] ||
|
||||
(cloaking_device_active && randf() > 0.10))
|
||||
{
|
||||
if (!shaders_supported)
|
||||
// Don't draw.
|
||||
return;
|
||||
}
|
||||
|
||||
NS_DURING
|
||||
if (!translucent)
|
||||
{
|
||||
[super drawEntity:immediate:translucent];
|
||||
}
|
||||
else
|
||||
{
|
||||
// draw the thing - code take from Entity drawEntity::
|
||||
//
|
||||
int ti;
|
||||
GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
|
||||
GLfloat mat_no[] = { 0.0, 0.0, 0.0, 1.0 };
|
||||
|
||||
NS_DURING
|
||||
|
||||
if (isSmoothShaded)
|
||||
glShadeModel(GL_SMOOTH);
|
||||
else
|
||||
glShadeModel(GL_FLAT);
|
||||
|
||||
if (!translucent)
|
||||
GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
|
||||
GLfloat mat_no[] = { 0.0, 0.0, 0.0, 1.0 };
|
||||
GLfloat amb_diff0[] = { 0.5, 0.5, 0.5, 1.0 };
|
||||
|
||||
if (EXPECT_NOT(basefile == nil))
|
||||
{
|
||||
OOLog(@"render.shipEntity.expectedBaseFile", @"Error: no basefile for entity %@", self);
|
||||
}
|
||||
|
||||
// Set up state
|
||||
glShadeModel(isSmoothShaded ? GL_SMOOTH : GL_FLAT);
|
||||
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_INDEX_ARRAY);
|
||||
glDisableClientState(GL_EDGE_FLAG_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glVertexPointer( 3, GL_FLOAT, 0, entityData.vertex_array);
|
||||
glNormalPointer( GL_FLOAT, 0, entityData.normal_array);
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, entityData.texture_uv_array);
|
||||
|
||||
if (immediate)
|
||||
{
|
||||
/* Gap removal (draw flat polys).
|
||||
|
||||
It is my belief that this has absolutely no effect whatsoever on gaps,
|
||||
as it's using the same geometry as the "real" rendering, but does stop
|
||||
alpha textures from semi-working. This is probably good, since we
|
||||
don't depth sort, but could be replaced with disabling blending.
|
||||
TODO: try the blending thing as above.
|
||||
-- Ahruman
|
||||
*/
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, amb_diff0);
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, mat_no);
|
||||
glColor4f( 0.25, 0.25, 0.25, 1.0); // gray
|
||||
glDepthMask(GL_FALSE); // don't write to depth buffer
|
||||
glDrawArrays(GL_TRIANGLES, 0, entityData.n_triangles); // draw in gray to mask the edges
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
// Now draw textured polygons.
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_ambient);
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, mat_no); // TODO: replace with using default OOMaterial if no custom material is defined.
|
||||
|
||||
for (i = 1; i <= n_textures; i++)
|
||||
{
|
||||
if (basefile)
|
||||
textureKey = [TextureStore getNameOfTextureWithGLuint: texture_name[i]];
|
||||
material = [materials objectForKey:textureKey];
|
||||
|
||||
if (material == nil)
|
||||
{
|
||||
// calls moved here because they are unsupported in display lists
|
||||
//
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_INDEX_ARRAY);
|
||||
glDisableClientState(GL_EDGE_FLAG_ARRAY);
|
||||
//
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glVertexPointer( 3, GL_FLOAT, 0, entityData.vertex_array);
|
||||
glNormalPointer( GL_FLOAT, 0, entityData.normal_array);
|
||||
glTexCoordPointer( 2, GL_FLOAT, 0, entityData.texture_uv_array);
|
||||
|
||||
ShipEntity *propertyEntity;
|
||||
if (!isSubentity) propertyEntity = self;
|
||||
else propertyEntity = (ShipEntity *)[self owner];
|
||||
|
||||
GLfloat utime = (GLfloat)[UNIVERSE getTime];
|
||||
GLfloat engine_level = [propertyEntity speed_factor];
|
||||
GLfloat laser_heat_level = [propertyEntity laserHeatLevel];
|
||||
GLfloat hull_heat_level = [propertyEntity hullHeatLevel];
|
||||
int entity_personality_int = propertyEntity->entity_personality;
|
||||
|
||||
laser_heat_level = OOClamp_0_1_f(laser_heat_level);
|
||||
|
||||
if (immediate)
|
||||
{
|
||||
//
|
||||
// gap removal (draws flat polys)
|
||||
//
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
GLfloat amb_diff0[] = { 0.5, 0.5, 0.5, 1.0};
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, amb_diff0);
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, mat_no);
|
||||
glColor4f( 0.25, 0.25, 0.25, 1.0); // gray
|
||||
glDepthMask(GL_FALSE); // don't write to depth buffer
|
||||
glDrawArrays( GL_TRIANGLES, 0, entityData.n_triangles); // draw in gray to mask the edges
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
//
|
||||
// now the textures ...
|
||||
//
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_ambient);
|
||||
glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, mat_no);
|
||||
|
||||
for (ti = 1; ti <= n_textures; ti++)
|
||||
{
|
||||
NSString* textureKey = [TextureStore getNameOfTextureWithGLuint: texture_name[ti]];
|
||||
#ifndef NO_SHADERS
|
||||
if ((shader_info) && [shader_info objectForKey: textureKey])
|
||||
{
|
||||
NSDictionary *shader = [shader_info objectForKey:textureKey];
|
||||
GLhandleARB shaderProgram = [[shader objectForKey:@"shaderProgram"] pointerValue];
|
||||
GLint variable_location;
|
||||
//
|
||||
// set up texture units
|
||||
//
|
||||
glUseProgramObjectARB(shaderProgram);
|
||||
//
|
||||
NSArray *texture_units = [shader objectForKey:@"textureNames"];
|
||||
int n_tu = [texture_units count];
|
||||
int i;
|
||||
for (i = 0; i < n_tu; i++)
|
||||
{
|
||||
// set up each texture unit in turn
|
||||
// associating texN with each texture
|
||||
GLuint textureN = [[texture_units objectAtIndex:i] intValue];
|
||||
|
||||
glActiveTextureARB( GL_TEXTURE0_ARB + i);
|
||||
glBindTexture( GL_TEXTURE_2D, textureN);
|
||||
|
||||
NSString* texdname = [NSString stringWithFormat:@"tex%d", i];
|
||||
const char* cname = [texdname UTF8String];
|
||||
variable_location = glGetUniformLocationARB(shaderProgram, cname);
|
||||
if (variable_location == -1)
|
||||
OOLog(kOOLogShaderTextureNameMissing, @"GLSL ERROR couldn't find location of %@ in shaderProgram %d", texdname, shaderProgram);
|
||||
else
|
||||
glUniform1iARB(variable_location, i); // associate texture unit number i with tex%d
|
||||
}
|
||||
|
||||
NSDictionary *uniforms = [shader objectForKey:@"uniforms"];
|
||||
if (uniforms != nil)
|
||||
{
|
||||
ApplyConstantUniforms([shader objectForKey:@"uniforms"], shaderProgram);
|
||||
}
|
||||
|
||||
// other uniform variables
|
||||
variable_location = glGetUniformLocationARB( shaderProgram, "time");
|
||||
if (variable_location != -1)
|
||||
{
|
||||
OOLog(@"rendering.opengl.shader.uniform.time", @"Binding time: %g", time);
|
||||
glUniform1fARB(variable_location, utime);
|
||||
}
|
||||
|
||||
variable_location = glGetUniformLocationARB( shaderProgram, "engine_level");
|
||||
if (variable_location != -1)
|
||||
{
|
||||
OOLog(@"rendering.opengl.shader.uniform.engineLevel", @"Binding engine_level: %g", engine_level);
|
||||
glUniform1fARB(variable_location, engine_level);
|
||||
}
|
||||
|
||||
variable_location = glGetUniformLocationARB( shaderProgram, "laser_heat_level");
|
||||
if (variable_location != -1)
|
||||
{
|
||||
OOLog(@"rendering.opengl.shader.uniform.laserHeatLevel", @"Binding laser_heat_level: %g", laser_heat_level);
|
||||
glUniform1fARB(variable_location, laser_heat_level);
|
||||
}
|
||||
|
||||
variable_location = glGetUniformLocationARB( shaderProgram, "hull_heat_level");
|
||||
if (variable_location != -1)
|
||||
{
|
||||
OOLog(@"rendering.opengl.shader.uniform.hullHeatLevel", @"Binding hull_heat_level: %g", hull_heat_level);
|
||||
glUniform1fARB(variable_location, hull_heat_level);
|
||||
}
|
||||
|
||||
variable_location = glGetUniformLocationARB( shaderProgram, "entity_personality_int");
|
||||
if (variable_location != -1)
|
||||
{
|
||||
OOLog(@"rendering.opengl.shader.uniform.entityPersonality.int", @"Binding entity_personality_int: %i", entity_personality_int);
|
||||
glUniform1iARB(variable_location, entity_personality_int);
|
||||
}
|
||||
|
||||
variable_location = glGetUniformLocationARB( shaderProgram, "entity_personality");
|
||||
if (variable_location != -1)
|
||||
{
|
||||
OOLog(@"rendering.opengl.shader.uniform.entityPersonality.float", @"Binding entity_personality: %g", entity_personality_int / (float)0x7FFF);
|
||||
glUniform1fARB(variable_location, entity_personality_int / (float)0x7FFF);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
glBindTexture(GL_TEXTURE_2D, texture_name[ti]);
|
||||
|
||||
glDrawArrays( GL_TRIANGLES, triangle_range[ti].location, triangle_range[ti].length);
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
// switch off shader
|
||||
if ((shader_info) && [shader_info objectForKey: textureKey])
|
||||
{
|
||||
glUseProgramObjectARB(0);
|
||||
glActiveTextureARB( GL_TEXTURE0_ARB);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (displayListName != 0)
|
||||
{
|
||||
[self drawEntity: YES : translucent];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self initialiseTextures];
|
||||
|
||||
#ifdef GNUSTEP
|
||||
// TODO: Find out what these APPLE functions can be replaced with
|
||||
#else
|
||||
if (usingVAR)
|
||||
glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
|
||||
#endif
|
||||
|
||||
[self generateDisplayList];
|
||||
}
|
||||
}
|
||||
// TODO: use a default material instead
|
||||
[OOMaterial applyNone];
|
||||
glBindTexture(GL_TEXTURE_2D, texture_name[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
OOLog(kOOLogFileNotFound, @"ERROR no basefile for entity %@");
|
||||
[material apply];
|
||||
}
|
||||
|
||||
glDrawArrays( GL_TRIANGLES, triangle_range[i].location, triangle_range[i].length);
|
||||
}
|
||||
[OOMaterial applyNone];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not immediate.
|
||||
if (displayListName != 0)
|
||||
{
|
||||
// TODO: Isn't this equivalent to "if immedate || displayListName != 0" above, along with passing displayListName != 0 as the super call's immediate parameter? -- Ahruman
|
||||
[self drawEntity:YES :translucent];
|
||||
}
|
||||
glShadeModel(GL_SMOOTH);
|
||||
CheckOpenGLErrors([NSString stringWithFormat:@"Entity after drawing %@", self]);
|
||||
|
||||
NS_HANDLER
|
||||
|
||||
OOLog(kOOLogException, @"***** [Entity drawEntity::] encountered exception: %@ : %@ *****",[localException name], [localException reason]);
|
||||
OOLog(kOOLogException, @"***** Removing entity %@ from UNIVERSE *****", self);
|
||||
[UNIVERSE removeEntity:self];
|
||||
if ([[localException name] hasPrefix:@"Oolite"])
|
||||
[UNIVERSE handleOoliteException:localException]; // handle these ourself
|
||||
else
|
||||
[localException raise]; // pass these on
|
||||
|
||||
NS_ENDHANDLER
|
||||
{
|
||||
// Set up display list.
|
||||
[self initialiseTextures];
|
||||
#if GL_APPLE_vertex_array_object
|
||||
if (usingVAR) glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
|
||||
#endif
|
||||
[self generateDisplayList];
|
||||
}
|
||||
}
|
||||
|
||||
if (!isSmoothShaded) glShadeModel(GL_SMOOTH);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((status == STATUS_COCKPIT_DISPLAY)&&((debug | debug_flag) & (DEBUG_COLLISIONS | DEBUG_OCTREE)))
|
||||
[octree drawOctree];
|
||||
|
||||
if ((debug | debug_flag) & (DEBUG_COLLISIONS | DEBUG_OCTREE))
|
||||
[octree drawOctreeCollisions];
|
||||
|
||||
if ((isSubentity)&&[self owner])
|
||||
else
|
||||
{
|
||||
if (([self owner]->status == STATUS_COCKPIT_DISPLAY)&&((debug | debug_flag) & (DEBUG_COLLISIONS | DEBUG_OCTREE)))
|
||||
// Translucent.
|
||||
if ((status == STATUS_COCKPIT_DISPLAY)&&((debug | debug_flag) & (DEBUG_COLLISIONS | DEBUG_OCTREE)))
|
||||
[octree drawOctree];
|
||||
|
||||
if ((debug | debug_flag) & (DEBUG_COLLISIONS | DEBUG_OCTREE))
|
||||
[octree drawOctreeCollisions];
|
||||
|
||||
if ((isSubentity)&&[self owner])
|
||||
{
|
||||
if (([self owner]->status == STATUS_COCKPIT_DISPLAY)&&((debug | debug_flag) & (DEBUG_COLLISIONS | DEBUG_OCTREE)))
|
||||
[octree drawOctree];
|
||||
if ((debug | debug_flag) & (DEBUG_COLLISIONS | DEBUG_OCTREE))
|
||||
[octree drawOctreeCollisions];
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
CheckOpenGLErrors([NSString stringWithFormat:@"ShipEntity after drawing Entity (main) %@", self]);
|
||||
//
|
||||
|
||||
if (immediate)
|
||||
return; // don't draw sub-entities when constructing a displayList
|
||||
|
||||
if (sub_entities)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < [sub_entities count]; i++)
|
||||
|
||||
if (!immediate)
|
||||
{
|
||||
Entity *se = (Entity *)[sub_entities objectAtIndex:i];
|
||||
[se setOwner:self]; // refresh ownership
|
||||
[se drawSubEntity:immediate:translucent];
|
||||
// Draw subentities.
|
||||
for (subEntityEnum = [sub_entities objectEnumerator]; (subEntity = [subEntityEnum nextObject]); )
|
||||
{
|
||||
[subEntity setOwner:self]; // refresh ownership
|
||||
[subEntity drawSubEntity:immediate :translucent];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
CheckOpenGLErrors([NSString stringWithFormat:@"ShipEntity after drawing Entity (subentities) %@", self]);
|
||||
//
|
||||
|
||||
CheckOpenGLErrors([NSString stringWithFormat:@"%s after drawing %@ (immediate: %s, translucent: %s)", __PRETTY_FUNCTION__, self, immediate ? "YES" : "NO", translucent ? "YES" : "NO"]);
|
||||
NS_HANDLER
|
||||
OOLog(@"exception.shipEntity.draw", @"***** %s encountered exception: %@ : %@ *****", __PRETTY_FUNCTION__, [localException name], [localException reason]);
|
||||
OOLog(@"exception.shipEntity.draw", @"***** Removing entity %@ from UNIVERSE *****", self);
|
||||
[UNIVERSE removeEntity:self];
|
||||
if ([[localException name] hasPrefix:@"Oolite"]) [UNIVERSE handleOoliteException:localException]; // handle these ourself
|
||||
else [localException raise]; // pass these on
|
||||
NS_ENDHANDLER
|
||||
}
|
||||
|
||||
|
||||
- (void) drawSubEntity:(BOOL) immediate :(BOOL) translucent
|
||||
{
|
||||
Entity* my_owner = [UNIVERSE entityForUniversalID:owner];
|
||||
@ -3821,10 +3722,9 @@ static GLfloat mascem_color2[4] = { 0.4, 0.1, 0.4, 1.0}; // purple
|
||||
return max_flight_speed;
|
||||
}
|
||||
|
||||
- (GLfloat) speed_factor
|
||||
- (GLfloat) speedFactor
|
||||
{
|
||||
if (max_flight_speed <= 0.0)
|
||||
return 0.0;
|
||||
if (max_flight_speed <= 0.0) return 0.0;
|
||||
return flight_speed / max_flight_speed;
|
||||
}
|
||||
|
||||
@ -4495,18 +4395,31 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
}
|
||||
|
||||
|
||||
- (GLfloat)laserHeatLevel
|
||||
- (float)laserHeatLevel
|
||||
{
|
||||
return (weapon_recharge_rate - shot_time) / weapon_recharge_rate;
|
||||
float result = (weapon_recharge_rate - shot_time) / weapon_recharge_rate;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (GLfloat)hullHeatLevel
|
||||
- (float)hullHeatLevel
|
||||
{
|
||||
return ship_temperature / (GLfloat)SHIP_MAX_CABIN_TEMP;
|
||||
}
|
||||
|
||||
|
||||
- (float)entityPersonality
|
||||
{
|
||||
return entity_personality / (float)0x7FFF;
|
||||
}
|
||||
|
||||
|
||||
- (int)entityPersonalityInt
|
||||
{
|
||||
return entity_personality;
|
||||
}
|
||||
|
||||
|
||||
- (void)setSuppressExplosion:(BOOL)suppress
|
||||
{
|
||||
suppressExplosion = suppress != NO;
|
||||
@ -7679,7 +7592,7 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
|
||||
flagsString = [flags count] ? [flags componentsJoinedByString:@", "] : @"none";
|
||||
OOLog(@"dumpState.shipEntity", @"Flags: %@", flagsString);
|
||||
|
||||
OOLog(@"dumpState.shipEntity.glsl", @"engine_level: %g", [self speed_factor]);
|
||||
OOLog(@"dumpState.shipEntity.glsl", @"engine_level: %g", [self speedFactor]);
|
||||
OOLog(@"dumpState.shipEntity.glsl", @"laser_heat_level: %g", OOClamp_0_1_f([self laserHeatLevel]));
|
||||
OOLog(@"dumpState.shipEntity.glsl", @"hull_heat_level: %g", [self hullHeatLevel]);
|
||||
OOLog(@"dumpState.shipEntity.glsl", @"entity_personality: %g", entity_personality / (float)0x7FFF);
|
||||
@ -7717,6 +7630,7 @@ static NSString * const kOOCacheOctrees = @"octrees";
|
||||
@end
|
||||
|
||||
|
||||
#if OLD_SHADERS
|
||||
// This could be more efficient.
|
||||
static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProgram)
|
||||
{
|
||||
@ -7770,4 +7684,5 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -478,9 +478,8 @@ MA 02110-1301, USA.
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
#ifdef GNUSTEP
|
||||
// TODO: find replacement for APPLE function
|
||||
#else
|
||||
|
||||
#if GL_APPLE_vertex_array_object
|
||||
if (usingVAR) glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
|
||||
#endif
|
||||
glBindTexture(GL_TEXTURE_2D, star_textureName);
|
||||
@ -517,9 +516,8 @@ MA 02110-1301, USA.
|
||||
if (![UNIVERSE reducedDetail])
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, blob_textureName);
|
||||
#ifdef GNUSTEP
|
||||
// TODO: Find replacement for APPLE fncall
|
||||
#else
|
||||
|
||||
#if GL_APPLE_vertex_array_object
|
||||
if (usingVAR) glBindVertexArrayAPPLE(gVertexArrayRangeObjects[1]);
|
||||
#endif
|
||||
|
||||
|
@ -48,10 +48,6 @@ extern int debug;
|
||||
+ (NSString*) getNameOfTextureWithGLuint:(GLuint) value;
|
||||
+ (NSSize) getSizeOfTexture:(NSString *)filename;
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
+ (GLhandleARB) shaderProgramFromDictionary:(NSDictionary *) shaderDict;
|
||||
#endif
|
||||
|
||||
+ (void) reloadTextures;
|
||||
|
||||
|
||||
|
@ -38,11 +38,6 @@ MA 02110-1301, USA.
|
||||
|
||||
|
||||
static NSString * const kOOLogPlanetTextureGen = @"texture.planet.generate";
|
||||
static NSString * const kOOLogShaderInitSuccess = @"rendering.opengl.shader.init.success";
|
||||
static NSString * const kOOLogShaderInitFailed = @"rendering.opengl.shader.init.failed";
|
||||
|
||||
|
||||
static BOOL GetShaderSource(NSString *shaderType, NSDictionary *shaderDict, NSString **outResult);
|
||||
|
||||
|
||||
@implementation TextureStore
|
||||
@ -318,172 +313,11 @@ GLuint max_texture_dimension = 512; // conservative start
|
||||
return size;
|
||||
}
|
||||
|
||||
#ifndef NO_SHADERS
|
||||
+ (GLhandleARB) shaderProgramFromDictionary:(NSDictionary *) shaderDict
|
||||
{
|
||||
if ([shaderUniversalDictionary objectForKey:shaderDict])
|
||||
return (GLhandleARB)[(NSNumber*)[shaderUniversalDictionary objectForKey:shaderDict] unsignedIntValue];
|
||||
|
||||
if (!shaderDict)
|
||||
{
|
||||
NSLog(@"ERROR: null dictionary passed to [TextureStore prepareShaderFDromDictionary:]");
|
||||
return NULL_SHADER; // failed!
|
||||
}
|
||||
|
||||
GLhandleARB fragment_shader_object = NULL_SHADER;
|
||||
GLhandleARB vertex_shader_object = NULL_SHADER;
|
||||
GLhandleARB shader_program = NULL_SHADER;
|
||||
|
||||
NSString *fragmentSource = nil;
|
||||
NSString *vertexSource = nil;
|
||||
|
||||
BOOL OK = YES;
|
||||
|
||||
NSString *shaderEnvMacros =
|
||||
@"#define OO_TIME\t\t\t\t\t\t1\n"
|
||||
"#define OO_ENGINE_LEVEL\t\t\t\t1\n"
|
||||
"#define OO_LASER_HEAT_LEVEL\t\t\t1\n"
|
||||
"#define OO_HULL_HEAT_LEVEL\t\t\t1\n"
|
||||
"#define OO_HULL_HEAT_LEVEL\t\t\t1\n"
|
||||
"#define OO_ENTITY_PERSONALITY_INT\t1\n"
|
||||
"#define OO_ENTITY_PERSONALITY\t\t1\n"
|
||||
"\n";
|
||||
|
||||
if (!GetShaderSource(@"fragment", shaderDict, &fragmentSource)) return NULL_SHADER;
|
||||
if (fragmentSource == nil) fragmentSource = [shaderDict objectForKey:@"glsl"];
|
||||
|
||||
if (!GetShaderSource(@"vertex", shaderDict, &vertexSource)) return NULL_SHADER;
|
||||
|
||||
if (fragmentSource == nil && vertexSource == nil)
|
||||
{
|
||||
OOLog(kOOLogShaderInitFailed, @"Shader dictionary specifies neither vertex shader nor fragment shader:\n", shaderDict);
|
||||
return NULL_SHADER;
|
||||
}
|
||||
|
||||
// check if we need to make a fragment shader
|
||||
if (fragmentSource != nil)
|
||||
{
|
||||
GLhandleARB shader_object = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB); // a fragment shader
|
||||
if (!shader_object)
|
||||
{
|
||||
OOLog(kOOLogShaderInitFailed, @"GLSL ERROR: could not create a fragment shader with glCreateShaderObjectARB()");
|
||||
OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
fragmentSource = [shaderEnvMacros stringByAppendingString:fragmentSource];
|
||||
|
||||
const GLcharARB *fragment_string;
|
||||
fragment_string = [fragmentSource cString];
|
||||
glShaderSourceARB(shader_object, 1, &fragment_string, NULL);
|
||||
|
||||
// compile the shader!
|
||||
glCompileShaderARB(shader_object);
|
||||
GLint result;
|
||||
glGetObjectParameterivARB(shader_object, GL_OBJECT_COMPILE_STATUS_ARB, &result);
|
||||
if (result != GL_TRUE)
|
||||
{
|
||||
char log[1024];
|
||||
GLsizei log_length;
|
||||
glGetInfoLogARB( shader_object, 1024, &log_length, log);
|
||||
OOLog(kOOLogShaderInitFailed, @"GLSL ERROR: shader code would not compile:\n%s\n\n%@\n\n", log, fragmentSource);
|
||||
OK = NO;
|
||||
}
|
||||
fragment_shader_object = shader_object;
|
||||
}
|
||||
}
|
||||
|
||||
// check if we need to make a vertex shader
|
||||
if (vertexSource)
|
||||
{
|
||||
GLhandleARB shader_object = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); // a vertex shader
|
||||
if (!shader_object)
|
||||
{
|
||||
OOLog(kOOLogShaderInitFailed, @"GLSL ERROR: could not create a fragment shader with glCreateShaderObjectARB()");
|
||||
OK = NO;
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
vertexSource = [shaderEnvMacros stringByAppendingString:vertexSource];
|
||||
|
||||
const GLcharARB *vertex_string;
|
||||
vertex_string = [vertexSource cString];
|
||||
glShaderSourceARB(shader_object, 1, &vertex_string, NULL);
|
||||
|
||||
// compile the shader!
|
||||
glCompileShaderARB(shader_object);
|
||||
GLint result;
|
||||
glGetObjectParameterivARB(shader_object, GL_OBJECT_COMPILE_STATUS_ARB, &result);
|
||||
if (result != GL_TRUE)
|
||||
{
|
||||
char log[1024];
|
||||
GLsizei log_length;
|
||||
glGetInfoLogARB( shader_object, 1024, &log_length, log);
|
||||
OOLog(kOOLogShaderInitFailed, @"GLSL ERROR: shader code would not compile:\n%s\n\n%@\n\n", log, vertexSource);
|
||||
OK = NO;
|
||||
}
|
||||
vertex_shader_object = shader_object;
|
||||
}
|
||||
}
|
||||
|
||||
if (OK && !fragment_shader_object && !vertex_shader_object)
|
||||
{
|
||||
OOLog(kOOLogShaderInitFailed, @"GLSL ERROR: could not create any shaders from %@", shaderDict);
|
||||
OK = NO;
|
||||
}
|
||||
|
||||
// create a shader program
|
||||
if (OK)
|
||||
{
|
||||
shader_program = glCreateProgramObjectARB();
|
||||
if (!shader_program)
|
||||
{
|
||||
OOLog(kOOLogShaderInitFailed, @"GLSL ERROR: could not create a shader program with glCreateProgramObjectARB()");
|
||||
OK = NO;
|
||||
}
|
||||
}
|
||||
|
||||
if (OK)
|
||||
{
|
||||
// attach the shader objects
|
||||
if (vertex_shader_object) glAttachObjectARB(shader_program, vertex_shader_object);
|
||||
if (fragment_shader_object) glAttachObjectARB(shader_program, fragment_shader_object);
|
||||
|
||||
// link the program
|
||||
glLinkProgramARB(shader_program);
|
||||
GLint result;
|
||||
glGetObjectParameterivARB(shader_program, GL_OBJECT_LINK_STATUS_ARB, &result);
|
||||
if (result != GL_TRUE)
|
||||
{
|
||||
char log[1024];
|
||||
GLsizei log_length;
|
||||
glGetInfoLogARB(shader_program, 1024, &log_length, log);
|
||||
OOLog(kOOLogShaderInitFailed, @"GLSL ERROR: shader program would not link:\n%s\n\n%@\n\n", log, shaderDict);
|
||||
OK = NO;
|
||||
}
|
||||
}
|
||||
if (vertex_shader_object != NULL_SHADER) glDeleteObjectARB(vertex_shader_object);
|
||||
if (fragment_shader_object != NULL_SHADER) glDeleteObjectARB(fragment_shader_object);
|
||||
if (!OK && shader_program != NULL_SHADER) glDeleteObjectARB(shader_program);
|
||||
|
||||
if (OK)
|
||||
{
|
||||
// store the resulting program for reuse
|
||||
if (!shaderUniversalDictionary) shaderUniversalDictionary = [[NSMutableDictionary dictionary] retain];
|
||||
[shaderUniversalDictionary setObject: [NSNumber numberWithUnsignedInt: (unsigned int) shader_program] forKey: shaderDict];
|
||||
}
|
||||
|
||||
return OK ? shader_program : NULL_SHADER;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+ (void) reloadTextures
|
||||
{
|
||||
/*
|
||||
FIX_ME: This function is only called when switching between strict and
|
||||
FIXME: This function is only called when switching between strict and
|
||||
non-strict mode, and apparently under some circumstances under GNUstep.
|
||||
It's so old that the dictionary it works on is used for almost exactly
|
||||
the opposite of what it expects. This is why we use classes and
|
||||
@ -943,52 +777,3 @@ void fillSquareImageWithPlanetNMap(unsigned char * imageBuffer, int width, int n
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/* Attempt to load fragment or vertex shader source.
|
||||
Returns YES if source was loaded or no shader was specified, and NO if an
|
||||
external shader was specified but could not be found.
|
||||
*/
|
||||
static BOOL GetShaderSource(NSString *shaderType, NSDictionary *shaderDict, NSString **outResult)
|
||||
{
|
||||
NSString *result = nil;
|
||||
NSString *shaderName = nil;
|
||||
NSArray *extensions = nil;
|
||||
NSEnumerator *extEnum = nil;
|
||||
NSString *extension = nil;
|
||||
NSString *nameWithExtension = nil;
|
||||
|
||||
shaderName = [shaderDict objectForKey:[shaderType stringByAppendingString:@"_shader"]];
|
||||
if (shaderName != nil)
|
||||
{
|
||||
result = [ResourceManager stringFromFilesNamed:shaderName inFolder:@"Shaders"];
|
||||
if (result == nil)
|
||||
{
|
||||
extensions = [NSArray arrayWithObjects:shaderType, [shaderType substringToIndex:4], nil]; // vertex and vert, or fragment and frag
|
||||
|
||||
// Futureproofing -- in future, we may wish to support automatic selection between supported shader languages.
|
||||
if (![shaderName pathHasExtensionInArray:extensions])
|
||||
{
|
||||
for (extEnum = [extensions objectEnumerator]; (extension = [extEnum nextObject]); )
|
||||
{
|
||||
nameWithExtension = [shaderName stringByAppendingPathExtension:extension];
|
||||
result = [ResourceManager stringFromFilesNamed:nameWithExtension
|
||||
inFolder:@"Shaders"];
|
||||
if (result != nil) break;
|
||||
}
|
||||
}
|
||||
if (result == nil)
|
||||
{
|
||||
OOLog(kOOLogFileNotFound, @"GLSL ERROR: failed to find fragment program %@.", shaderName);
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = [shaderDict objectForKey:[@"glsl-" stringByAppendingString:shaderType]];
|
||||
}
|
||||
|
||||
if (outResult != NULL) *outResult = result;
|
||||
return YES;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ MA 02110-1301, USA.
|
||||
#import "legacy_random.h"
|
||||
#import "OOMaths.h"
|
||||
#import "OOColor.h"
|
||||
#import "OOWeakReference.h"
|
||||
|
||||
#define CROSSHAIR_SIZE 32.0
|
||||
|
||||
@ -108,126 +109,128 @@ MA 02110-1301, USA.
|
||||
|
||||
extern int debug;
|
||||
|
||||
@interface Universe : NSObject
|
||||
@interface Universe: NSObject <OOWeakReferenceSupport>
|
||||
{
|
||||
@public
|
||||
// use a sorted list for drawing and other activities
|
||||
//
|
||||
Entity* sortedEntities[UNIVERSE_MAX_ENTITIES];
|
||||
int n_entities;
|
||||
int cursor_row;
|
||||
|
||||
@public
|
||||
// use a sorted list for drawing and other activities
|
||||
//
|
||||
Entity* sortedEntities[UNIVERSE_MAX_ENTITIES];
|
||||
int n_entities;
|
||||
int cursor_row;
|
||||
|
||||
// // collision optimisation sorted lists
|
||||
Entity *x_list_start, *y_list_start, *z_list_start;
|
||||
Entity *x_list_start, *y_list_start, *z_list_start;
|
||||
// //
|
||||
// ////
|
||||
|
||||
// colors
|
||||
//
|
||||
GLfloat sun_diffuse[4];
|
||||
GLfloat sun_specular[4];
|
||||
GLfloat stars_ambient[4];
|
||||
|
||||
GLfloat air_resist_factor;
|
||||
|
||||
int viewDirection; // read only
|
||||
|
||||
@protected
|
||||
MyOpenGLView *gameView;
|
||||
|
||||
#ifndef GNUSTEP
|
||||
NSSpeechSynthesizer* speechSynthesizer; // use this from OS X 10.3 onwards
|
||||
NSArray *speechArray;
|
||||
#endif
|
||||
|
||||
int next_universal_id;
|
||||
Entity* entity_for_uid[MAX_ENTITY_UID];
|
||||
// colors
|
||||
//
|
||||
GLfloat sun_diffuse[4];
|
||||
GLfloat sun_specular[4];
|
||||
GLfloat stars_ambient[4];
|
||||
|
||||
GLfloat air_resist_factor;
|
||||
|
||||
NSMutableArray *entities;
|
||||
|
||||
int station;
|
||||
int sun;
|
||||
int planet;
|
||||
|
||||
int firstBeacon, lastBeacon;
|
||||
|
||||
GLfloat sky_clear_color[4];
|
||||
|
||||
NSString *currentMessage;
|
||||
|
||||
GuiDisplayGen* gui;
|
||||
GuiDisplayGen* message_gui;
|
||||
GuiDisplayGen* comm_log_gui;
|
||||
|
||||
BOOL displayGUI;
|
||||
BOOL displayCursor;
|
||||
|
||||
BOOL reducedDetail;
|
||||
|
||||
BOOL displayFPS;
|
||||
|
||||
double universal_time;
|
||||
double time_delta;
|
||||
double ai_think_time;
|
||||
|
||||
double demo_stage_time;
|
||||
int demo_stage;
|
||||
int demo_ship_index;
|
||||
NSArray *demo_ships;
|
||||
|
||||
GLfloat sun_center_position[4];
|
||||
|
||||
BOOL dumpCollisionInfo;
|
||||
|
||||
NSDictionary *shipdata; // holds data on all ships available, loaded at initialisation
|
||||
NSDictionary *shipyard; // holds data on all ships for sale, loaded at initialisation
|
||||
|
||||
NSDictionary *commoditylists; // holds data on commodities for various types of station, loaded at initialisation
|
||||
NSArray *commoditydata; // holds data on commodities extracted from commoditylists
|
||||
|
||||
NSDictionary *illegal_goods; // holds the legal penalty for illicit commodities, loaded at initialisation
|
||||
NSDictionary *descriptions; // holds descriptive text for lots of stuff, loaded at initialisation
|
||||
NSDictionary *customsounds; // holds descriptive audio for lots of stuff, loaded at initialisation
|
||||
NSDictionary *characters; // holds descriptons of characters
|
||||
NSDictionary *planetinfo; // holds overrides for individual planets, keyed by "g# p#" where g# is the galaxy number 0..7 and p# the planet number 0..255
|
||||
NSDictionary *missiontext; // holds descriptive text for missions, loaded at initialisation
|
||||
NSArray *equipmentdata; // holds data on available equipment, loaded at initialisation
|
||||
|
||||
Random_Seed galaxy_seed;
|
||||
Random_Seed system_seed;
|
||||
Random_Seed target_system_seed;
|
||||
|
||||
Random_Seed systems[256]; // hold pregenerated universe info
|
||||
NSString* system_names[256]; // hold pregenerated universe info
|
||||
BOOL system_found[256]; // holds matches for input strings
|
||||
|
||||
int breakPatternCounter;
|
||||
|
||||
ShipEntity *demo_ship;
|
||||
|
||||
StationEntity* cachedStation;
|
||||
PlanetEntity* cachedPlanet;
|
||||
PlanetEntity* cachedSun;
|
||||
|
||||
BOOL strict;
|
||||
|
||||
BOOL no_update;
|
||||
|
||||
NSMutableDictionary* local_planetinfo_overrides;
|
||||
|
||||
NSException* exception;
|
||||
|
||||
NSMutableArray* activeWormholes;
|
||||
|
||||
NSMutableArray* characterPool;
|
||||
|
||||
CollisionRegion* universeRegion;
|
||||
|
||||
// check and maintain linked lists occasionally
|
||||
BOOL doLinkedListMaintenanceThisUpdate;
|
||||
|
||||
// experimental proc-genned textures
|
||||
BOOL doProcedurallyTexturedPlanets;
|
||||
int viewDirection; // read only
|
||||
|
||||
@protected
|
||||
MyOpenGLView *gameView;
|
||||
|
||||
#ifndef GNUSTEP
|
||||
NSSpeechSynthesizer* speechSynthesizer; // use this from OS X 10.3 onwards
|
||||
NSArray *speechArray;
|
||||
#endif
|
||||
|
||||
int next_universal_id;
|
||||
Entity* entity_for_uid[MAX_ENTITY_UID];
|
||||
|
||||
NSMutableArray *entities;
|
||||
|
||||
int station;
|
||||
int sun;
|
||||
int planet;
|
||||
|
||||
int firstBeacon, lastBeacon;
|
||||
|
||||
GLfloat sky_clear_color[4];
|
||||
|
||||
NSString *currentMessage;
|
||||
|
||||
GuiDisplayGen* gui;
|
||||
GuiDisplayGen* message_gui;
|
||||
GuiDisplayGen* comm_log_gui;
|
||||
|
||||
BOOL displayGUI;
|
||||
BOOL displayCursor;
|
||||
|
||||
BOOL reducedDetail;
|
||||
|
||||
BOOL displayFPS;
|
||||
|
||||
double universal_time;
|
||||
double time_delta;
|
||||
double ai_think_time;
|
||||
|
||||
double demo_stage_time;
|
||||
int demo_stage;
|
||||
int demo_ship_index;
|
||||
NSArray *demo_ships;
|
||||
|
||||
GLfloat sun_center_position[4];
|
||||
|
||||
BOOL dumpCollisionInfo;
|
||||
|
||||
NSDictionary *shipdata; // holds data on all ships available, loaded at initialisation
|
||||
NSDictionary *shipyard; // holds data on all ships for sale, loaded at initialisation
|
||||
|
||||
NSDictionary *commoditylists; // holds data on commodities for various types of station, loaded at initialisation
|
||||
NSArray *commoditydata; // holds data on commodities extracted from commoditylists
|
||||
|
||||
NSDictionary *illegal_goods; // holds the legal penalty for illicit commodities, loaded at initialisation
|
||||
NSDictionary *descriptions; // holds descriptive text for lots of stuff, loaded at initialisation
|
||||
NSDictionary *customsounds; // holds descriptive audio for lots of stuff, loaded at initialisation
|
||||
NSDictionary *characters; // holds descriptons of characters
|
||||
NSDictionary *planetinfo; // holds overrides for individual planets, keyed by "g# p#" where g# is the galaxy number 0..7 and p# the planet number 0..255
|
||||
NSDictionary *missiontext; // holds descriptive text for missions, loaded at initialisation
|
||||
NSArray *equipmentdata; // holds data on available equipment, loaded at initialisation
|
||||
|
||||
Random_Seed galaxy_seed;
|
||||
Random_Seed system_seed;
|
||||
Random_Seed target_system_seed;
|
||||
|
||||
Random_Seed systems[256]; // hold pregenerated universe info
|
||||
NSString* system_names[256]; // hold pregenerated universe info
|
||||
BOOL system_found[256]; // holds matches for input strings
|
||||
|
||||
int breakPatternCounter;
|
||||
|
||||
ShipEntity *demo_ship;
|
||||
|
||||
StationEntity* cachedStation;
|
||||
PlanetEntity* cachedPlanet;
|
||||
PlanetEntity* cachedSun;
|
||||
|
||||
BOOL strict;
|
||||
|
||||
BOOL no_update;
|
||||
|
||||
NSMutableDictionary* local_planetinfo_overrides;
|
||||
|
||||
NSException* exception;
|
||||
|
||||
NSMutableArray* activeWormholes;
|
||||
|
||||
NSMutableArray* characterPool;
|
||||
|
||||
CollisionRegion* universeRegion;
|
||||
|
||||
// check and maintain linked lists occasionally
|
||||
BOOL doLinkedListMaintenanceThisUpdate;
|
||||
|
||||
// experimental proc-genned textures
|
||||
BOOL doProcedurallyTexturedPlanets;
|
||||
|
||||
OOWeakReference *weakSelf;
|
||||
}
|
||||
|
||||
- (BOOL) doProcedurallyTexturedPlanets;
|
||||
|
@ -276,9 +276,25 @@ static BOOL MaintainLinkedLists(Universe* uni);
|
||||
|
||||
[[OOCacheManager sharedCache] flush];
|
||||
|
||||
[weakSelf weakRefDrop];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
- (id)weakRetain
|
||||
{
|
||||
if (weakSelf == nil) weakSelf = [OOWeakReference weakRefWithObject:self];
|
||||
return [weakSelf retain];
|
||||
}
|
||||
|
||||
|
||||
- (void)weakRefDied:(OOWeakReference *)weakRef
|
||||
{
|
||||
if (weakRef == weakSelf) weakSelf = nil;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL) doProcedurallyTexturedPlanets
|
||||
{
|
||||
return doProcedurallyTexturedPlanets;
|
||||
|
Loading…
x
Reference in New Issue
Block a user