mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-02-18 15:30:30 +00:00
Apple2Mac first cut and refactor common rendering code
* Based on NSOpenGLView and Apple's GLEssentials sample code * CVDisplayLink- or NSTimer-driven rendering * Works in window or fullscreen mode on Mac OSX Lion or later TODO FIXME: * Breaks Linux/Posix build * Cocoa menu interfaces * Key/mouse/joystick/gamepad handling
This commit is contained in:
parent
f794098a02
commit
6858e51a75
@ -11,8 +11,6 @@
|
||||
773B3D1A1956885A0085CE5F /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 773B3D181956885A0085CE5F /* InfoPlist.strings */; };
|
||||
773B3D1C1956885A0085CE5F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 773B3D1B1956885A0085CE5F /* main.m */; };
|
||||
773B3D201956885A0085CE5F /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 773B3D1E1956885A0085CE5F /* Credits.rtf */; };
|
||||
773B3D231956885A0085CE5F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 773B3D221956885A0085CE5F /* AppDelegate.m */; };
|
||||
773B3D261956885A0085CE5F /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 773B3D241956885A0085CE5F /* MainMenu.xib */; };
|
||||
773B3D281956885A0085CE5F /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 773B3D271956885A0085CE5F /* Images.xcassets */; };
|
||||
773B3DA019568A570085CE5F /* cpu-supp.c in Sources */ = {isa = PBXBuildFile; fileRef = 773B3D5D19568A570085CE5F /* cpu-supp.c */; };
|
||||
773B3DA219568A570085CE5F /* darwin-shim.c in Sources */ = {isa = PBXBuildFile; fileRef = 773B3D6019568A570085CE5F /* darwin-shim.c */; };
|
||||
@ -32,7 +30,6 @@
|
||||
773B3DC019568A570085CE5F /* darwin-glue.S in Sources */ = {isa = PBXBuildFile; fileRef = 773B3D9119568A570085CE5F /* darwin-glue.S */; };
|
||||
773B3DC319568A570085CE5F /* zlib-helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = 773B3D9519568A570085CE5F /* zlib-helpers.c */; };
|
||||
773B3DCB1956903D0085CE5F /* libz.1.1.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 773B3DCA1956903D0085CE5F /* libz.1.1.3.dylib */; };
|
||||
773B3DD3195697290085CE5F /* EmulatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 773B3DD2195697290085CE5F /* EmulatorView.m */; };
|
||||
779DD827195764E200DF89E5 /* rom-shim.c in Sources */ = {isa = PBXBuildFile; fileRef = 779DD826195764E200DF89E5 /* rom-shim.c */; };
|
||||
779DD82F195BD9F900DF89E5 /* cpu.S in Sources */ = {isa = PBXBuildFile; fileRef = 773B3D9019568A570085CE5F /* cpu.S */; };
|
||||
779DD830195BD9F900DF89E5 /* prefs.c in Sources */ = {isa = PBXBuildFile; fileRef = 773B3D7719568A570085CE5F /* prefs.c */; };
|
||||
@ -62,6 +59,18 @@
|
||||
779DD852195BDA3000DF89E5 /* testcpu.c in Sources */ = {isa = PBXBuildFile; fileRef = 773B3D7E19568A570085CE5F /* testcpu.c */; };
|
||||
779DD853195BDA3400DF89E5 /* testcommon.c in Sources */ = {isa = PBXBuildFile; fileRef = 773B3D7C19568A570085CE5F /* testcommon.c */; };
|
||||
779DD856195BDB1700DF89E5 /* CPUTestAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 779DD854195BDB1700DF89E5 /* CPUTestAppDelegate.m */; };
|
||||
779F561C19D7929100A6F107 /* glvideo.c in Sources */ = {isa = PBXBuildFile; fileRef = 77E1C0C719D736EB004344E0 /* glvideo.c */; };
|
||||
779F562119DA584800A6F107 /* Basic.vert in Resources */ = {isa = PBXBuildFile; fileRef = 779F561D19D79AC000A6F107 /* Basic.vert */; };
|
||||
779F562219DA585200A6F107 /* Basic.frag in Resources */ = {isa = PBXBuildFile; fileRef = 779F561E19D79AC000A6F107 /* Basic.frag */; };
|
||||
779F562319DA59D600A6F107 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 773B3D241956885A0085CE5F /* MainMenu.xib */; };
|
||||
77E1C0B319D72700004344E0 /* vectorUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = 77E1C0A919D72700004344E0 /* vectorUtil.c */; };
|
||||
77E1C0B419D72700004344E0 /* sourceUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = 77E1C0AB19D72700004344E0 /* sourceUtil.c */; };
|
||||
77E1C0B519D72700004344E0 /* modelUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = 77E1C0AD19D72700004344E0 /* modelUtil.c */; };
|
||||
77E1C0B619D72700004344E0 /* matrixUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = 77E1C0AF19D72700004344E0 /* matrixUtil.c */; };
|
||||
77E1C0B719D72700004344E0 /* imageUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 77E1C0B019D72700004344E0 /* imageUtil.m */; };
|
||||
77E1C0C419D7298F004344E0 /* EmulatorWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 77E1C0BE19D7298F004344E0 /* EmulatorWindowController.m */; };
|
||||
77E1C0C519D7298F004344E0 /* EmulatorGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 77E1C0C019D7298F004344E0 /* EmulatorGLView.m */; };
|
||||
77E1C0C619D7298F004344E0 /* EmulatorFullscreenWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 77E1C0C219D7298F004344E0 /* EmulatorFullscreenWindow.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@ -75,8 +84,6 @@
|
||||
773B3D1B1956885A0085CE5F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
773B3D1D1956885A0085CE5F /* Apple2Mac-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Apple2Mac-Prefix.pch"; sourceTree = "<group>"; };
|
||||
773B3D1F1956885A0085CE5F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = en.lproj/Credits.rtf; sourceTree = "<group>"; };
|
||||
773B3D211956885A0085CE5F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
|
||||
773B3D221956885A0085CE5F /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||
773B3D251956885A0085CE5F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
773B3D271956885A0085CE5F /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||
773B3D2E1956885A0085CE5F /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
@ -122,13 +129,34 @@
|
||||
773B3D9519568A570085CE5F /* zlib-helpers.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "zlib-helpers.c"; sourceTree = "<group>"; };
|
||||
773B3D9619568A570085CE5F /* zlib-helpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "zlib-helpers.h"; sourceTree = "<group>"; };
|
||||
773B3DCA1956903D0085CE5F /* libz.1.1.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.1.3.dylib; path = usr/lib/libz.1.1.3.dylib; sourceTree = SDKROOT; };
|
||||
773B3DD1195697290085CE5F /* EmulatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EmulatorView.h; sourceTree = "<group>"; };
|
||||
773B3DD2195697290085CE5F /* EmulatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EmulatorView.m; sourceTree = "<group>"; };
|
||||
779DD826195764E200DF89E5 /* rom-shim.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "rom-shim.c"; sourceTree = "<group>"; };
|
||||
779DD850195BD9F900DF89E5 /* Apple2MacTestCPU.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Apple2MacTestCPU.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
779DD851195BD9F900DF89E5 /* Apple2MacTestCPU-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Apple2MacTestCPU-Info.plist"; path = "/Users/aaronculliney/Documents/00web/apple2/Apple2Mac/Apple2MacTests/Apple2MacTestCPU-Info.plist"; sourceTree = "<absolute>"; };
|
||||
779DD854195BDB1700DF89E5 /* CPUTestAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CPUTestAppDelegate.m; sourceTree = "<group>"; };
|
||||
779DD855195BDB1700DF89E5 /* CPUTestAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CPUTestAppDelegate.h; sourceTree = "<group>"; };
|
||||
779F561B19D78B8200A6F107 /* renderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = renderer.h; sourceTree = "<group>"; };
|
||||
779F561D19D79AC000A6F107 /* Basic.vert */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = Basic.vert; sourceTree = "<group>"; };
|
||||
779F561E19D79AC000A6F107 /* Basic.frag */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = Basic.frag; sourceTree = "<group>"; };
|
||||
77E1C0A119D726C9004344E0 /* character.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = character.vsh; path = Shaders/character.vsh; sourceTree = "<group>"; };
|
||||
77E1C0A219D726C9004344E0 /* character.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = character.fsh; path = Shaders/character.fsh; sourceTree = "<group>"; };
|
||||
77E1C0A819D72700004344E0 /* vectorUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vectorUtil.h; path = video_util/vectorUtil.h; sourceTree = "<group>"; };
|
||||
77E1C0A919D72700004344E0 /* vectorUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vectorUtil.c; path = video_util/vectorUtil.c; sourceTree = "<group>"; };
|
||||
77E1C0AA19D72700004344E0 /* sourceUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sourceUtil.h; path = video_util/sourceUtil.h; sourceTree = "<group>"; };
|
||||
77E1C0AB19D72700004344E0 /* sourceUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sourceUtil.c; path = video_util/sourceUtil.c; sourceTree = "<group>"; };
|
||||
77E1C0AC19D72700004344E0 /* modelUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = modelUtil.h; path = video_util/modelUtil.h; sourceTree = "<group>"; };
|
||||
77E1C0AD19D72700004344E0 /* modelUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = modelUtil.c; path = video_util/modelUtil.c; sourceTree = "<group>"; };
|
||||
77E1C0AE19D72700004344E0 /* matrixUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = matrixUtil.h; path = video_util/matrixUtil.h; sourceTree = "<group>"; };
|
||||
77E1C0AF19D72700004344E0 /* matrixUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = matrixUtil.c; path = video_util/matrixUtil.c; sourceTree = "<group>"; };
|
||||
77E1C0B019D72700004344E0 /* imageUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = imageUtil.m; path = video_util/imageUtil.m; sourceTree = "<group>"; };
|
||||
77E1C0B119D72700004344E0 /* imageUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imageUtil.h; path = video_util/imageUtil.h; sourceTree = "<group>"; };
|
||||
77E1C0B219D72700004344E0 /* glUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = glUtil.h; path = video_util/glUtil.h; sourceTree = "<group>"; };
|
||||
77E1C0BE19D7298F004344E0 /* EmulatorWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EmulatorWindowController.m; path = Classes/OSX/EmulatorWindowController.m; sourceTree = "<group>"; };
|
||||
77E1C0BF19D7298F004344E0 /* EmulatorWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EmulatorWindowController.h; path = Classes/OSX/EmulatorWindowController.h; sourceTree = "<group>"; };
|
||||
77E1C0C019D7298F004344E0 /* EmulatorGLView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EmulatorGLView.m; path = Classes/OSX/EmulatorGLView.m; sourceTree = "<group>"; };
|
||||
77E1C0C119D7298F004344E0 /* EmulatorGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EmulatorGLView.h; path = Classes/OSX/EmulatorGLView.h; sourceTree = "<group>"; };
|
||||
77E1C0C219D7298F004344E0 /* EmulatorFullscreenWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EmulatorFullscreenWindow.m; path = Classes/OSX/EmulatorFullscreenWindow.m; sourceTree = "<group>"; };
|
||||
77E1C0C319D7298F004344E0 /* EmulatorFullscreenWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EmulatorFullscreenWindow.h; path = Classes/OSX/EmulatorFullscreenWindow.h; sourceTree = "<group>"; };
|
||||
77E1C0C719D736EB004344E0 /* glvideo.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = glvideo.c; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -198,6 +226,7 @@
|
||||
children = (
|
||||
773B3D4519568A570085CE5F /* src */,
|
||||
773B3D431956897D0085CE5F /* Classes */,
|
||||
77E1C09E19D726B8004344E0 /* Shaders */,
|
||||
773B3D44195689910085CE5F /* Resources */,
|
||||
773B3D161956885A0085CE5F /* Supporting Files */,
|
||||
);
|
||||
@ -239,10 +268,12 @@
|
||||
773B3D431956897D0085CE5F /* Classes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
773B3D211956885A0085CE5F /* AppDelegate.h */,
|
||||
773B3D221956885A0085CE5F /* AppDelegate.m */,
|
||||
773B3DD1195697290085CE5F /* EmulatorView.h */,
|
||||
773B3DD2195697290085CE5F /* EmulatorView.m */,
|
||||
77E1C0BE19D7298F004344E0 /* EmulatorWindowController.m */,
|
||||
77E1C0BF19D7298F004344E0 /* EmulatorWindowController.h */,
|
||||
77E1C0C019D7298F004344E0 /* EmulatorGLView.m */,
|
||||
77E1C0C119D7298F004344E0 /* EmulatorGLView.h */,
|
||||
77E1C0C219D7298F004344E0 /* EmulatorFullscreenWindow.m */,
|
||||
77E1C0C319D7298F004344E0 /* EmulatorFullscreenWindow.h */,
|
||||
);
|
||||
name = Classes;
|
||||
sourceTree = "<group>";
|
||||
@ -284,6 +315,7 @@
|
||||
773B3D8819568A570085CE5F /* timing.h */,
|
||||
773B3D8919568A570085CE5F /* uthash.h */,
|
||||
773B3D8A19568A570085CE5F /* video */,
|
||||
77E1C0A719D726E8004344E0 /* video_util */,
|
||||
773B3D8D19568A570085CE5F /* vm.c */,
|
||||
773B3D8E19568A570085CE5F /* x86 */,
|
||||
773B3D9519568A570085CE5F /* zlib-helpers.c */,
|
||||
@ -321,7 +353,11 @@
|
||||
773B3D8A19568A570085CE5F /* video */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
779F561D19D79AC000A6F107 /* Basic.vert */,
|
||||
779F561E19D79AC000A6F107 /* Basic.frag */,
|
||||
77E1C0C719D736EB004344E0 /* glvideo.c */,
|
||||
773B3D8B19568A570085CE5F /* video.h */,
|
||||
779F561B19D78B8200A6F107 /* renderer.h */,
|
||||
);
|
||||
path = video;
|
||||
sourceTree = "<group>";
|
||||
@ -337,6 +373,33 @@
|
||||
path = x86;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
77E1C09E19D726B8004344E0 /* Shaders */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
77E1C0A119D726C9004344E0 /* character.vsh */,
|
||||
77E1C0A219D726C9004344E0 /* character.fsh */,
|
||||
);
|
||||
name = Shaders;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
77E1C0A719D726E8004344E0 /* video_util */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
77E1C0A819D72700004344E0 /* vectorUtil.h */,
|
||||
77E1C0A919D72700004344E0 /* vectorUtil.c */,
|
||||
77E1C0AA19D72700004344E0 /* sourceUtil.h */,
|
||||
77E1C0AB19D72700004344E0 /* sourceUtil.c */,
|
||||
77E1C0AC19D72700004344E0 /* modelUtil.h */,
|
||||
77E1C0AD19D72700004344E0 /* modelUtil.c */,
|
||||
77E1C0AE19D72700004344E0 /* matrixUtil.h */,
|
||||
77E1C0AF19D72700004344E0 /* matrixUtil.c */,
|
||||
77E1C0B019D72700004344E0 /* imageUtil.m */,
|
||||
77E1C0B119D72700004344E0 /* imageUtil.h */,
|
||||
77E1C0B219D72700004344E0 /* glUtil.h */,
|
||||
);
|
||||
name = video_util;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@ -413,8 +476,10 @@
|
||||
files = (
|
||||
773B3D1A1956885A0085CE5F /* InfoPlist.strings in Resources */,
|
||||
773B3D281956885A0085CE5F /* Images.xcassets in Resources */,
|
||||
779F562219DA585200A6F107 /* Basic.frag in Resources */,
|
||||
773B3D201956885A0085CE5F /* Credits.rtf in Resources */,
|
||||
773B3D261956885A0085CE5F /* MainMenu.xib in Resources */,
|
||||
779F562119DA584800A6F107 /* Basic.vert in Resources */,
|
||||
779F562319DA59D600A6F107 /* MainMenu.xib in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -500,20 +565,27 @@
|
||||
773B3DA419568A570085CE5F /* display.c in Sources */,
|
||||
773B3DA319568A570085CE5F /* disk.c in Sources */,
|
||||
773B3DAD19568A570085CE5F /* debugger.c in Sources */,
|
||||
77E1C0B319D72700004344E0 /* vectorUtil.c in Sources */,
|
||||
773B3DAB19568A570085CE5F /* keys.c in Sources */,
|
||||
773B3DBC19568A570085CE5F /* timing.c in Sources */,
|
||||
773B3DAF19568A570085CE5F /* misc.c in Sources */,
|
||||
77E1C0C419D7298F004344E0 /* EmulatorWindowController.m in Sources */,
|
||||
77E1C0B619D72700004344E0 /* matrixUtil.c in Sources */,
|
||||
77E1C0C519D7298F004344E0 /* EmulatorGLView.m in Sources */,
|
||||
773B3DAE19568A570085CE5F /* opcodes.c in Sources */,
|
||||
779DD827195764E200DF89E5 /* rom-shim.c in Sources */,
|
||||
773B3DC319568A570085CE5F /* zlib-helpers.c in Sources */,
|
||||
77E1C0B719D72700004344E0 /* imageUtil.m in Sources */,
|
||||
773B3DA219568A570085CE5F /* darwin-shim.c in Sources */,
|
||||
773B3D231956885A0085CE5F /* AppDelegate.m in Sources */,
|
||||
77E1C0B519D72700004344E0 /* modelUtil.c in Sources */,
|
||||
773B3DAC19568A570085CE5F /* debug.l in Sources */,
|
||||
77E1C0C619D7298F004344E0 /* EmulatorFullscreenWindow.m in Sources */,
|
||||
773B3DA519568A570085CE5F /* font.c in Sources */,
|
||||
773B3DA019568A570085CE5F /* cpu-supp.c in Sources */,
|
||||
779F561C19D7929100A6F107 /* glvideo.c in Sources */,
|
||||
77E1C0B419D72700004344E0 /* sourceUtil.c in Sources */,
|
||||
773B3DBE19568A570085CE5F /* vm.c in Sources */,
|
||||
773B3DC019568A570085CE5F /* darwin-glue.S in Sources */,
|
||||
773B3DD3195697290085CE5F /* EmulatorView.m in Sources */,
|
||||
773B3D1C1956885A0085CE5F /* main.m in Sources */,
|
||||
773B3DAA19568A570085CE5F /* joystick.c in Sources */,
|
||||
);
|
||||
|
@ -1,15 +0,0 @@
|
||||
//
|
||||
// AppDelegate.h
|
||||
// Apple2Mac
|
||||
//
|
||||
// Created by Aaron Culliney on 6/21/14.
|
||||
// Copyright (c) 2014 deadc0de.org. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
@property (assign) IBOutlet NSWindow *window;
|
||||
|
||||
@end
|
@ -1,27 +0,0 @@
|
||||
//
|
||||
// AppDelegate.m
|
||||
// Apple2Mac
|
||||
//
|
||||
// Created by Aaron Culliney on 6/21/14.
|
||||
// Copyright (c) 2014 deadc0de.org. All rights reserved.
|
||||
//
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
#import "common.h"
|
||||
|
||||
extern void c_initialize_firsttime(void);
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
#if 0
|
||||
c_initialize_firsttime();
|
||||
|
||||
// spin off cpu thread
|
||||
pthread_create(&cpu_thread_id, NULL, (void *) &cpu_thread, (void *)NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
@ -1,664 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13D65" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment version="1060" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
|
||||
<outlet property="delegate" destination="494" id="495"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate">
|
||||
<connections>
|
||||
<outlet property="window" destination="QvC-M9-y7g" id="gIp-Ho-8D9"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
|
||||
<menu title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||
<menu title="AMainMenu" systemMenu="main" id="29">
|
||||
<items>
|
||||
<menuItem title="Apple2Mac" id="1Xt-HY-uBw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Apple2Mac" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<menuItem title="Apple2Mac" id="56">
|
||||
<menu key="submenu" title="Apple2Mac" systemMenu="apple" id="57">
|
||||
<items>
|
||||
<menuItem title="About Apple2Mac" id="5kV-Vb-QxS">
|
||||
<menuItem title="About Apple2Mac" id="58">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-1" id="Exp-CZ-Vem"/>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
|
||||
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
||||
<menuItem title="Services" id="NMo-om-nkz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
||||
<menuItem isSeparatorItem="YES" id="236">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
||||
<menuItem title="Hide Apple2Mac" keyEquivalent="h" id="Olw-nP-bQN">
|
||||
<menuItem title="Toggle Full Screen..." keyEquivalent="F" id="rP9-cs-9dM">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="PnN-Uc-m68"/>
|
||||
<action selector="toggleFullScreen:" target="M8b-ga-iOS" id="Xan-eQ-CRM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
|
||||
<menuItem isSeparatorItem="YES" id="143">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Services" id="131">
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="130"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="144">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Apple2Mac" keyEquivalent="h" id="134">
|
||||
<connections>
|
||||
<action selector="hide:" target="-1" id="367"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="145">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="-1" id="VT4-aY-XCT"/>
|
||||
<action selector="hideOtherApplications:" target="-1" id="368"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="Kd2-mp-pUS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menuItem title="Show All" id="150">
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="-1" id="Dhg-Le-xox"/>
|
||||
<action selector="unhideAllApplications:" target="-1" id="370"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
||||
<menuItem title="Quit Apple2Mac" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<menuItem isSeparatorItem="YES" id="149">
|
||||
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
|
||||
</menuItem>
|
||||
<menuItem title="Quit Apple2Mac" keyEquivalent="q" id="136">
|
||||
<connections>
|
||||
<action selector="terminate:" target="-1" id="Te7-pn-YzF"/>
|
||||
<action selector="terminate:" target="-3" id="449"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="dMs-cI-mzQ">
|
||||
<menuItem title="Help" id="490">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="File" id="bib-Uj-vzu">
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="491">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
|
||||
<menuItem title="Apple2Mac Help" keyEquivalent="?" id="492" userLabel="Menu Item - Apple2Mac Help">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="-1" id="4Si-XN-c54"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="-1" id="bVn-NM-KNZ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="tXI-mr-wws">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="vNY-rz-j42">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="-1" id="Daa-9d-B3U"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
|
||||
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
|
||||
<connections>
|
||||
<action selector="performClose:" target="-1" id="HmO-Ls-i7Q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="-1" id="teZ-XB-qJY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
|
||||
<connections>
|
||||
<action selector="saveDocumentAs:" target="-1" id="mDf-zr-I0C"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" id="KaW-ft-85H">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="-1" id="iJ3-Pv-kwq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
|
||||
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="runPageLayout:" target="-1" id="Din-rz-gC5"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
|
||||
<connections>
|
||||
<action selector="print:" target="-1" id="qaZ-4w-aoO"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="5QF-Oa-p0T">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
|
||||
<connections>
|
||||
<action selector="undo:" target="-1" id="M6e-cu-g7V"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
|
||||
<connections>
|
||||
<action selector="redo:" target="-1" id="oIA-Rs-6OD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
|
||||
<connections>
|
||||
<action selector="cut:" target="-1" id="YJe-68-I9s"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
|
||||
<connections>
|
||||
<action selector="copy:" target="-1" id="G1f-GL-Joy"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
|
||||
<connections>
|
||||
<action selector="paste:" target="-1" id="UvS-8e-Qdg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="-1" id="cEh-KX-wJQ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="pa3-QI-u2k">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="delete:" target="-1" id="0Mk-Ml-PaM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="-1" id="VNm-Mi-diN"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
|
||||
<menuItem title="Find" id="4EN-yA-p0u">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Find" id="1b7-l0-nxx">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="cD7-Qs-BN4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="WD3-Gg-5AJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="NDo-RZ-v9R"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="HOh-sY-3ay"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="-1" id="U76-nv-p5D"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="-1" id="IOG-6D-g5B"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="-1" id="vFj-Ks-hy3"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="-1" id="fz7-VC-reM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
|
||||
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="-1" id="7w6-Qz-0kB"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="-1" id="muD-Qn-j4w"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="2lM-Qi-WAP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Substitutions" id="9ic-FL-obx">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="oku-mr-iSq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
|
||||
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="-1" id="3IJ-Se-DZD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="ptq-xd-QOA"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="oCt-pO-9gS"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" id="cwL-P1-jid">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="-1" id="Gip-E3-Fov"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Data Detectors" id="tRr-pd-1PS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDataDetection:" target="-1" id="R1I-Nq-Kbl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="-1" id="DvP-Fe-Py6"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Transformations" id="2oI-Rn-ZJC">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="-1" id="sPh-Tk-edu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="-1" id="iUZ-b5-hil"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="-1" id="26H-TL-nsh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Speech" id="xrE-MZ-jX0">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="-1" id="654-Ng-kyl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="-1" id="dX8-6p-jy9"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Format" id="jxT-CU-nIS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Format" id="GEO-Iw-cKr">
|
||||
<items>
|
||||
<menuItem title="Font" id="Gi5-1S-RQB">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
|
||||
<connections>
|
||||
<action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
|
||||
<connections>
|
||||
<action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
|
||||
<connections>
|
||||
<action selector="underline:" target="-1" id="FYS-2b-JAY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
|
||||
<connections>
|
||||
<action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
|
||||
<menuItem title="Kern" id="jBQ-r6-VK2">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Kern" id="tlD-Oa-oAM">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="GUa-eO-cwY">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="-1" id="6dk-9l-Ckg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="cDB-IK-hbR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="-1" id="U8a-gz-Maa"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="46P-cB-AYj">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="-1" id="hr7-Nz-8ro"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="ogc-rX-tC1">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="-1" id="8i4-f9-FKE"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Ligatures" id="o6e-r0-MWq">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="agt-UL-0e3">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="-1" id="7uR-wd-Dx6"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="J7y-lM-qPV">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="-1" id="iX2-gA-Ilz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="xQD-1f-W4t">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="-1" id="KcB-kA-TuK"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Baseline" id="OaQ-X3-Vso">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Baseline" id="ijk-EB-dga">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="3Om-Ey-2VK">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="-1" id="0vZ-95-Ywn"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="Rqc-34-cIF">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="-1" id="3qV-fo-wpU"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="I0S-gh-46l">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="-1" id="Q6W-4W-IGz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="2h7-ER-AoG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="-1" id="4sk-31-7Q9"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="1tx-W0-xDw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="-1" id="OF1-bc-KW4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="-1" id="mSX-Xz-DV3"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="-1" id="GJO-xA-L4q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="-1" id="JfD-CL-leO"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Text" id="Fal-I4-PZk">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="d9c-me-L2H">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="-1" id="zUv-R1-uAa"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="-1" id="spX-mk-kcS"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="J5U-5w-g23">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="-1" id="ljL-7U-jND"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="-1" id="r48-bG-YeY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
|
||||
<menuItem title="Writing Direction" id="H1b-Si-o9J">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
|
||||
<items>
|
||||
<menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="YGs-j5-SAR">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="-1" id="qtV-5e-UBP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="Lbh-J2-qVU">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="-1" id="S0X-9S-QSf"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="jFq-tB-4Kx">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="-1" id="5fk-qB-AqJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
|
||||
<menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="Nop-cj-93Q">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="-1" id="lPI-Se-ZHp"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="BgM-ve-c93">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="-1" id="caW-Bv-w94"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="RB4-Sm-HuC">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="-1" id="EXD-6r-ZUu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
|
||||
<menuItem title="Show Ruler" id="vLm-3I-IUL">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="-1" id="FOx-HJ-KwY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="-1" id="71i-fW-3W2"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="-1" id="cSh-wd-qM2"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="H8h-7b-M4v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="View" id="HyV-fh-RgO">
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="-1" id="BXY-wc-z0C"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="-1" id="pQI-g3-MTW"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="aUF-d1-5bR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="-1" id="VwT-WD-YPe"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="performZoom:" target="-1" id="DIl-cC-cCs"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="-1" id="DRN-fu-gQh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="wpr-3q-Mcd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
|
||||
<items>
|
||||
<menuItem title="Apple2Mac Help" keyEquivalent="?" id="FKE-Sm-Kum">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="-1" id="y7X-2Q-9no"/>
|
||||
<action selector="showHelp:" target="-1" id="493"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
@ -666,15 +82,22 @@
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<window title="Apple2Mac" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="QvC-M9-y7g">
|
||||
<window title="Apple2Mac" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371" userLabel="Window - Apple2Mac">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="335" y="390" width="480" height="360"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1280" height="778"/>
|
||||
<view key="contentView" id="EiT-Mj-1SZ" customClass="EmulatorView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="360"/>
|
||||
<rect key="contentRect" x="200" y="200" width="320" height="480"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1178"/>
|
||||
<view key="contentView" id="372" customClass="EmulatorGLView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</view>
|
||||
</window>
|
||||
<customObject id="494" userLabel="GL Essentials View" customClass="EmulatorGLView"/>
|
||||
<customObject id="M8b-ga-iOS" userLabel="GL Essentials Window Controller" customClass="EmulatorWindowController" colorLabel="IBBuiltInLabel-Blue">
|
||||
<connections>
|
||||
<outlet property="view" destination="372" id="pRG-Kn-92X"/>
|
||||
<outlet property="window" destination="371" id="z3B-S9-PsV"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
</objects>
|
||||
</document>
|
||||
|
15
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorFullscreenWindow.h
Normal file
15
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorFullscreenWindow.h
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// EmulatorFullscreenWindow.h
|
||||
// Apple2Mac
|
||||
//
|
||||
// Created by Aaron Culliney on 9/27/14.
|
||||
// Copyright (c) 2014 deadc0de.org. All rights reserved.
|
||||
//
|
||||
|
||||
// Based on sample code from https://developer.apple.com/library/mac/samplecode/GLEssentials/Introduction/Intro.html
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface EmulatorFullscreenWindow : NSWindow
|
||||
|
||||
@end
|
48
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorFullscreenWindow.m
Normal file
48
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorFullscreenWindow.m
Normal file
@ -0,0 +1,48 @@
|
||||
//
|
||||
// EmulatorFullscreenWindow.m
|
||||
// Apple2Mac
|
||||
//
|
||||
// Created by Aaron Culliney on 9/27/14.
|
||||
// Copyright (c) 2014 deadc0de.org. All rights reserved.
|
||||
//
|
||||
|
||||
// Based on sample code from https://developer.apple.com/library/mac/samplecode/GLEssentials/Introduction/Intro.html
|
||||
|
||||
#import "EmulatorFullscreenWindow.h"
|
||||
|
||||
@implementation EmulatorFullscreenWindow
|
||||
|
||||
- (id)init
|
||||
{
|
||||
// Create a screen-sized window on the display you want to take over
|
||||
NSRect screenRect = [[NSScreen mainScreen] frame];
|
||||
|
||||
// Initialize the window making it size of the screen and borderless
|
||||
self = [super initWithContentRect:screenRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES];
|
||||
|
||||
// Set the window level to be above the menu bar to cover everything else
|
||||
[self setLevel:NSMainMenuWindowLevel+1];
|
||||
|
||||
// Set opaque
|
||||
[self setOpaque:YES];
|
||||
|
||||
// Hide this when user switches to another window (or app)
|
||||
[self setHidesOnDeactivate:YES];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)canBecomeKeyWindow
|
||||
{
|
||||
// Return yes so that this borderless window can receive input
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent *)event
|
||||
{
|
||||
// Implement keyDown since controller will not get [ESC] key event which
|
||||
// the controller uses to kill fullscreen
|
||||
[[self windowController] keyDown:event];
|
||||
}
|
||||
|
||||
@end
|
18
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorGLView.h
Normal file
18
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorGLView.h
Normal file
@ -0,0 +1,18 @@
|
||||
//
|
||||
// EmulatorGLView.h
|
||||
// Apple2Mac
|
||||
//
|
||||
// Created by Aaron Culliney on 9/27/14.
|
||||
// Copyright (c) 2014 deadc0de.org. All rights reserved.
|
||||
//
|
||||
|
||||
// Based on sample code from https://developer.apple.com/library/mac/samplecode/GLEssentials/Introduction/Intro.html
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <QuartzCore/CVDisplayLink.h>
|
||||
|
||||
#import "modelUtil.h"
|
||||
#import "imageUtil.h"
|
||||
|
||||
@interface EmulatorGLView : NSOpenGLView
|
||||
@end
|
304
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorGLView.m
Normal file
304
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorGLView.m
Normal file
@ -0,0 +1,304 @@
|
||||
//
|
||||
// EmulatorGLView.m
|
||||
// Apple2Mac
|
||||
//
|
||||
// Created by Aaron Culliney on 9/27/14.
|
||||
// Copyright (c) 2014 deadc0de.org. All rights reserved.
|
||||
//
|
||||
|
||||
// Based on sample code from https://developer.apple.com/library/mac/samplecode/GLEssentials/Introduction/Intro.html
|
||||
|
||||
#import "EmulatorGLView.h"
|
||||
|
||||
// Apple //e common routines
|
||||
#import "common.h"
|
||||
#import "video/renderer.h"
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#define USE_DISPLAYLINK 0
|
||||
#define BROKEN_DISPLAYLINK 1
|
||||
#else
|
||||
// iOS uses CADisplayLink
|
||||
#define USE_DISPLAYLINK 1
|
||||
#endif
|
||||
|
||||
|
||||
#define SUPPORT_RETINA_RESOLUTION 1
|
||||
|
||||
@interface EmulatorGLView ()
|
||||
|
||||
#if USE_DISPLAYLINK
|
||||
@property (nonatomic, assign) CVDisplayLinkRef displayLink;
|
||||
#else
|
||||
@property (nonatomic, retain) NSTimer *timer;
|
||||
#endif
|
||||
|
||||
- (void)initGL;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation EmulatorGLView
|
||||
|
||||
#if USE_DISPLAYLINK
|
||||
@synthesize displayLink = _displayLink;
|
||||
#else
|
||||
@synthesize timer = _timer;
|
||||
#endif
|
||||
|
||||
#pragma mark CVDisplayLink / NSTimer stuff
|
||||
|
||||
#if USE_DISPLAYLINK
|
||||
- (CVReturn)getFrameForTime:(const CVTimeStamp *)outputTime
|
||||
{
|
||||
// There is no autorelease pool when this method is called
|
||||
// because it will be called from a background thread.
|
||||
// It's important to create one or app can leak objects.
|
||||
@autoreleasepool {
|
||||
// We draw on a secondary thread through the display link
|
||||
// When resizing the view, -reshape is called automatically on the main
|
||||
// thread. Add a mutex around to avoid the threads accessing the context
|
||||
// simultaneously when resizing
|
||||
|
||||
#if BROKEN_DISPLAYLINK
|
||||
#warning ASC NOTE 2014/09/27 multi-threaded OpenGL on Mac considered harmful to developer sanity
|
||||
// 2014/09/27 Kinda defeats the purpose of using CVDisplayLink ... but keeps it from crashing to dispatch to main queue
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
#endif
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
[self drawView];
|
||||
#if BROKEN_DISPLAYLINK
|
||||
});
|
||||
#endif
|
||||
}
|
||||
return kCVReturnSuccess;
|
||||
}
|
||||
|
||||
// This is the renderer output callback function
|
||||
static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *now, const CVTimeStamp *outputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext)
|
||||
{
|
||||
CVReturn result = [(EmulatorGLView *)displayLinkContext getFrameForTime:outputTime];
|
||||
return result;
|
||||
}
|
||||
|
||||
#else // use NSTimer
|
||||
- (void)targetMethod:(NSTimer *)theTimer
|
||||
{
|
||||
NSAssert([NSThread isMainThread], @"Timer fired on non-main thread!");
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
[self drawView];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
NSOpenGLPixelFormatAttribute attrs[] =
|
||||
{
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFADepthSize, 24,
|
||||
// Must specify the 3.2 Core Profile to use OpenGL 3.2
|
||||
#if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||
NSOpenGLPFAOpenGLProfile,
|
||||
NSOpenGLProfileVersion3_2Core,
|
||||
#endif
|
||||
0
|
||||
};
|
||||
|
||||
NSOpenGLPixelFormat *pf = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease];
|
||||
|
||||
if (!pf)
|
||||
{
|
||||
NSLog(@"No OpenGL pixel format");
|
||||
}
|
||||
|
||||
NSOpenGLContext* context = [[[NSOpenGLContext alloc] initWithFormat:pf shareContext:nil] autorelease];
|
||||
|
||||
#if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3 && defined(DEBUG)
|
||||
// When we're using a CoreProfile context, crash if we call a legacy OpenGL function
|
||||
// This will make it much more obvious where and when such a function call is made so
|
||||
// that we can remove such calls.
|
||||
// Without this we'd simply get GL_INVALID_OPERATION error for calling legacy functions
|
||||
// but it would be more difficult to see where that function was called.
|
||||
CGLEnable([context CGLContextObj], kCGLCECrashOnRemovedFunctions);
|
||||
#endif
|
||||
|
||||
[self setPixelFormat:pf];
|
||||
[self setOpenGLContext:context];
|
||||
|
||||
#if SUPPORT_RETINA_RESOLUTION
|
||||
// Opt-In to Retina resolution
|
||||
[self setWantsBestResolutionOpenGLSurface:YES];
|
||||
#endif // SUPPORT_RETINA_RESOLUTION
|
||||
}
|
||||
|
||||
- (void)prepareOpenGL
|
||||
{
|
||||
[super prepareOpenGL];
|
||||
|
||||
// Make all the OpenGL calls to setup rendering
|
||||
// and build the necessary rendering objects
|
||||
[self initGL];
|
||||
|
||||
#if USE_DISPLAYLINK
|
||||
// Create a display link capable of being used with all active displays
|
||||
CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink);
|
||||
|
||||
// Set the renderer output callback function
|
||||
CVDisplayLinkSetOutputCallback(_displayLink, &displayLinkCallback, self);
|
||||
|
||||
// Set the display link for the current renderer
|
||||
CGLContextObj cglContext = [[self openGLContext] CGLContextObj];
|
||||
CGLPixelFormatObj cglPixelFormat = [[self pixelFormat] CGLPixelFormatObj];
|
||||
CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(_displayLink, cglContext, cglPixelFormat);
|
||||
|
||||
// Activate the display link
|
||||
CVDisplayLinkStart(_displayLink);
|
||||
#else
|
||||
[self.timer invalidate];
|
||||
self.timer = nil;
|
||||
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(targetMethod:) userInfo:nil repeats:YES];
|
||||
#endif
|
||||
|
||||
// Register to be notified when the window closes so we can stop the displaylink
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:[self window]];
|
||||
}
|
||||
|
||||
- (void)windowWillClose:(NSNotification*)notification
|
||||
{
|
||||
// Stop the display link when the window is closing because default
|
||||
// OpenGL render buffers will be destroyed. If display link continues to
|
||||
// fire without renderbuffers, OpenGL draw calls will set errors.
|
||||
#if USE_DISPLAYLINK
|
||||
CVDisplayLinkStop(_displayLink);
|
||||
#else
|
||||
[self.timer invalidate];
|
||||
self.timer = nil;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)initGL
|
||||
{
|
||||
// The reshape function may have changed the thread to which our OpenGL
|
||||
// context is attached before prepareOpenGL and initGL are called. So call
|
||||
// makeCurrentContext to ensure that our OpenGL context current to this
|
||||
// thread (i.e. makeCurrentContext directs all OpenGL calls on this thread
|
||||
// to [self openGLContext])
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
|
||||
c_initialize_firsttime();
|
||||
pthread_create(&cpu_thread_id, NULL, (void *)&cpu_thread, (void *)NULL);
|
||||
|
||||
// Synchronize buffer swaps with vertical refresh rate
|
||||
GLint swapInt = 1;
|
||||
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
|
||||
|
||||
// Init our renderer. Use 0 for the defaultFBO which is appropriate for
|
||||
// OSX (but not iOS since iOS apps must create their own FBO)
|
||||
#if TARGET_OS_MAC
|
||||
video_driver_init(0);
|
||||
#elif TARGET_OS_IPHONE
|
||||
# error "FBO FIXME TODO"
|
||||
video_driver_init(otherFBO);
|
||||
#else
|
||||
# error "unknown/unsupported Apple platform
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)reshape
|
||||
{
|
||||
[super reshape];
|
||||
|
||||
// We draw on a secondary thread through the display link. However, when
|
||||
// resizing the view, -drawRect is called on the main thread.
|
||||
// Add a mutex around to avoid the threads accessing the context
|
||||
// simultaneously when resizing.
|
||||
CGLLockContext([[self openGLContext] CGLContextObj]);
|
||||
|
||||
// Get the view size in Points
|
||||
NSRect viewRectPoints = [self bounds];
|
||||
|
||||
#if SUPPORT_RETINA_RESOLUTION
|
||||
|
||||
// Rendering at retina resolutions will reduce aliasing, but at the potential
|
||||
// cost of framerate and battery life due to the GPU needing to render more
|
||||
// pixels.
|
||||
|
||||
// Any calculations the renderer does which use pixel dimentions, must be
|
||||
// in "retina" space. [NSView convertRectToBacking] converts point sizes
|
||||
// to pixel sizes. Thus the renderer gets the size in pixels, not points,
|
||||
// so that it can set it's viewport and perform and other pixel based
|
||||
// calculations appropriately.
|
||||
// viewRectPixels will be larger (2x) than viewRectPoints for retina displays.
|
||||
// viewRectPixels will be the same as viewRectPoints for non-retina displays
|
||||
NSRect viewRectPixels = [self convertRectToBacking:viewRectPoints];
|
||||
|
||||
#else //if !SUPPORT_RETINA_RESOLUTION
|
||||
|
||||
// App will typically render faster and use less power rendering at
|
||||
// non-retina resolutions since the GPU needs to render less pixels. There
|
||||
// is the cost of more aliasing, but it will be no-worse than on a Mac
|
||||
// without a retina display.
|
||||
|
||||
// Points:Pixels is always 1:1 when not supporting retina resolutions
|
||||
NSRect viewRectPixels = viewRectPoints;
|
||||
|
||||
#endif // !SUPPORT_RETINA_RESOLUTION
|
||||
|
||||
// Set the new dimensions in our renderer
|
||||
video_driver_reshape((int)viewRectPixels.size.width, (int)viewRectPixels.size.height);
|
||||
|
||||
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
||||
}
|
||||
|
||||
- (void)renewGState
|
||||
{
|
||||
// Called whenever graphics state updated (such as window resize)
|
||||
|
||||
// OpenGL rendering is not synchronous with other rendering on the OSX.
|
||||
// Therefore, call disableScreenUpdatesUntilFlush so the window server
|
||||
// doesn't render non-OpenGL content in the window asynchronously from
|
||||
// OpenGL content, which could cause flickering. (non-OpenGL content
|
||||
// includes the title bar and drawing done by the app with other APIs)
|
||||
[[self window] disableScreenUpdatesUntilFlush];
|
||||
[super renewGState];
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)theRect
|
||||
{
|
||||
NSAssert([NSThread isMainThread], @"drawRect called on non-main thread!");
|
||||
// Called during resize operations
|
||||
// Avoid flickering during resize by drawing
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
[self drawView];
|
||||
}
|
||||
|
||||
- (void)drawView
|
||||
{
|
||||
CGLLockContext([[self openGLContext] CGLContextObj]);
|
||||
video_driver_render();
|
||||
CGLFlushDrawable([[self openGLContext] CGLContextObj]);
|
||||
CGLUnlockContext([[self openGLContext] CGLContextObj]);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
// Stop the display link BEFORE releasing anything in the view
|
||||
// otherwise the display link thread may call into the view and crash
|
||||
// when it encounters something that has been release
|
||||
#if USE_DISPLAYLINK
|
||||
CVDisplayLinkStop(_displayLink);
|
||||
CVDisplayLinkRelease(_displayLink);
|
||||
#else
|
||||
[self.timer invalidate];
|
||||
self.timer = nil;
|
||||
#endif
|
||||
|
||||
// shut down common OpenGL stuff AFTER display link has been released
|
||||
video_driver_shutdown();
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
@end
|
16
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorWindowController.h
Normal file
16
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorWindowController.h
Normal file
@ -0,0 +1,16 @@
|
||||
//
|
||||
// EmulatorWindowController.h
|
||||
// Apple2Mac
|
||||
//
|
||||
// Created by Aaron Culliney on 9/27/14.
|
||||
// Copyright (c) 2014 deadc0de.org. All rights reserved.
|
||||
//
|
||||
|
||||
// Based on sample code from https://developer.apple.com/library/mac/samplecode/GLEssentials/Introduction/Intro.html
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import "EmulatorGLView.h"
|
||||
|
||||
@interface EmulatorWindowController : NSWindowController
|
||||
|
||||
@end
|
136
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorWindowController.m
Normal file
136
Apple2Mac/Apple2Mac/Classes/OSX/EmulatorWindowController.m
Normal file
@ -0,0 +1,136 @@
|
||||
//
|
||||
// EmulatorWindowController.m
|
||||
// Apple2Mac
|
||||
//
|
||||
// Created by Aaron Culliney on 9/27/14.
|
||||
// Copyright (c) 2014 deadc0de.org. All rights reserved.
|
||||
//
|
||||
|
||||
// Based on sample code from https://developer.apple.com/library/mac/samplecode/GLEssentials/Introduction/Intro.html
|
||||
|
||||
#import "EmulatorWindowController.h"
|
||||
#import "EmulatorFullscreenWindow.h"
|
||||
|
||||
@interface EmulatorWindowController ()
|
||||
|
||||
@property (nonatomic, assign) IBOutlet EmulatorGLView *view;
|
||||
@property (nonatomic, retain) EmulatorFullscreenWindow *fullscreenWindow;
|
||||
@property (nonatomic, retain) NSWindow *standardWindow;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation EmulatorWindowController
|
||||
|
||||
@synthesize view = _view;
|
||||
@synthesize fullscreenWindow = _fullscreenWindow;
|
||||
@synthesize standardWindow = _standardWindow;
|
||||
|
||||
- (id)initWithWindow:(NSWindow *)window
|
||||
{
|
||||
self = [super initWithWindow:window];
|
||||
|
||||
if (self)
|
||||
{
|
||||
// Initialize to nil since it indicates app is not fullscreen
|
||||
self.fullscreenWindow = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (IBAction)toggleFullScreen:(id)sender
|
||||
{
|
||||
if (self.fullscreenWindow)
|
||||
{
|
||||
[self goWindow];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self goFullscreen];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)goFullscreen
|
||||
{
|
||||
// If app is already fullscreen...
|
||||
if (self.fullscreenWindow)
|
||||
{
|
||||
//...don't do anything
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate a new fullscreen window
|
||||
self.fullscreenWindow = [[[EmulatorFullscreenWindow alloc] init] autorelease];
|
||||
|
||||
// Resize the view to screensize
|
||||
NSRect viewRect = [self.fullscreenWindow frame];
|
||||
|
||||
// Set the view to the size of the fullscreen window
|
||||
[self.view setFrameSize: viewRect.size];
|
||||
|
||||
// Set the view in the fullscreen window
|
||||
[self.fullscreenWindow setContentView:self.view];
|
||||
|
||||
self.standardWindow = [self window];
|
||||
|
||||
// Hide non-fullscreen window so it doesn't show up when switching out
|
||||
// of this app (i.e. with CMD-TAB)
|
||||
[self.standardWindow orderOut:self];
|
||||
|
||||
// Set controller to the fullscreen window so that all input will go to
|
||||
// this controller (self)
|
||||
[self setWindow:self.fullscreenWindow];
|
||||
|
||||
// Show the window and make it the key window for input
|
||||
[self.fullscreenWindow makeKeyAndOrderFront:self];
|
||||
}
|
||||
|
||||
- (void)goWindow
|
||||
{
|
||||
// If controller doesn't have a full screen window...
|
||||
if (self.fullscreenWindow == nil)
|
||||
{
|
||||
//...app is already windowed so don't do anything
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the rectangle of the original window
|
||||
NSRect viewRect = [self.standardWindow frame];
|
||||
|
||||
// Set the view rect to the new size
|
||||
[self.view setFrame:viewRect];
|
||||
|
||||
// Set controller to the standard window so that all input will go to
|
||||
// this controller (self)
|
||||
[self setWindow:self.standardWindow];
|
||||
|
||||
// Set the content of the orginal window to the view
|
||||
[[self window] setContentView:self.view];
|
||||
|
||||
// Show the window and make it the key window for input
|
||||
[[self window] makeKeyAndOrderFront:self];
|
||||
|
||||
// Release/nilify fullscreenWindow
|
||||
self.fullscreenWindow = nil;
|
||||
}
|
||||
|
||||
- (void)keyDown:(NSEvent *)event
|
||||
{
|
||||
unichar c = [[event charactersIgnoringModifiers] characterAtIndex:0];
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 27:
|
||||
NSLog(@"key ESC");
|
||||
return;
|
||||
case 'f':
|
||||
NSLog(@"key 'f'");
|
||||
return;
|
||||
}
|
||||
|
||||
// Allow other character to be handled (or not and beep)
|
||||
[super keyDown:event];
|
||||
}
|
||||
|
||||
@end
|
@ -1,13 +0,0 @@
|
||||
//
|
||||
// EmulatorView.h
|
||||
// Apple2Mac
|
||||
//
|
||||
// Created by Aaron Culliney on 6/21/14.
|
||||
// Copyright (c) 2014 deadc0de.org. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface EmulatorView : NSView
|
||||
|
||||
@end
|
@ -1,59 +0,0 @@
|
||||
//
|
||||
// EmulatorView.m
|
||||
// Apple2Mac
|
||||
//
|
||||
// Created by Aaron Culliney on 6/21/14.
|
||||
// Copyright (c) 2014 deadc0de.org. All rights reserved.
|
||||
//
|
||||
|
||||
#import "EmulatorView.h"
|
||||
|
||||
|
||||
void video_driver_init() {
|
||||
// TBD ... initialize main game GL view
|
||||
}
|
||||
|
||||
void video_driver_shutdown() {
|
||||
// TBD ... destroy main game GL view
|
||||
}
|
||||
|
||||
void video_sync(int ignored) {
|
||||
// TBD ...
|
||||
}
|
||||
|
||||
@implementation EmulatorView
|
||||
|
||||
- (id)initWithFrame:(NSRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self)
|
||||
{
|
||||
// Initialization code here.
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)drawRect:(NSRect)dirtyRect
|
||||
{
|
||||
[super drawRect:dirtyRect];
|
||||
|
||||
NSString* hws = @"Hello World!";
|
||||
NSPoint p;
|
||||
NSMutableDictionary* attribs;
|
||||
NSColor* c;
|
||||
NSFont* fnt;
|
||||
|
||||
p = NSMakePoint( 10, 100 );
|
||||
|
||||
attribs = [[[NSMutableDictionary alloc] init] autorelease];
|
||||
|
||||
c = [NSColor redColor];
|
||||
fnt = [NSFont fontWithName:@"Times Roman" size:48];
|
||||
|
||||
[attribs setObject:c forKey:NSForegroundColorAttributeName];
|
||||
[attribs setObject:fnt forKey:NSFontAttributeName];
|
||||
|
||||
[hws drawAtPoint:p withAttributes:attribs];
|
||||
}
|
||||
|
||||
@end
|
@ -6,14 +6,28 @@
|
||||
// Copyright (c) 2014 deadc0de.org. All rights reserved.
|
||||
//
|
||||
|
||||
#if ESSENTIAL_GL_PRACTICES_IOS
|
||||
#import <UIKit/UIKit.h>
|
||||
#else
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
|
||||
extern int argc;
|
||||
extern const char **argv;
|
||||
|
||||
int main(int argc_, const char *argv_[])
|
||||
{
|
||||
int retVal = 1;
|
||||
argc = argc_;
|
||||
argv = argv_;
|
||||
return NSApplicationMain(argc, argv);
|
||||
|
||||
#if ESSENTIAL_GL_PRACTICES_IOS
|
||||
@autoreleasepool {
|
||||
retVal = UIApplicationMain(argc, argv, nil, nil);
|
||||
}
|
||||
#else
|
||||
retVal = NSApplicationMain(argc, argv);
|
||||
#endif
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
34
src/common.h
34
src/common.h
@ -58,7 +58,7 @@
|
||||
#if VIDEO_OPENGL
|
||||
#include "video/vgl.h"
|
||||
#else
|
||||
#define GLint int
|
||||
#define GLenum int
|
||||
#define glGetError() 0
|
||||
#endif
|
||||
|
||||
@ -103,36 +103,42 @@ extern FILE *error_log;
|
||||
#define LOG(...) \
|
||||
if (do_logging) { \
|
||||
errno = 0; \
|
||||
GLint _glerr = 0; \
|
||||
GLenum _glerr = 0; \
|
||||
_LOG(__VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define ERRLOG(...) \
|
||||
if (do_logging) { \
|
||||
GLint _glerr = glGetError(); \
|
||||
GLenum _glerr = glGetError(); \
|
||||
_LOG(__VA_ARGS__); \
|
||||
while ( (_glerr = glGetError()) ) { \
|
||||
_LOG(__VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define GL_ERRLOG(...) \
|
||||
if (do_logging) { \
|
||||
GLint _glerr = glGetError(); \
|
||||
if (_glerr) { \
|
||||
GLenum _glerr = 0; \
|
||||
while ( (_glerr = glGetError()) ) { \
|
||||
_LOG(__VA_ARGS__); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ERRQUIT(...) \
|
||||
do { \
|
||||
GLint _glerr = glGetError(); \
|
||||
GLenum _glerr = glGetError(); \
|
||||
_LOG(__VA_ARGS__); \
|
||||
while ( (_glerr = glGetError()) ) { \
|
||||
_LOG(__VA_ARGS__); \
|
||||
} \
|
||||
QUIT_FUNCTION(1); \
|
||||
} while(0)
|
||||
|
||||
#define GL_ERRQUIT(...) \
|
||||
do { \
|
||||
GLint _glerr = glGetError(); \
|
||||
if (_glerr) { \
|
||||
_LOG( __VA_ARGS__); \
|
||||
GLenum _glerr = 0; \
|
||||
while ( (_glerr = glGetError()) ) { \
|
||||
_LOG(__VA_ARGS__); \
|
||||
QUIT_FUNCTION(_glerr); \
|
||||
} \
|
||||
} while(0)
|
||||
@ -157,7 +163,7 @@ extern FILE *error_log;
|
||||
|
||||
#define RELEASE_LOG(...) \
|
||||
do { \
|
||||
GLint _glerr = glGetError(); \
|
||||
GLenum _glerr = glGetError(); \
|
||||
errno = 0; \
|
||||
_LOG(__VA_ARGS__); \
|
||||
} while(0);
|
||||
@ -168,4 +174,12 @@ extern FILE *error_log;
|
||||
(x) = NULL; \
|
||||
} while (0);
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define CFRELEASE(x) \
|
||||
do { \
|
||||
CFRelease((x)); \
|
||||
(x) = NULL; \
|
||||
} while (0);
|
||||
#endif
|
||||
|
||||
#endif // whole file
|
||||
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "video/renderer.h"
|
||||
|
||||
#define DYNAMIC_SZ 11 // 7 pixels (as bytes) + 2pre + 2post
|
||||
|
||||
@ -564,12 +565,6 @@ void video_plotchar( int x, int y, int scheme, uint8_t c ) {
|
||||
_plot_char80(&d,&s);
|
||||
}
|
||||
|
||||
#if !HEADLESS
|
||||
extern void video_driver_init(void);
|
||||
extern void video_driver_main_loop(void);
|
||||
extern void video_driver_sync(void);
|
||||
extern void video_driver_shutdown(void);
|
||||
#endif
|
||||
void video_init(void) {
|
||||
|
||||
video__fb1 = vga_mem_page_0;
|
||||
@ -581,10 +576,12 @@ void video_init(void) {
|
||||
|
||||
video_initialize_color();
|
||||
#if !HEADLESS
|
||||
#if !defined(__APPLE__)
|
||||
if (!is_headless) {
|
||||
video_driver_init();
|
||||
video_driver_init((void *)0);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void video_main_loop(void) {
|
||||
@ -598,8 +595,10 @@ void video_shutdown(void) {
|
||||
if (!is_headless) {
|
||||
video_driver_shutdown();
|
||||
}
|
||||
#if !defined(__APPLE__)
|
||||
exit(0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
|
@ -634,7 +634,7 @@ int main(int _argc, char **_argv) {
|
||||
c_initialize_firsttime(); /* init svga graphics and vm */
|
||||
|
||||
// spin off cpu thread
|
||||
pthread_create(&cpu_thread_id, NULL, (void *) &cpu_thread,(void *)NULL);
|
||||
pthread_create(&cpu_thread_id, NULL, (void *)&cpu_thread, (void *)NULL);
|
||||
|
||||
c_keys_set_key(kF8); // show credits
|
||||
|
||||
|
@ -1,13 +1,30 @@
|
||||
static const char * fragmentShader =
|
||||
"#version 100\n"
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
"varying lowp vec4 DestinationColor;\n"
|
||||
"varying mediump vec2 TextureCoordOut;\n"
|
||||
// Declare inputs and outputs
|
||||
// varTexcoord : TexCoord for the fragment computed by the rasterizer based on
|
||||
// the varTexcoord values output in the vertex shader.
|
||||
// gl_FragColor : Implicitly declare in fragments shaders less than 1.40.
|
||||
// Output color of our fragment.
|
||||
// fragColor : Output color of our fragment. Basically the same as gl_FragColor,
|
||||
// but we must explicitly declared this in shaders version 1.40 and
|
||||
// above.
|
||||
|
||||
"uniform sampler2D Sampler;\n"
|
||||
#if __VERSION__ >= 140
|
||||
in vec2 varTexcoord;
|
||||
out vec4 fragColor;
|
||||
#else
|
||||
varying vec2 varTexcoord;
|
||||
#endif
|
||||
|
||||
"void main(void) {\n"
|
||||
" //gl_FragColor = texture2D(Sampler, TextureCoordOut) * DestinationColor;\n"
|
||||
" gl_FragColor = texture2D(Sampler, TextureCoordOut);\n"
|
||||
"}"
|
||||
;
|
||||
uniform sampler2D diffuseTexture;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
#if __VERSION__ >= 140
|
||||
fragColor = texture(diffuseTexture, varTexcoord.st, 0.0);
|
||||
#else
|
||||
gl_FragColor = texture2D(diffuseTexture, varTexcoord.st, 0.0);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,24 +1,35 @@
|
||||
static const char * vertexShader =
|
||||
"#version 100\n"
|
||||
#ifdef GL_ES
|
||||
precision highp float;
|
||||
#endif
|
||||
|
||||
"attribute vec4 Position;\n"
|
||||
"attribute vec2 TextureCoord;\n"
|
||||
"//attribute vec4 TestColor;\n"
|
||||
// Declare our modelViewProjection matrix that we'll compute
|
||||
// outside the shader and set each frame
|
||||
uniform mat4 modelViewProjectionMatrix;
|
||||
|
||||
"// base screen scolor\n"
|
||||
"uniform vec4 SourceColor;\n"
|
||||
// Declare inputs and outputs
|
||||
// inPosition : Position attributes from the VAO/VBOs
|
||||
// inTexcoord : Texcoord attributes from the VAO/VBOs
|
||||
// varTexcoord : TexCoord we'll pass to the rasterizer
|
||||
// gl_Position : implicitly declared in all vertex shaders. Clip space position
|
||||
// passed to rasterizer used to build the triangles
|
||||
|
||||
"uniform mat4 Projection;\n"
|
||||
"uniform mat4 Modelview;\n"
|
||||
#if __VERSION__ >= 140
|
||||
in vec4 inPosition;
|
||||
in vec2 inTexcoord;
|
||||
out vec2 varTexcoord;
|
||||
#else
|
||||
attribute vec4 inPosition;
|
||||
attribute vec2 inTexcoord;
|
||||
varying vec2 varTexcoord;
|
||||
#endif
|
||||
|
||||
"varying vec4 DestinationColor;\n"
|
||||
"varying vec2 TextureCoordOut;\n"
|
||||
void main(void)
|
||||
{
|
||||
// Transform the vertex by the model view projection matrix so
|
||||
// the polygon shows up in the right place
|
||||
gl_Position = modelViewProjectionMatrix * inPosition;
|
||||
|
||||
"void main(void) {\n"
|
||||
" DestinationColor = SourceColor;\n"
|
||||
" //DestinationColor = TestColor;\n"
|
||||
" //gl_Position = Projection * Modelview * Position;\n"
|
||||
" gl_Position = Position;\n"
|
||||
" TextureCoordOut = TextureCoord;\n"
|
||||
"}\n"
|
||||
;
|
||||
// Pass the unmodified texture coordinate from the vertex buffer
|
||||
// directly down to the rasterizer.
|
||||
varTexcoord = inTexcoord;
|
||||
}
|
||||
|
@ -14,44 +14,23 @@
|
||||
#include "common.h"
|
||||
#include "video/glinput.h"
|
||||
#include "video/vgl.h"
|
||||
#if 0
|
||||
#include "video/matmath.h"
|
||||
#include "video/renderer.h"
|
||||
|
||||
#include "video_util/modelUtil.h"
|
||||
#include "video_util/sourceUtil.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#import <CoreFoundation/CoreFoundation.h>
|
||||
#endif
|
||||
|
||||
#include "video/Basic.vert"
|
||||
#include "video/Basic.frag"
|
||||
// TODO: implement 3D CRT object, possibly with perspective drawing?
|
||||
#define PERSPECTIVE 0
|
||||
|
||||
#define DEBUG_GEOMETRY 0
|
||||
|
||||
typedef struct UniformHandles {
|
||||
GLuint modelview;
|
||||
GLuint projection;
|
||||
GLuint sourceColor;
|
||||
} UniformHandles;
|
||||
|
||||
typedef struct AttributeHandles {
|
||||
GLuint position;
|
||||
GLuint texCoord;
|
||||
#if DEBUG_GEOMETRY
|
||||
GLuint testColor;
|
||||
#endif
|
||||
} AttributeHandles;
|
||||
|
||||
typedef struct Drawable {
|
||||
GLuint vertexBuffer;
|
||||
GLuint indexBuffer;
|
||||
int vertexCount;
|
||||
int indexCount;
|
||||
bool allocated;
|
||||
} Drawable;
|
||||
|
||||
typedef struct ShaderInfo {
|
||||
GLuint shader;
|
||||
GLenum type;// GL shader type
|
||||
const char *shadername;
|
||||
const GLchar *source;
|
||||
UT_hash_handle hh;
|
||||
} ShaderInfo;
|
||||
enum {
|
||||
POS_ATTRIB_IDX,
|
||||
NORMAL_ATTRIB_IDX,
|
||||
TEXCOORD_ATTRIB_IDX
|
||||
};
|
||||
|
||||
static int windowWidth = SCANWIDTH*1.5;
|
||||
static int windowHeight = SCANHEIGHT*1.5;
|
||||
@ -61,306 +40,603 @@ static int viewportY = 0;
|
||||
static int viewportWidth = SCANWIDTH*1.5;
|
||||
static int viewportHeight = SCANHEIGHT*1.5;
|
||||
|
||||
#if 0
|
||||
static matT translation = {};
|
||||
#endif
|
||||
static GLint uniformMVPIdx;
|
||||
static GLuint crtVAOName;
|
||||
static GLenum crtElementType;
|
||||
static GLuint crtNumElements;
|
||||
|
||||
static GLuint a2framebufferTexture = 0;
|
||||
static UniformHandles uniforms = { 0 };
|
||||
static AttributeHandles attributes = { 0 };
|
||||
static Drawable crtDrawable = { 0 };
|
||||
static ShaderInfo *allShaders = NULL;
|
||||
static GLuint a2TextureName = 0;
|
||||
static GLuint defaultFBO = 0;
|
||||
static GLuint program = 0;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// compile/link/load shaders
|
||||
// OpenGL helper routines
|
||||
//
|
||||
|
||||
static GLuint _load_shaders(ShaderInfo *shaders) {
|
||||
if (shaders == NULL) {
|
||||
return 0;
|
||||
static GLsizei _get_gl_type_size(GLenum type) {
|
||||
switch (type) {
|
||||
case GL_BYTE:
|
||||
return sizeof(GLbyte);
|
||||
case GL_UNSIGNED_BYTE:
|
||||
return sizeof(GLubyte);
|
||||
case GL_SHORT:
|
||||
return sizeof(GLshort);
|
||||
case GL_UNSIGNED_SHORT:
|
||||
return sizeof(GLushort);
|
||||
case GL_INT:
|
||||
return sizeof(GLint);
|
||||
case GL_UNSIGNED_INT:
|
||||
return sizeof(GLuint);
|
||||
case GL_FLOAT:
|
||||
return sizeof(GLfloat);
|
||||
}
|
||||
|
||||
GLuint program = glCreateProgram();
|
||||
if (!program) {
|
||||
GL_ERRLOG("glCreateProgram");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ShaderInfo *entry = shaders;
|
||||
while (entry->type != GL_NONE) {
|
||||
GLuint shader = glCreateShader(entry->type);
|
||||
entry->shader = shader;
|
||||
if (!shader || !entry->source) {
|
||||
for (entry = shaders; entry->type != GL_NONE; ++entry) {
|
||||
glDeleteShader(entry->shader);
|
||||
entry->shader = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
glShaderSource(shader, 1, &entry->source, NULL);
|
||||
glCompileShader( shader );
|
||||
GL_ERRLOG("glCompileShader");
|
||||
|
||||
GLint compiled = 0;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
|
||||
if (!compiled) {
|
||||
GLsizei len = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
|
||||
GLchar* log = (GLchar*)malloc(sizeof(GLchar)*(len+1));
|
||||
glGetShaderInfoLog(shader, len, &len, log);
|
||||
ERRQUIT("Shader '%s' compilation failed: %s", entry->shadername, log);
|
||||
free(log);
|
||||
return 0;
|
||||
}
|
||||
|
||||
glAttachShader(program, shader);
|
||||
++entry;
|
||||
}
|
||||
|
||||
glLinkProgram(program);
|
||||
GL_ERRLOG("glLinkProgram");
|
||||
|
||||
GLint linked = 0;
|
||||
glGetProgramiv(program, GL_LINK_STATUS, &linked);
|
||||
if (!linked) {
|
||||
GLsizei len;
|
||||
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
|
||||
GLchar* log = (GLchar*)malloc(sizeof(GLchar)*(len+1));
|
||||
glGetProgramInfoLog(program, len, &len, log);
|
||||
ERRQUIT("Shader '%s' linking failed: %s", entry->shadername, log);
|
||||
free(log);
|
||||
for (entry = shaders; entry->type != GL_NONE; ++entry) {
|
||||
glDeleteShader(entry->shader);
|
||||
entry->shader = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
return program;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _create_gl_program(void) {
|
||||
|
||||
ShaderInfo shaders[] = {
|
||||
{ .type=GL_VERTEX_SHADER, .shadername="vertex shader", .source=vertexShader },
|
||||
{ .type=GL_FRAGMENT_SHADER, .shadername="fragment shader", .source=fragmentShader },
|
||||
{ .type=GL_NONE, .shadername=NULL, .source=NULL }
|
||||
};
|
||||
program = _load_shaders(shaders);
|
||||
glUseProgram(program);
|
||||
GL_ERRLOG("glUseProgram");
|
||||
|
||||
ShaderInfo *info = calloc(1, sizeof(ShaderInfo));
|
||||
memcpy(info, &shaders[0], sizeof(ShaderInfo));
|
||||
HASH_ADD_INT(allShaders, /*index*/shader, /*new node*/info);
|
||||
|
||||
info = calloc(1, sizeof(ShaderInfo));
|
||||
memcpy(info, &shaders[1], sizeof(ShaderInfo));
|
||||
HASH_ADD_INT(allShaders, /*index*/shader, /*new node*/info);
|
||||
|
||||
// TODO : other shader effects, for example NTSC noise, CRT glitches, pixel bloom, etc ...
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// generate/manage vertices for the Cathode Ray Tube object
|
||||
//
|
||||
|
||||
static void _generate_crt_object(void) {
|
||||
// TODO FIXME: use actual 3D CRT surface with vertices/indices dynamically generated based on
|
||||
// screen dimensions / device DPI
|
||||
|
||||
if (crtDrawable.allocated) {
|
||||
glDeleteBuffers(1, &crtDrawable.vertexBuffer);
|
||||
glDeleteBuffers(1, &crtDrawable.indexBuffer);
|
||||
crtDrawable.allocated = false;
|
||||
}
|
||||
|
||||
static demoModel *_create_CRT_model() {
|
||||
#define STRIDE 9*sizeof(GLfloat)
|
||||
#define TEST_COLOR_OFF (GLvoid *)(3*sizeof(GLfloat))
|
||||
#define TEX_COORD_OFF (GLvoid *)(7*sizeof(GLfloat))
|
||||
|
||||
// NOTE: vertices in Normalized Device Coordinates
|
||||
const GLuint numverts = 6;
|
||||
GLfloat vrt[] = {
|
||||
-1.0, -1.0, 0.0, /*color*/1.0,1.0,1.0,1.0, /*interleaved tex coord:*/0.0, 1.0,// Triangle 1
|
||||
1.0, -1.0, 0.0, /*color*/1.0,1.0,1.0,1.0, /*interleaved tex coord:*/1.0, 1.0,
|
||||
-1.0, 1.0, 0.0, /*color*/1.0,1.0,1.0,1.0, /*interleaved tex coord:*/0.0, 0.0,
|
||||
-1.0, 1.0, 0.0, /*color*/1.0,1.0,1.0,1.0, /*interleaved tex coord:*/0.0, 0.0,// Triangle 2
|
||||
1.0, -1.0, 0.0, /*color*/1.0,1.0,1.0,1.0, /*interleaved tex coord:*/1.0, 1.0,
|
||||
1.0, 1.0, 0.0, /*color*/1.0,1.0,1.0,1.0, /*interleaved tex coord:*/1.0, 0.0,
|
||||
const GLfloat crt_positions[] = {
|
||||
// CRT screen quad
|
||||
-1.0, -1.0, 0.0, 1.0,
|
||||
1.0, -1.0, 0.0, 1.0,
|
||||
-1.0, 1.0, 0.0, 1.0,
|
||||
1.0, 1.0, 0.0, 1.0,
|
||||
#if PERSPECTIVE
|
||||
// CRT back side point
|
||||
0.0, 0.0, -1.0, 1.0,
|
||||
#endif
|
||||
};
|
||||
const GLuint numindices = 6;
|
||||
const GLushort ind[] = {
|
||||
0, 1, 2, 3, 4, 5
|
||||
const GLfloat crt_texcoords[] = {
|
||||
0.0, 1.0,
|
||||
1.0, 1.0,
|
||||
0.0, 0.0,
|
||||
1.0, 0.0,
|
||||
};
|
||||
const GLushort indices[] = {
|
||||
// CRT screen quad
|
||||
0, 1, 2, 2, 1, 3
|
||||
#if PERSPECTIVE
|
||||
// ...
|
||||
#endif
|
||||
};
|
||||
|
||||
// Create VBO for the vertices
|
||||
glGenBuffers(1, &crtDrawable.vertexBuffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, crtDrawable.vertexBuffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vrt), &vrt[0], GL_STATIC_DRAW);
|
||||
GL_ERRLOG("vertex buffer setup");
|
||||
demoModel *crt = calloc(1, sizeof(demoModel));
|
||||
crt->numVertices = 4;
|
||||
crt->numElements = 6;
|
||||
|
||||
// Create VBO for the indices
|
||||
glGenBuffers(1, &crtDrawable.indexBuffer);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, crtDrawable.indexBuffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ind), &ind[0], GL_STATIC_DRAW);
|
||||
GL_ERRLOG("element buffer setup");
|
||||
crt->positions = malloc(sizeof(crt_positions));
|
||||
memcpy(crt->positions, &crt_positions[0], sizeof(crt_positions));
|
||||
crt->positionType = GL_FLOAT;
|
||||
crt->positionSize = 4; // x,y,z coordinates
|
||||
crt->positionArraySize = sizeof(crt_positions);
|
||||
|
||||
crtDrawable.vertexCount = numverts;
|
||||
crtDrawable.indexCount = numindices;
|
||||
crtDrawable.allocated = true;
|
||||
crt->texcoords = malloc(sizeof(crt_texcoords));
|
||||
memcpy(crt->texcoords, &crt_texcoords[0], sizeof(crt_texcoords));
|
||||
crt->texcoordType = GL_FLOAT;
|
||||
crt->texcoordSize = 2; // s,t coordinates
|
||||
crt->texcoordArraySize = sizeof(crt_texcoords);
|
||||
|
||||
crt->normals = NULL;
|
||||
crt->normalType = GL_NONE;
|
||||
crt->normalSize = GL_NONE;
|
||||
crt->normalArraySize = 0;
|
||||
|
||||
crt->elements = malloc(sizeof(indices));
|
||||
memcpy(crt->elements, &indices[0], sizeof(indices));
|
||||
crt->elementType = GL_UNSIGNED_SHORT;
|
||||
crt->elementArraySize = sizeof(indices);
|
||||
|
||||
return crt;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// initialization routines
|
||||
//
|
||||
static GLuint _create_VAO(demoModel *model) {
|
||||
GLuint vaoName;
|
||||
|
||||
// Create a vertex array object (VAO) to cache model parameters
|
||||
glGenVertexArrays(1, &vaoName);
|
||||
glBindVertexArray(vaoName);
|
||||
|
||||
GLuint posBufferName;
|
||||
|
||||
// Create a vertex buffer object (VBO) to store positions and load data
|
||||
glGenBuffers(1, &posBufferName);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, posBufferName);
|
||||
glBufferData(GL_ARRAY_BUFFER, model->positionArraySize, model->positions, GL_STATIC_DRAW);
|
||||
|
||||
// Enable the position attribute for this VAO
|
||||
glEnableVertexAttribArray(POS_ATTRIB_IDX);
|
||||
|
||||
// Get the size of the position type so we can set the stride properly
|
||||
GLsizei posTypeSize = _get_gl_type_size(model->positionType);
|
||||
|
||||
// Set up parmeters for position attribute in the VAO including,
|
||||
// size, type, stride, and offset in the currenly bound VAO
|
||||
// This also attaches the position VBO to the VAO
|
||||
glVertexAttribPointer(POS_ATTRIB_IDX, // What attibute index will this array feed in the vertex shader (see buildProgram)
|
||||
model->positionSize, // How many elements are there per position?
|
||||
model->positionType, // What is the type of this data?
|
||||
GL_FALSE, // Do we want to normalize this data (0-1 range for fixed-pont types)
|
||||
model->positionSize*posTypeSize, // What is the stride (i.e. bytes between positions)?
|
||||
0); // What is the offset in the VBO to the position data?
|
||||
|
||||
if (model->normals) {
|
||||
GLuint normalBufferName;
|
||||
|
||||
// Create a vertex buffer object (VBO) to store positions
|
||||
glGenBuffers(1, &normalBufferName);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, normalBufferName);
|
||||
|
||||
// Allocate and load normal data into the VBO
|
||||
glBufferData(GL_ARRAY_BUFFER, model->normalArraySize, model->normals, GL_STATIC_DRAW);
|
||||
|
||||
// Enable the normal attribute for this VAO
|
||||
glEnableVertexAttribArray(NORMAL_ATTRIB_IDX);
|
||||
|
||||
// Get the size of the normal type so we can set the stride properly
|
||||
GLsizei normalTypeSize = _get_gl_type_size(model->normalType);
|
||||
|
||||
// Set up parmeters for position attribute in the VAO including,
|
||||
// size, type, stride, and offset in the currenly bound VAO
|
||||
// This also attaches the position VBO to the VAO
|
||||
glVertexAttribPointer(NORMAL_ATTRIB_IDX, // What attibute index will this array feed in the vertex shader (see buildProgram)
|
||||
model->normalSize, // How many elements are there per normal?
|
||||
model->normalType, // What is the type of this data?
|
||||
GL_FALSE, // Do we want to normalize this data (0-1 range for fixed-pont types)
|
||||
model->normalSize*normalTypeSize, // What is the stride (i.e. bytes between normals)?
|
||||
0); // What is the offset in the VBO to the normal data?
|
||||
}
|
||||
|
||||
if (model->texcoords) {
|
||||
GLuint texcoordBufferName;
|
||||
|
||||
// Create a VBO to store texcoords
|
||||
glGenBuffers(1, &texcoordBufferName);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, texcoordBufferName);
|
||||
|
||||
// Allocate and load texcoord data into the VBO
|
||||
glBufferData(GL_ARRAY_BUFFER, model->texcoordArraySize, model->texcoords, GL_STATIC_DRAW);
|
||||
|
||||
// Enable the texcoord attribute for this VAO
|
||||
glEnableVertexAttribArray(TEXCOORD_ATTRIB_IDX);
|
||||
|
||||
// Get the size of the texcoord type so we can set the stride properly
|
||||
GLsizei texcoordTypeSize = _get_gl_type_size(model->texcoordType);
|
||||
|
||||
// Set up parmeters for texcoord attribute in the VAO including,
|
||||
// size, type, stride, and offset in the currenly bound VAO
|
||||
// This also attaches the texcoord VBO to VAO
|
||||
glVertexAttribPointer(TEXCOORD_ATTRIB_IDX, // What attibute index will this array feed in the vertex shader (see buildProgram)
|
||||
model->texcoordSize, // How many elements are there per texture coord?
|
||||
model->texcoordType, // What is the type of this data in the array?
|
||||
GL_TRUE, // Do we want to normalize this data (0-1 range for fixed-point types)
|
||||
model->texcoordSize*texcoordTypeSize, // What is the stride (i.e. bytes between texcoords)?
|
||||
0); // What is the offset in the VBO to the texcoord data?
|
||||
}
|
||||
|
||||
GLuint elementBufferName;
|
||||
|
||||
// Create a VBO to vertex array elements
|
||||
// This also attaches the element array buffer to the VAO
|
||||
glGenBuffers(1, &elementBufferName);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferName);
|
||||
|
||||
// Allocate and load vertex array element data into VBO
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, model->elementArraySize, model->elements, GL_STATIC_DRAW);
|
||||
|
||||
GL_ERRLOG("finished creating VAO/VBOs")
|
||||
|
||||
return vaoName;
|
||||
}
|
||||
|
||||
static void _destroy_VAO(GLuint vaoName) {
|
||||
GLuint index;
|
||||
GLuint bufName;
|
||||
|
||||
// Bind the VAO so we can get data from it
|
||||
glBindVertexArray(vaoName);
|
||||
|
||||
// For every possible attribute set in the VAO
|
||||
for (index = 0; index < 16; index++) {
|
||||
// Get the VBO set for that attibute
|
||||
glGetVertexAttribiv(index , GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, (GLint*)&bufName);
|
||||
|
||||
// If there was a VBO set...
|
||||
if (bufName) {
|
||||
//...delete the VBO
|
||||
glDeleteBuffers(1, &bufName);
|
||||
}
|
||||
}
|
||||
|
||||
// Get any element array VBO set in the VAO
|
||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, (GLint*)&bufName);
|
||||
|
||||
// If there was a element array VBO set in the VAO
|
||||
if(bufName) {
|
||||
//...delete the VBO
|
||||
glDeleteBuffers(1, &bufName);
|
||||
}
|
||||
|
||||
// Finally, delete the VAO
|
||||
glDeleteVertexArrays(1, &vaoName);
|
||||
|
||||
GL_ERRLOG("destroying VAO/VBOs");
|
||||
}
|
||||
|
||||
static GLuint _create_CRT_texture(void) {
|
||||
GLuint texName;
|
||||
|
||||
// Create a texture object to apply to model
|
||||
glGenTextures(1, &texName);
|
||||
glBindTexture(GL_TEXTURE_2D, texName);
|
||||
|
||||
// Set up filter and wrap modes for this texture object
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
||||
// Indicate that pixel rows are tightly packed
|
||||
// (defaults to stride of 4 which is kind of only good for
|
||||
// RGBA or FLOAT data types)
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
// Allocate and load image data into texture
|
||||
glTexImage2D(GL_TEXTURE_2D, /*level*/0, /*internal format*/GL_RGBA, SCANWIDTH, SCANHEIGHT, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
|
||||
GL_ERRLOG("finished creating CRT texture");
|
||||
|
||||
return texName;
|
||||
}
|
||||
|
||||
static GLuint _build_program(demoSource *vertexSource, demoSource *fragmentSource, bool hasNormal, bool hasTexcoord) {
|
||||
GLuint prgName;
|
||||
|
||||
GLint logLength, status;
|
||||
|
||||
// String to pass to glShaderSource
|
||||
GLchar *sourceString = NULL;
|
||||
|
||||
// Determine if GLSL version 140 is supported by this context.
|
||||
// We'll use this info to generate a GLSL shader source string
|
||||
// with the proper version preprocessor string prepended
|
||||
float glLanguageVersion;
|
||||
|
||||
#if ESSENTIAL_GL_PRACTICES_IOS
|
||||
sscanf((char *)glGetString(GL_SHADING_LANGUAGE_VERSION), "OpenGL ES GLSL ES %f", &glLanguageVersion);
|
||||
#else
|
||||
sscanf((char *)glGetString(GL_SHADING_LANGUAGE_VERSION), "%f", &glLanguageVersion);
|
||||
#endif
|
||||
|
||||
// GL_SHADING_LANGUAGE_VERSION returns the version standard version form
|
||||
// with decimals, but the GLSL version preprocessor directive simply
|
||||
// uses integers (thus 1.10 should 110 and 1.40 should be 140, etc.)
|
||||
// We multiply the floating point number by 100 to get a proper
|
||||
// number for the GLSL preprocessor directive
|
||||
GLuint version = 100 * glLanguageVersion;
|
||||
|
||||
// Get the size of the version preprocessor string info so we know
|
||||
// how much memory to allocate for our sourceString
|
||||
const GLsizei versionStringSize = sizeof("#version 123\n");
|
||||
|
||||
// Create a program object
|
||||
prgName = glCreateProgram();
|
||||
|
||||
// Indicate the attribute indicies on which vertex arrays will be
|
||||
// set with glVertexAttribPointer
|
||||
// See buildVAO to see where vertex arrays are actually set
|
||||
glBindAttribLocation(prgName, POS_ATTRIB_IDX, "inPosition");
|
||||
|
||||
if (hasNormal) {
|
||||
glBindAttribLocation(prgName, NORMAL_ATTRIB_IDX, "inNormal");
|
||||
}
|
||||
|
||||
if (hasTexcoord) {
|
||||
glBindAttribLocation(prgName, TEXCOORD_ATTRIB_IDX, "inTexcoord");
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
// Specify and compile VertexShader //
|
||||
//////////////////////////////////////
|
||||
|
||||
// Allocate memory for the source string including the version preprocessor information
|
||||
sourceString = malloc(vertexSource->byteSize + versionStringSize);
|
||||
|
||||
// Prepend our vertex shader source string with the supported GLSL version so
|
||||
// the shader will work on ES, Legacy, and OpenGL 3.2 Core Profile contexts
|
||||
sprintf(sourceString, "#version %d\n%s", version, vertexSource->string);
|
||||
|
||||
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexShader, 1, (const GLchar **)&(sourceString), NULL);
|
||||
glCompileShader(vertexShader);
|
||||
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength);
|
||||
|
||||
if (logLength > 0) {
|
||||
GLchar *log = (GLchar *)malloc(logLength);
|
||||
glGetShaderInfoLog(vertexShader, logLength, &logLength, log);
|
||||
LOG("Vtx Shader compile log:%s\n", log);
|
||||
free(log);
|
||||
}
|
||||
|
||||
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status);
|
||||
if (status == 0) {
|
||||
LOG("Failed to compile vtx shader:\n%s\n", sourceString);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(sourceString);
|
||||
sourceString = NULL;
|
||||
|
||||
// Attach the vertex shader to our program
|
||||
glAttachShader(prgName, vertexShader);
|
||||
|
||||
// Delete the vertex shader since it is now attached
|
||||
// to the program, which will retain a reference to it
|
||||
glDeleteShader(vertexShader);
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Specify and compile Fragment Shader //
|
||||
/////////////////////////////////////////
|
||||
|
||||
// Allocate memory for the source string including the version preprocessor information
|
||||
sourceString = malloc(fragmentSource->byteSize + versionStringSize);
|
||||
|
||||
// Prepend our fragment shader source string with the supported GLSL version so
|
||||
// the shader will work on ES, Legacy, and OpenGL 3.2 Core Profile contexts
|
||||
sprintf(sourceString, "#version %d\n%s", version, fragmentSource->string);
|
||||
|
||||
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragShader, 1, (const GLchar **)&(sourceString), NULL);
|
||||
glCompileShader(fragShader);
|
||||
glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength);
|
||||
if (logLength > 0) {
|
||||
GLchar *log = (GLchar *)malloc(logLength);
|
||||
glGetShaderInfoLog(fragShader, logLength, &logLength, log);
|
||||
LOG("Frag Shader compile log:\n%s\n", log);
|
||||
free(log);
|
||||
}
|
||||
|
||||
glGetShaderiv(fragShader, GL_COMPILE_STATUS, &status);
|
||||
if (status == 0) {
|
||||
LOG("Failed to compile frag shader:\n%s\n", sourceString);
|
||||
return 0;
|
||||
}
|
||||
|
||||
free(sourceString);
|
||||
sourceString = NULL;
|
||||
|
||||
// Attach the fragment shader to our program
|
||||
glAttachShader(prgName, fragShader);
|
||||
|
||||
// Delete the fragment shader since it is now attached
|
||||
// to the program, which will retain a reference to it
|
||||
glDeleteShader(fragShader);
|
||||
|
||||
//////////////////////
|
||||
// Link the program //
|
||||
//////////////////////
|
||||
|
||||
glLinkProgram(prgName);
|
||||
glGetProgramiv(prgName, GL_INFO_LOG_LENGTH, &logLength);
|
||||
if (logLength > 0) {
|
||||
GLchar *log = (GLchar*)malloc(logLength);
|
||||
glGetProgramInfoLog(prgName, logLength, &logLength, log);
|
||||
LOG("Program link log:\n%s\n", log);
|
||||
free(log);
|
||||
}
|
||||
|
||||
glGetProgramiv(prgName, GL_LINK_STATUS, &status);
|
||||
if (status == 0) {
|
||||
LOG("Failed to link program");
|
||||
return 0;
|
||||
}
|
||||
|
||||
glValidateProgram(prgName);
|
||||
glGetProgramiv(prgName, GL_INFO_LOG_LENGTH, &logLength);
|
||||
if (logLength > 0) {
|
||||
GLchar *log = (GLchar*)malloc(logLength);
|
||||
glGetProgramInfoLog(prgName, logLength, &logLength, log);
|
||||
LOG("Program validate log:\n%s\n", log);
|
||||
free(log);
|
||||
}
|
||||
|
||||
glGetProgramiv(prgName, GL_VALIDATE_STATUS, &status);
|
||||
if (status == 0) {
|
||||
LOG("Failed to validate program");
|
||||
return 0;
|
||||
}
|
||||
|
||||
glUseProgram(prgName);
|
||||
|
||||
///////////////////////////////////////
|
||||
// Setup common program input points //
|
||||
///////////////////////////////////////
|
||||
|
||||
GLint samplerLoc = glGetUniformLocation(prgName, "diffuseTexture");
|
||||
|
||||
// Indicate that the diffuse texture will be bound to texture unit 0
|
||||
GLint unit = 0;
|
||||
glUniform1i(samplerLoc, unit);
|
||||
|
||||
GL_ERRLOG("build program");
|
||||
|
||||
return prgName;
|
||||
}
|
||||
|
||||
static demoSource *_create_shader_source(const char *fileName) {
|
||||
demoSource *src = NULL;
|
||||
#ifdef __APPLE__
|
||||
CFBundleRef mainBundle = CFBundleGetMainBundle();
|
||||
CFStringRef fileString = CFStringCreateWithCString(/*allocator*/NULL, fileName, CFStringGetSystemEncoding());
|
||||
CFURLRef fileURL = CFBundleCopyResourceURL(mainBundle, fileString, NULL, NULL);
|
||||
CFRELEASE(fileString);
|
||||
CFStringRef filePath = CFURLCopyFileSystemPath(fileURL, kCFURLPOSIXPathStyle);
|
||||
CFRELEASE(fileURL);
|
||||
src = srcLoadSource(CFStringGetCStringPtr(filePath, CFStringGetSystemEncoding()));
|
||||
CFRELEASE(filePath);
|
||||
#else
|
||||
#error FIXME TODO need to leveage GNU build system install_dir or somesuch stuff ...
|
||||
#endif
|
||||
return src;
|
||||
}
|
||||
|
||||
static void gldriver_init_common(void) {
|
||||
LOG("%s %s", glGetString(GL_RENDERER), glGetString(GL_VERSION));
|
||||
|
||||
_generate_crt_object();
|
||||
viewportWidth = 400;
|
||||
viewportHeight = 400;
|
||||
|
||||
_create_gl_program();
|
||||
// ----------------------------
|
||||
// Create CRT model VAO/VBOs
|
||||
|
||||
// Extract the handles to attributes and uniforms
|
||||
attributes.position = glGetAttribLocation(program, "Position");
|
||||
GL_ERRLOG("glGetAttribLocation");
|
||||
#if DEBUG_GEOMETRY
|
||||
attributes.testColor = glGetAttribLocation(program, "TestColor");
|
||||
GL_ERRQUIT("cannot get TestColor attribute location for DEBUG_GEOMETRY preprocessor configuration");
|
||||
#endif
|
||||
attributes.texCoord = glGetAttribLocation(program, "TextureCoord");
|
||||
uniforms.projection = glGetUniformLocation(program, "Projection");
|
||||
LOG("projection = %d", uniforms.projection);
|
||||
uniforms.modelview = glGetUniformLocation(program, "Modelview");
|
||||
LOG("modelview = %d", uniforms.modelview);
|
||||
uniforms.sourceColor = glGetUniformLocation(program, "SourceColor");
|
||||
LOG("sourceColor = %d", uniforms.sourceColor);
|
||||
// create CRT model
|
||||
demoModel *crtModel = _create_CRT_model();
|
||||
|
||||
// Set up to use Apple //e framebuffer as texture
|
||||
glGenTextures(1, &a2framebufferTexture);
|
||||
GL_ERRLOG("glGenTextures");
|
||||
glBindTexture(GL_TEXTURE_2D, a2framebufferTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*GL_NEAREST*/);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR/*GL_NEAREST*/);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
// Build Vertex Buffer Objects (VBOs) and Vertex Array Object (VAOs) with our model data
|
||||
crtVAOName = _create_VAO(crtModel);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, /*level*/0, /*internal format*/GL_RGBA, windowWidth, windowHeight, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
GL_ERRLOG("glTexImage2D");
|
||||
// Cache the number of element and primType to use later in our glDrawElements calls
|
||||
crtNumElements = crtModel->numElements;
|
||||
crtElementType = crtModel->elementType;
|
||||
|
||||
// Initialize various state
|
||||
glEnableVertexAttribArray(attributes.position);
|
||||
GL_ERRLOG("glEnableVertexAttribArray");
|
||||
#if DEBUG_GEOMETRY
|
||||
glEnableVertexAttribArray(attributes.testColor);
|
||||
GL_ERRLOG("glEnableVertexAttribArray");
|
||||
#endif
|
||||
glEnableVertexAttribArray(attributes.texCoord);
|
||||
GL_ERRLOG("glEnableVertexAttribArray");
|
||||
// We're using VBOs we can destroy all this memory since buffers are
|
||||
// loaded into GL and we've saved anything else we need
|
||||
mdlDestroyModel(crtModel);
|
||||
crtModel = NULL;
|
||||
|
||||
//glEnable(GL_DEPTH_TEST);
|
||||
glClearColor(0.2, 0.2f, 0.2f, 1);
|
||||
// Build a default texture object with our image data
|
||||
a2TextureName = _create_CRT_texture();
|
||||
|
||||
#if 0
|
||||
// Set up transforms
|
||||
translation = mat4_translate_xyz(0.f, 0.f, -7.f, MAT4);
|
||||
#endif
|
||||
// ----------------------------
|
||||
// Load/setup shaders
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
ERRQUIT("framebuffer status: %04X", status);
|
||||
demoSource *vtxSource = _create_shader_source("Basic.vert");
|
||||
demoSource *frgSource = _create_shader_source("Basic.frag");
|
||||
|
||||
// Build Program
|
||||
program = _build_program(vtxSource, frgSource, /*withNormal:*/false, /*withTexcoord:*/true);
|
||||
glUseProgram(program);
|
||||
|
||||
srcDestroySource(vtxSource);
|
||||
srcDestroySource(frgSource);
|
||||
|
||||
uniformMVPIdx = glGetUniformLocation(program, "modelViewProjectionMatrix");
|
||||
if (uniformMVPIdx < 0) {
|
||||
LOG("No modelViewProjectionMatrix in character shader");
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
// setup static OpenGL state
|
||||
|
||||
// Depth test will always be enabled
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// We will always cull back faces for better performance
|
||||
glEnable(GL_CULL_FACE);
|
||||
|
||||
// Always use this clear color
|
||||
glClearColor(0.5f, 0.4f, 0.5f, 1.0f);
|
||||
|
||||
// Draw our scene once without presenting the rendered image.
|
||||
// This is done in order to pre-warm OpenGL
|
||||
// We don't need to present the buffer since we don't actually want the
|
||||
// user to see this, we're only drawing as a pre-warm stage
|
||||
video_driver_render();
|
||||
|
||||
// Check for errors to make sure all of our setup went ok
|
||||
GL_ERRLOG("finished initialization");
|
||||
}
|
||||
|
||||
static void gldriver_shutdown(void) {
|
||||
// Cleanup all OpenGL objects
|
||||
glDeleteTextures(1, &a2TextureName);
|
||||
_destroy_VAO(crtVAOName);
|
||||
glDeleteProgram(program);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
//
|
||||
// update, display, reshape
|
||||
// update, render, reshape
|
||||
//
|
||||
static void gldriver_update(void) {
|
||||
#if !defined(__APPLE__)
|
||||
// HACK MAYBE FIXME : pumps the joystick sampling code that is currently integrated into the keys routine
|
||||
c_keys_handle_input(-1, 0, 0);
|
||||
#endif
|
||||
#if USE_GLUT
|
||||
glutPostRedisplay();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void gldriver_display(void) {
|
||||
static void gldriver_render(void) {
|
||||
if (is_headless) {
|
||||
return;
|
||||
}
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT/*| GL_DEPTH_BUFFER_BIT*/);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Set the viewport transform.
|
||||
glViewport(viewportX, viewportY, viewportWidth, viewportHeight);
|
||||
|
||||
// Set the source color
|
||||
GLfloat sourceColor[] = { 1.f, 1.f, 1.f, 1.f };
|
||||
glUniform4fv(uniforms.sourceColor, 1, &sourceColor[0]);
|
||||
GL_ERRQUIT("glUniform4fv");
|
||||
|
||||
#if 0
|
||||
// Set the model-view transform.
|
||||
matT rotation = mat_identity();
|
||||
matT modelview = mat_mult_mat(rotation, translation, MAT4);
|
||||
glUniformMatrix4fv(uniforms.modelview, 1, 0, MAT_POINTER(modelview));
|
||||
GL_ERRQUIT("glUniformMatrix4fv");
|
||||
|
||||
// Set the projection transform.
|
||||
float h = 4.0f * windowHeight / windowWidth;
|
||||
matT projectionMatrix = mat4_frustum(-2, 2, -h / 2, h / 2, 5, 10);
|
||||
glUniformMatrix4fv(uniforms.projection, 1, 0, MAT_POINTER(projectionMatrix));
|
||||
GL_ERRQUIT("glUniformMatrix4fv");
|
||||
#if PERSPECTIVE
|
||||
// Calculate modelview and projection matrices
|
||||
GLfloat modelView[16];
|
||||
GLfloat projection[16];
|
||||
mtxLoadPerspective(projection, 90, (float)viewportWidth / (float)viewportHeight, 5.0, 10000);
|
||||
#endif
|
||||
|
||||
// texture ...
|
||||
// Calculate the modelview matrix to render our character
|
||||
// at the proper position and rotation
|
||||
GLfloat mvp[16];
|
||||
#if PERSPECTIVE
|
||||
// Create model-view-projection matrix
|
||||
//mtxLoadTranslate(modelView, 0, 150, -450);
|
||||
//mtxRotateXApply(modelView, -90.0f);
|
||||
//mtxRotateApply(modelView, -45.0f, 0.7, 0.3, 1);
|
||||
mtxMultiply(mvp, projection, modelView);
|
||||
#else
|
||||
// Just load an identity matrix for a pure orthographic/non-perspective viewing
|
||||
mtxLoadIdentity(mvp);
|
||||
#endif
|
||||
|
||||
// Have our shader use the modelview projection matrix
|
||||
// that we calculated above
|
||||
glUniformMatrix4fv(uniformMVPIdx, 1, GL_FALSE, mvp);
|
||||
|
||||
// Update texture from Apple //e internal framebuffer
|
||||
const uint8_t * const fb = video_current_framebuffer();
|
||||
uint8_t index;
|
||||
#warning FIXME TODO use memcpy?
|
||||
unsigned int count = SCANWIDTH * SCANHEIGHT;
|
||||
char pixels[SCANWIDTH * SCANHEIGHT * 4];
|
||||
for (unsigned int i=0, j=0; i<count; i++, j+=4) {
|
||||
index = *(fb + i);
|
||||
*( (uint32_t*)(pixels + j) ) = (uint32_t)(
|
||||
((uint32_t)(colormap[index].red) << 0 ) |
|
||||
((uint32_t)(colormap[index].green) << 8 ) |
|
||||
((uint32_t)(colormap[index].blue) << 16) |
|
||||
((uint32_t)0xff << 24)
|
||||
);
|
||||
if (fb != NULL) {
|
||||
for (unsigned int i=0, j=0; i<count; i++, j+=4) {
|
||||
index = *(fb + i);
|
||||
*( (uint32_t*)(pixels + j) ) = (uint32_t)(
|
||||
((uint32_t)(colormap[index].red) << 0 ) |
|
||||
((uint32_t)(colormap[index].green) << 8 ) |
|
||||
((uint32_t)(colormap[index].blue) << 16) |
|
||||
((uint32_t)0xff << 24)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, a2framebufferTexture);
|
||||
#if 0
|
||||
int width, height;
|
||||
void *test_pixels = test_texture(&width, &height);
|
||||
glTexImage2D(GL_TEXTURE_2D, /*level*/0, /*internal format*/GL_RGBA, width, height, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, test_pixels);
|
||||
#else
|
||||
glBindTexture(GL_TEXTURE_2D, a2TextureName);
|
||||
glTexImage2D(GL_TEXTURE_2D, /*level*/0, /*internal format*/GL_RGBA, SCANWIDTH, SCANHEIGHT, /*border*/0, /*format*/GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *)&pixels[0]);
|
||||
#endif
|
||||
GL_ERRLOG("glTexImage2D");
|
||||
glGetError();
|
||||
|
||||
// Draw the CRT object and the apple2 framebuffer as a texture
|
||||
glBindBuffer(GL_ARRAY_BUFFER, crtDrawable.vertexBuffer);
|
||||
glVertexAttribPointer(attributes.position, 3, GL_FLOAT, GL_FALSE, STRIDE, 0);
|
||||
#if DEBUG_GEOMETRY
|
||||
glVertexAttribPointer(attributes.testColor, 4, GL_FLOAT, GL_FALSE, STRIDE, TEST_COLOR_OFF);
|
||||
#endif
|
||||
glVertexAttribPointer(attributes.texCoord, 2, GL_FLOAT, GL_FALSE, STRIDE, TEX_COORD_OFF);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, crtDrawable.indexBuffer);
|
||||
glDrawElements(GL_TRIANGLES, crtDrawable.indexCount, GL_UNSIGNED_SHORT, 0);
|
||||
GL_ERRLOG("glDrawElements");
|
||||
// Bind our vertex array object
|
||||
glBindVertexArray(crtVAOName);
|
||||
|
||||
glutSwapBuffers();
|
||||
// Cull back faces now that we no longer render
|
||||
// with an inverted matrix
|
||||
glCullFace(GL_BACK);
|
||||
|
||||
// Draw the CRT object
|
||||
glDrawElements(GL_TRIANGLES, crtNumElements, crtElementType, 0);
|
||||
}
|
||||
|
||||
static void gldriver_reshape(int w, int h) {
|
||||
LOG("reshape to w:%d h:%d", w, h);
|
||||
//LOG("reshape to w:%d h:%d", w, h);
|
||||
windowWidth = w;
|
||||
windowHeight = h;
|
||||
|
||||
@ -373,34 +649,28 @@ static void gldriver_reshape(int w, int h) {
|
||||
viewportY = 0;
|
||||
viewportWidth = w2;
|
||||
viewportHeight = h;
|
||||
LOG("OK1 : x:%d,y:%d w:%d,h:%d", viewportX, viewportY, viewportWidth, viewportHeight);
|
||||
//LOG("OK1 : x:%d,y:%d w:%d,h:%d", viewportX, viewportY, viewportWidth, viewportHeight);
|
||||
} else if (h2 <= h) {
|
||||
viewportX = 0;
|
||||
viewportY = (h-h2)/2;
|
||||
viewportWidth = w;
|
||||
viewportHeight = h2;
|
||||
LOG("OK2 : x:%d,y:%d w:%d,h:%d", viewportX, viewportY, viewportWidth, viewportHeight);
|
||||
//LOG("OK2 : x:%d,y:%d w:%d,h:%d", viewportX, viewportY, viewportWidth, viewportHeight);
|
||||
} else {
|
||||
viewportX = 0;
|
||||
viewportY = 0;
|
||||
viewportWidth = w;
|
||||
viewportHeight = h;
|
||||
LOG("small viewport : x:%d,y:%d w:%d,h:%d", viewportX, viewportY, viewportWidth, viewportHeight);
|
||||
//LOG("small viewport : x:%d,y:%d w:%d,h:%d", viewportX, viewportY, viewportWidth, viewportHeight);
|
||||
}
|
||||
|
||||
glViewport(viewportX, viewportY, viewportWidth, viewportHeight);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void video_set_mode(a2_video_mode_t mode) {
|
||||
// no-op ...
|
||||
}
|
||||
|
||||
void video_driver_init(void) {
|
||||
#if defined(__APPLE__)
|
||||
gldriver_init_common();
|
||||
#else
|
||||
#if USE_GLUT
|
||||
static void _init_with_glut(GLuint fbo) {
|
||||
glutInit(&argc, argv);
|
||||
glutInitDisplayMode(/*GLUT_DOUBLE|*/GLUT_RGBA/*|GLUT_DEPTH*/);
|
||||
glutInitDisplayMode(/*GLUT_DOUBLE|*/GLUT_RGBA|GLUT_DEPTH);
|
||||
glutInitWindowSize(windowWidth, windowHeight);
|
||||
//glutInitContextVersion(4, 0); -- Is this needed?
|
||||
glutInitContextProfile(GLUT_CORE_PROFILE);
|
||||
@ -414,7 +684,7 @@ void video_driver_init(void) {
|
||||
gldriver_init_common();
|
||||
|
||||
glutIdleFunc(gldriver_update);
|
||||
glutDisplayFunc(gldriver_display);
|
||||
glutDisplayFunc(gldriver_render);
|
||||
glutReshapeFunc(gldriver_reshape);
|
||||
//glutMouseFunc(gldriver_mouse);
|
||||
//glutMotionFunc(gldriver_mouse_drag);
|
||||
@ -425,21 +695,46 @@ void video_driver_init(void) {
|
||||
glutSpecialFunc(gldriver_on_key_special_down);
|
||||
glutSpecialUpFunc(gldriver_on_key_special_up);
|
||||
#endif
|
||||
#endif // !__APPLE__
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// renderer API
|
||||
|
||||
void video_driver_init(void *fbo) {
|
||||
defaultFBO = (GLuint)fbo;
|
||||
#if defined(__APPLE__)
|
||||
gldriver_init_common();
|
||||
#elif USE_GLUT
|
||||
gldriver_init_glut();
|
||||
#else
|
||||
#error no working codepaths
|
||||
#endif
|
||||
}
|
||||
|
||||
void video_driver_main_loop(void) {
|
||||
#if USE_GLUT
|
||||
glutMainLoop();
|
||||
#endif
|
||||
}
|
||||
|
||||
void video_driver_render(void) {
|
||||
gldriver_render();
|
||||
}
|
||||
|
||||
void video_driver_reshape(int w, int h) {
|
||||
gldriver_reshape(w, h);
|
||||
}
|
||||
|
||||
void video_driver_sync(void) {
|
||||
if (is_headless) {
|
||||
return;
|
||||
}
|
||||
#if USE_GLUT
|
||||
glutPostRedisplay();
|
||||
#endif
|
||||
}
|
||||
|
||||
void video_driver_shutdown(void) {
|
||||
// FIXME TODO ...
|
||||
gldriver_shutdown();
|
||||
}
|
||||
|
||||
|
18
src/video/renderer.h
Normal file
18
src/video/renderer.h
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Apple // emulator for *nix
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
// glvideo -- Created by Aaron Culliney
|
||||
|
||||
void video_driver_init(void *context);
|
||||
void video_driver_main_loop(void);
|
||||
void video_driver_reshape(int width, int height);
|
||||
void video_driver_render(void);
|
||||
void video_driver_shutdown(void);
|
@ -14,8 +14,14 @@
|
||||
// #define USE_GL3W
|
||||
|
||||
#if defined(__APPLE__)
|
||||
# include <OpenGLES/ES2/gl.h>
|
||||
# include <OpenGLES/ES2/glext.h>
|
||||
# include <TargetConditionals.h>
|
||||
# if TARGET_OS_MAC
|
||||
# include <OpenGL/OpenGL.h>
|
||||
# include <OpenGL/gl3.h>
|
||||
# else
|
||||
# include <OpenGLES/ES2/gl.h>
|
||||
# include <OpenGLES/ES2/glext.h>
|
||||
# endif
|
||||
#elif defined(USE_GL3W)
|
||||
# include <GL3/gl3.h>
|
||||
# include <GL3/gl3w.h>
|
||||
|
@ -109,8 +109,6 @@ void video_loadfont_int(int first, int qty, const uint8_t *data);
|
||||
*/
|
||||
void video_plotchar(int row, int col, int color, uint8_t code);
|
||||
|
||||
void video_set_mode(a2_video_mode_t mode);
|
||||
|
||||
/*
|
||||
* Get a reference to current internal framebuffer
|
||||
*/
|
||||
|
@ -430,7 +430,7 @@ static void c_flash_cursor(int on) {
|
||||
}
|
||||
}
|
||||
|
||||
void video_driver_sync(void) {
|
||||
static void video_driver_sync(void) {
|
||||
if (is_headless) {
|
||||
return;
|
||||
}
|
||||
@ -676,7 +676,7 @@ void video_set_mode(a2_video_mode_t mode) {
|
||||
_size_hints_set_fixed();
|
||||
}
|
||||
|
||||
void video_driver_init() {
|
||||
void video_driver_init(void *context) {
|
||||
XSetWindowAttributes attribs;
|
||||
unsigned long attribmask;
|
||||
int x, y; /* window position */
|
||||
|
145
src/video_util/glUtil.h
Normal file
145
src/video_util/glUtil.h
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
File: glUtil.h
|
||||
Abstract:
|
||||
Includes the appropriate OpenGL headers (depending on whether this
|
||||
is built for iOS or OSX) and provides some API utility functions
|
||||
|
||||
Version: 1.7
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __GL_UTIL_H__
|
||||
#define __GL_UTIL_H__
|
||||
|
||||
#if ESSENTIAL_GL_PRACTICES_IOS
|
||||
|
||||
#import <OpenGLES/ES2/gl.h>
|
||||
#import <OpenGLES/ES2/glext.h>
|
||||
|
||||
#else
|
||||
|
||||
#import <OpenGL/OpenGL.h>
|
||||
|
||||
// OpenGL 3.2 is only supported on MacOS X Lion and later
|
||||
// CGL_VERSION_1_3 is defined as 1 on MacOS X Lion and later
|
||||
#if CGL_VERSION_1_3
|
||||
// Set to 0 to run on the Legacy OpenGL Profile
|
||||
#define ESSENTIAL_GL_PRACTICES_SUPPORT_GL3 1
|
||||
#else
|
||||
#define ESSENTIAL_GL_PRACTICES_SUPPORT_GL3 0
|
||||
#endif //!CGL_VERSION_1_3
|
||||
|
||||
#if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||
#import <OpenGL/gl3.h>
|
||||
#else
|
||||
#import <OpenGL/gl.h>
|
||||
#endif //!ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||
|
||||
#endif // !ESSENTIAL_GL_PRACTICES_IOS
|
||||
|
||||
|
||||
//The name of the VertexArrayObject are slightly different in
|
||||
// OpenGLES, OpenGL Core Profile, and OpenGL Legacy
|
||||
// The arguments are exactly the same across these APIs however
|
||||
#if ESSENTIAL_GL_PRACTICES_IOS
|
||||
#define glBindVertexArray glBindVertexArrayOES
|
||||
#define glGenVertexArrays glGenVertexArraysOES
|
||||
#define glDeleteVertexArrays glDeleteVertexArraysOES
|
||||
#else
|
||||
#if ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||
#define glBindVertexArray glBindVertexArray
|
||||
#define glGenVertexArrays glGenVertexArrays
|
||||
#define glGenerateMipmap glGenerateMipmap
|
||||
#define glDeleteVertexArrays glDeleteVertexArrays
|
||||
#else
|
||||
#define glBindVertexArray glBindVertexArrayAPPLE
|
||||
#define glGenVertexArrays glGenVertexArraysAPPLE
|
||||
#define glGenerateMipmap glGenerateMipmapEXT
|
||||
#define glDeleteVertexArrays glDeleteVertexArraysAPPLE
|
||||
#endif //!ESSENTIAL_GL_PRACTICES_SUPPORT_GL3
|
||||
#endif //!ESSENTIAL_GL_PRACTICES_IOS
|
||||
|
||||
static inline const char * GetGLErrorString(GLenum error)
|
||||
{
|
||||
const char *str;
|
||||
switch( error )
|
||||
{
|
||||
case GL_NO_ERROR:
|
||||
str = "GL_NO_ERROR";
|
||||
break;
|
||||
case GL_INVALID_ENUM:
|
||||
str = "GL_INVALID_ENUM";
|
||||
break;
|
||||
case GL_INVALID_VALUE:
|
||||
str = "GL_INVALID_VALUE";
|
||||
break;
|
||||
case GL_INVALID_OPERATION:
|
||||
str = "GL_INVALID_OPERATION";
|
||||
break;
|
||||
#if defined __gl_h_ || defined __gl3_h_
|
||||
case GL_OUT_OF_MEMORY:
|
||||
str = "GL_OUT_OF_MEMORY";
|
||||
break;
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
str = "GL_INVALID_FRAMEBUFFER_OPERATION";
|
||||
break;
|
||||
#endif
|
||||
#if defined __gl_h_
|
||||
case GL_STACK_OVERFLOW:
|
||||
str = "GL_STACK_OVERFLOW";
|
||||
break;
|
||||
case GL_STACK_UNDERFLOW:
|
||||
str = "GL_STACK_UNDERFLOW";
|
||||
break;
|
||||
case GL_TABLE_TOO_LARGE:
|
||||
str = "GL_TABLE_TOO_LARGE";
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
str = "(ERROR: Unknown Error Enum)";
|
||||
break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
#endif // __GL_UTIL_H__
|
75
src/video_util/imageUtil.h
Normal file
75
src/video_util/imageUtil.h
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
File: imageUtil.h
|
||||
Abstract:
|
||||
Functions for loading an image files for textures.
|
||||
|
||||
Version: 1.7
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __IMAGE_UTIL_H__
|
||||
#define __IMAGE_UTIL_H__
|
||||
|
||||
#include "glUtil.h"
|
||||
|
||||
typedef struct demoImageRec
|
||||
{
|
||||
GLubyte* data;
|
||||
|
||||
GLsizei size;
|
||||
|
||||
GLuint width;
|
||||
GLuint height;
|
||||
GLenum format;
|
||||
GLenum type;
|
||||
|
||||
GLuint rowByteSize;
|
||||
|
||||
} demoImage;
|
||||
|
||||
demoImage* imgLoadImage(const char* filepathname, int flipVertical);
|
||||
|
||||
void imgDestroyImage(demoImage* image);
|
||||
|
||||
#endif //__IMAGE_UTIL_H__
|
||||
|
116
src/video_util/imageUtil.m
Normal file
116
src/video_util/imageUtil.m
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
File: imageUtil.m
|
||||
Abstract:
|
||||
Functions for loading an image files for textures.
|
||||
|
||||
Version: 1.7
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#include "imageUtil.h"
|
||||
|
||||
#if ESSENTIAL_GL_PRACTICES_IOS
|
||||
#import <UIKit/UIKit.h>
|
||||
#else
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#endif
|
||||
|
||||
demoImage* imgLoadImage(const char* filepathname, int flipVertical)
|
||||
{
|
||||
NSString *filepathString = [[NSString alloc] initWithUTF8String:filepathname];
|
||||
|
||||
#if ESSENTIAL_GL_PRACTICES_IOS
|
||||
UIImage* imageClass = [[UIImage alloc] initWithContentsOfFile:filepathString];
|
||||
#else
|
||||
NSImage *nsimage = [[NSImage alloc] initWithContentsOfFile: filepathString];
|
||||
|
||||
NSBitmapImageRep *imageClass = [[NSBitmapImageRep alloc] initWithData:[nsimage TIFFRepresentation]];
|
||||
[nsimage release];
|
||||
#endif
|
||||
|
||||
CGImageRef cgImage = imageClass.CGImage;
|
||||
if (!cgImage)
|
||||
{
|
||||
[filepathString release];
|
||||
[imageClass release];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
demoImage* image = malloc(sizeof(demoImage));
|
||||
image->width = CGImageGetWidth(cgImage);
|
||||
image->height = CGImageGetHeight(cgImage);
|
||||
image->rowByteSize = image->width * 4;
|
||||
image->data = malloc(image->height * image->rowByteSize);
|
||||
image->format = GL_RGBA;
|
||||
image->type = GL_UNSIGNED_BYTE;
|
||||
|
||||
CGContextRef context = CGBitmapContextCreate(image->data, image->width, image->height, 8, image->rowByteSize, CGImageGetColorSpace(cgImage), kCGImageAlphaNoneSkipLast);
|
||||
CGContextSetBlendMode(context, kCGBlendModeCopy);
|
||||
if(flipVertical)
|
||||
{
|
||||
CGContextTranslateCTM(context, 0.0, image->height);
|
||||
CGContextScaleCTM(context, 1.0, -1.0);
|
||||
}
|
||||
CGContextDrawImage(context, CGRectMake(0.0, 0.0, image->width, image->height), cgImage);
|
||||
CGContextRelease(context);
|
||||
|
||||
if(NULL == image->data)
|
||||
{
|
||||
[filepathString release];
|
||||
[imageClass release];
|
||||
|
||||
imgDestroyImage(image);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
[filepathString release];
|
||||
[imageClass release];
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
void imgDestroyImage(demoImage* image)
|
||||
{
|
||||
free(image->data);
|
||||
free(image);
|
||||
}
|
990
src/video_util/matrixUtil.c
Normal file
990
src/video_util/matrixUtil.c
Normal file
@ -0,0 +1,990 @@
|
||||
/*
|
||||
File: matrixUtil.c
|
||||
Abstract:
|
||||
Functions for performing matrix math.
|
||||
|
||||
Version: 1.7
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#include "matrixUtil.h"
|
||||
#include "vectorUtil.h"
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
|
||||
void mtxMultiply(float* ret, const float* lhs, const float* rhs)
|
||||
{
|
||||
// [ 0 4 8 12 ] [ 0 4 8 12 ]
|
||||
// [ 1 5 9 13 ] x [ 1 5 9 13 ]
|
||||
// [ 2 6 10 14 ] [ 2 6 10 14 ]
|
||||
// [ 3 7 11 15 ] [ 3 7 11 15 ]
|
||||
ret[ 0] = lhs[ 0]*rhs[ 0] + lhs[ 4]*rhs[ 1] + lhs[ 8]*rhs[ 2] + lhs[12]*rhs[ 3];
|
||||
ret[ 1] = lhs[ 1]*rhs[ 0] + lhs[ 5]*rhs[ 1] + lhs[ 9]*rhs[ 2] + lhs[13]*rhs[ 3];
|
||||
ret[ 2] = lhs[ 2]*rhs[ 0] + lhs[ 6]*rhs[ 1] + lhs[10]*rhs[ 2] + lhs[14]*rhs[ 3];
|
||||
ret[ 3] = lhs[ 3]*rhs[ 0] + lhs[ 7]*rhs[ 1] + lhs[11]*rhs[ 2] + lhs[15]*rhs[ 3];
|
||||
|
||||
ret[ 4] = lhs[ 0]*rhs[ 4] + lhs[ 4]*rhs[ 5] + lhs[ 8]*rhs[ 6] + lhs[12]*rhs[ 7];
|
||||
ret[ 5] = lhs[ 1]*rhs[ 4] + lhs[ 5]*rhs[ 5] + lhs[ 9]*rhs[ 6] + lhs[13]*rhs[ 7];
|
||||
ret[ 6] = lhs[ 2]*rhs[ 4] + lhs[ 6]*rhs[ 5] + lhs[10]*rhs[ 6] + lhs[14]*rhs[ 7];
|
||||
ret[ 7] = lhs[ 3]*rhs[ 4] + lhs[ 7]*rhs[ 5] + lhs[11]*rhs[ 6] + lhs[15]*rhs[ 7];
|
||||
|
||||
ret[ 8] = lhs[ 0]*rhs[ 8] + lhs[ 4]*rhs[ 9] + lhs[ 8]*rhs[10] + lhs[12]*rhs[11];
|
||||
ret[ 9] = lhs[ 1]*rhs[ 8] + lhs[ 5]*rhs[ 9] + lhs[ 9]*rhs[10] + lhs[13]*rhs[11];
|
||||
ret[10] = lhs[ 2]*rhs[ 8] + lhs[ 6]*rhs[ 9] + lhs[10]*rhs[10] + lhs[14]*rhs[11];
|
||||
ret[11] = lhs[ 3]*rhs[ 8] + lhs[ 7]*rhs[ 9] + lhs[11]*rhs[10] + lhs[15]*rhs[11];
|
||||
|
||||
ret[12] = lhs[ 0]*rhs[12] + lhs[ 4]*rhs[13] + lhs[ 8]*rhs[14] + lhs[12]*rhs[15];
|
||||
ret[13] = lhs[ 1]*rhs[12] + lhs[ 5]*rhs[13] + lhs[ 9]*rhs[14] + lhs[13]*rhs[15];
|
||||
ret[14] = lhs[ 2]*rhs[12] + lhs[ 6]*rhs[13] + lhs[10]*rhs[14] + lhs[14]*rhs[15];
|
||||
ret[15] = lhs[ 3]*rhs[12] + lhs[ 7]*rhs[13] + lhs[11]*rhs[14] + lhs[15]*rhs[15];}
|
||||
|
||||
|
||||
void mtxLoadPerspective(float* mtx, float fov, float aspect, float nearZ, float farZ)
|
||||
{
|
||||
float f = 1.0f / tanf( (fov * (M_PI/180)) / 2.0f);
|
||||
|
||||
mtx[0] = f / aspect;
|
||||
mtx[1] = 0.0f;
|
||||
mtx[2] = 0.0f;
|
||||
mtx[3] = 0.0f;
|
||||
|
||||
mtx[4] = 0.0f;
|
||||
mtx[5] = f;
|
||||
mtx[6] = 0.0f;
|
||||
mtx[7] = 0.0f;
|
||||
|
||||
mtx[8] = 0.0f;
|
||||
mtx[9] = 0.0f;
|
||||
mtx[10] = (farZ+nearZ) / (nearZ-farZ);
|
||||
mtx[11] = -1.0f;
|
||||
|
||||
mtx[12] = 0.0f;
|
||||
mtx[13] = 0.0f;
|
||||
mtx[14] = 2 * farZ * nearZ / (nearZ-farZ);
|
||||
mtx[15] = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
void mtxLoadOrthographic(float* mtx,
|
||||
float left, float right,
|
||||
float bottom, float top,
|
||||
float nearZ, float farZ)
|
||||
{
|
||||
//See appendix G of OpenGL Red Book
|
||||
|
||||
mtx[ 0] = 2.0f / (right - left);
|
||||
mtx[ 1] = 0.0;
|
||||
mtx[ 2] = 0.0;
|
||||
mtx[ 3] = 0.0;
|
||||
|
||||
mtx[ 4] = 0.0;
|
||||
mtx[ 5] = 2.0f / (top - bottom);
|
||||
mtx[ 6] = 0.0;
|
||||
mtx[ 7] = 0.0;
|
||||
|
||||
mtx[ 8] = 0.0;
|
||||
mtx[ 9] = 0.0;
|
||||
mtx[10] = -2.0f / (farZ - nearZ);
|
||||
mtx[11] = 0.0;
|
||||
|
||||
mtx[12] = -(right + left) / (right - left);
|
||||
mtx[13] = -(top + bottom) / (top - bottom);
|
||||
mtx[14] = -(farZ + nearZ) / (farZ - nearZ);
|
||||
mtx[15] = 1.0f;
|
||||
}
|
||||
|
||||
static inline float sgn(float val)
|
||||
{
|
||||
return (val > 0.0f) ? 1.0f : ((val < 0.0f) ? -1.0f : 0.0f);
|
||||
}
|
||||
|
||||
void mtxModifyObliqueProjection(float* mtx, const float* src, const float* plane)
|
||||
{
|
||||
float vec[4];
|
||||
|
||||
memcpy(mtx, src, 16 * sizeof(float));
|
||||
|
||||
vec[0] = (sgn(plane[0]) + mtx[8]) / mtx[0];
|
||||
vec[1] = (sgn(plane[1]) + mtx[9]) / mtx[5];
|
||||
vec[2] = -1.0f;
|
||||
vec[3] = (1.0f + mtx[10]) / mtx[14];
|
||||
|
||||
float dot = vec4DotProduct(plane, vec);
|
||||
|
||||
vec[0] = plane[0] * (2.0f / dot);
|
||||
vec[1] = plane[1] * (2.0f / dot);
|
||||
vec[2] = plane[2] * (2.0f / dot);
|
||||
vec[3] = plane[3] * (2.0f / dot);
|
||||
|
||||
// Replace the third row of the projection matrix
|
||||
mtx[ 2] = vec[0];
|
||||
mtx[ 6] = vec[1];
|
||||
mtx[10] = vec[2];
|
||||
mtx[14] = vec[3];
|
||||
}
|
||||
|
||||
void mtxTranspose(float* mtx, const float* src)
|
||||
{
|
||||
//Use a temp to swap in case mtx == src
|
||||
|
||||
float tmp;
|
||||
mtx[0] = src[0];
|
||||
mtx[5] = src[5];
|
||||
mtx[10] = src[10];
|
||||
mtx[15] = src[15];
|
||||
|
||||
tmp = src[4];
|
||||
mtx[4] = src[1];
|
||||
mtx[1] = tmp;
|
||||
|
||||
tmp = src[8];
|
||||
mtx[8] = src[2];
|
||||
mtx[2] = tmp;
|
||||
|
||||
tmp = src[12];
|
||||
mtx[12] = src[3];
|
||||
mtx[3] = tmp;
|
||||
|
||||
tmp = src[9];
|
||||
mtx[9] = src[6];
|
||||
mtx[6] = tmp;
|
||||
|
||||
tmp = src[13];
|
||||
mtx[13] = src[7];
|
||||
mtx[ 7] = tmp;
|
||||
|
||||
tmp = src[14];
|
||||
mtx[14] = src[11];
|
||||
mtx[11] = tmp;
|
||||
|
||||
}
|
||||
|
||||
void mtxInvert(float* mtx, const float* src)
|
||||
{
|
||||
float tmp[16];
|
||||
float val, val2, val_inv;
|
||||
int i, j, i4, i8, i12, ind;
|
||||
|
||||
mtxTranspose(tmp, src);
|
||||
|
||||
mtxLoadIdentity(mtx);
|
||||
|
||||
|
||||
for(i = 0; i != 4; i++)
|
||||
{
|
||||
val = tmp[(i << 2) + i];
|
||||
ind = i;
|
||||
|
||||
i4 = i + 4;
|
||||
i8 = i + 8;
|
||||
i12 = i + 12;
|
||||
|
||||
for (j = i + 1; j != 4; j++)
|
||||
{
|
||||
if(fabsf(tmp[(i << 2) + j]) > fabsf(val))
|
||||
{
|
||||
ind = j;
|
||||
val = tmp[(i << 2) + j];
|
||||
}
|
||||
}
|
||||
|
||||
if(ind != i)
|
||||
{
|
||||
val2 = mtx[i];
|
||||
mtx[i] = mtx[ind];
|
||||
mtx[ind] = val2;
|
||||
|
||||
val2 = tmp[i];
|
||||
tmp[i] = tmp[ind];
|
||||
tmp[ind] = val2;
|
||||
|
||||
ind += 4;
|
||||
|
||||
val2 = mtx[i4];
|
||||
mtx[i4] = mtx[ind];
|
||||
mtx[ind] = val2;
|
||||
|
||||
val2 = tmp[i4];
|
||||
tmp[i4] = tmp[ind];
|
||||
tmp[ind] = val2;
|
||||
|
||||
ind += 4;
|
||||
|
||||
val2 = mtx[i8];
|
||||
mtx[i8] = mtx[ind];
|
||||
mtx[ind] = val2;
|
||||
|
||||
val2 = tmp[i8];
|
||||
tmp[i8] = tmp[ind];
|
||||
tmp[ind] = val2;
|
||||
|
||||
ind += 4;
|
||||
|
||||
val2 = mtx[i12];
|
||||
mtx[i12] = mtx[ind];
|
||||
mtx[ind] = val2;
|
||||
|
||||
val2 = tmp[i12];
|
||||
tmp[i12] = tmp[ind];
|
||||
tmp[ind] = val2;
|
||||
}
|
||||
|
||||
if(val == 0)
|
||||
{
|
||||
mtxLoadIdentity(mtx);
|
||||
return;
|
||||
}
|
||||
|
||||
val_inv = 1.0f / val;
|
||||
|
||||
tmp[i] *= val_inv;
|
||||
mtx[i] *= val_inv;
|
||||
|
||||
tmp[i4] *= val_inv;
|
||||
mtx[i4] *= val_inv;
|
||||
|
||||
tmp[i8] *= val_inv;
|
||||
mtx[i8] *= val_inv;
|
||||
|
||||
tmp[i12] *= val_inv;
|
||||
mtx[i12] *= val_inv;
|
||||
|
||||
if(i != 0)
|
||||
{
|
||||
val = tmp[i << 2];
|
||||
|
||||
tmp[0] -= tmp[i] * val;
|
||||
mtx[0] -= mtx[i] * val;
|
||||
|
||||
tmp[4] -= tmp[i4] * val;
|
||||
mtx[4] -= mtx[i4] * val;
|
||||
|
||||
tmp[8] -= tmp[i8] * val;
|
||||
mtx[8] -= mtx[i8] * val;
|
||||
|
||||
tmp[12] -= tmp[i12] * val;
|
||||
mtx[12] -= mtx[i12] * val;
|
||||
}
|
||||
|
||||
if(i != 1)
|
||||
{
|
||||
val = tmp[(i << 2) + 1];
|
||||
|
||||
tmp[1] -= tmp[i] * val;
|
||||
mtx[1] -= mtx[i] * val;
|
||||
|
||||
tmp[5] -= tmp[i4] * val;
|
||||
mtx[5] -= mtx[i4] * val;
|
||||
|
||||
tmp[9] -= tmp[i8] * val;
|
||||
mtx[9] -= mtx[i8] * val;
|
||||
|
||||
tmp[13] -= tmp[i12] * val;
|
||||
mtx[13] -= mtx[i12] * val;
|
||||
}
|
||||
|
||||
if(i != 2)
|
||||
{
|
||||
val = tmp[(i << 2) + 2];
|
||||
|
||||
tmp[2] -= tmp[i] * val;
|
||||
mtx[2] -= mtx[i] * val;
|
||||
|
||||
tmp[6] -= tmp[i4] * val;
|
||||
mtx[6] -= mtx[i4] * val;
|
||||
|
||||
tmp[10] -= tmp[i8] * val;
|
||||
mtx[10] -= mtx[i8] * val;
|
||||
|
||||
tmp[14] -= tmp[i12] * val;
|
||||
mtx[14] -= mtx[i12] * val;
|
||||
}
|
||||
|
||||
if(i != 3)
|
||||
{
|
||||
val = tmp[(i << 2) + 3];
|
||||
|
||||
tmp[3] -= tmp[i] * val;
|
||||
mtx[3] -= mtx[i] * val;
|
||||
|
||||
tmp[7] -= tmp[i4] * val;
|
||||
mtx[7] -= mtx[i4] * val;
|
||||
|
||||
tmp[11] -= tmp[i8] * val;
|
||||
mtx[11] -= mtx[i8] * val;
|
||||
|
||||
tmp[15] -= tmp[i12] * val;
|
||||
mtx[15] -= mtx[i12] * val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mtxLoadIdentity(float* mtx)
|
||||
{
|
||||
// [ 0 4 8 12 ]
|
||||
// [ 1 5 9 13 ]
|
||||
// [ 2 6 10 14 ]
|
||||
// [ 3 7 11 15 ]
|
||||
mtx[ 0] = mtx[ 5] = mtx[10] = mtx[15] = 1.0f;
|
||||
|
||||
mtx[ 1] = mtx[ 2] = mtx[ 3] = mtx[ 4] =
|
||||
mtx[ 6] = mtx[ 7] = mtx[ 8] = mtx[ 9] =
|
||||
mtx[11] = mtx[12] = mtx[13] = mtx[14] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
void mtxLoadTranslate(float* mtx, float xTrans, float yTrans, float zTrans)
|
||||
{
|
||||
|
||||
// [ 0 4 8 x ]
|
||||
// [ 1 5 9 y ]
|
||||
// [ 2 6 10 z ]
|
||||
// [ 3 7 11 15 ]
|
||||
mtx[ 0] = mtx[ 5] = mtx[10] = mtx[15] = 1.0f;
|
||||
|
||||
mtx[ 1] = mtx[ 2] = mtx[ 3] = mtx[ 4] =
|
||||
mtx[ 6] = mtx[ 7] = mtx[ 8] = mtx[ 9] =
|
||||
mtx[11] = 0.0;
|
||||
|
||||
mtx[12] = xTrans;
|
||||
mtx[13] = yTrans;
|
||||
mtx[14] = zTrans;
|
||||
}
|
||||
|
||||
|
||||
void mtxLoadScale(float* mtx, float xScale, float yScale, float zScale)
|
||||
{
|
||||
// [ x 4 8 12 ]
|
||||
// [ 1 y 9 13 ]
|
||||
// [ 2 6 z 14 ]
|
||||
// [ 3 7 11 15 ]
|
||||
mtx[ 0] = xScale;
|
||||
mtx[ 5] = yScale;
|
||||
mtx[10] = zScale;
|
||||
mtx[15] = 1.0f;
|
||||
|
||||
mtx[ 1] = mtx[ 2] = mtx[ 3] = mtx[ 4] =
|
||||
mtx[ 6] = mtx[ 7] = mtx[ 8] = mtx[ 9] =
|
||||
mtx[11] = mtx[12] = mtx[13] = mtx[14] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
void mtxLoadRotateX(float* mtx, float rad)
|
||||
{
|
||||
// [ 0 4 8 12 ]
|
||||
// [ 1 cos -sin 13 ]
|
||||
// [ 2 sin cos 14 ]
|
||||
// [ 3 7 11 15 ]
|
||||
|
||||
mtx[10] = mtx[ 5] = cosf(rad);
|
||||
mtx[ 6] = sinf(rad);
|
||||
mtx[ 9] = -mtx[ 6];
|
||||
|
||||
mtx[ 0] = mtx[15] = 1.0f;
|
||||
|
||||
mtx[ 1] = mtx[ 2] = mtx[ 3] = mtx[ 4] =
|
||||
mtx[ 7] = mtx[ 8] = mtx[11] = mtx[12] =
|
||||
mtx[13] = mtx[14] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
void mtxLoadRotateY(float* mtx, float rad)
|
||||
{
|
||||
// [ cos 4 -sin 12 ]
|
||||
// [ 1 5 9 13 ]
|
||||
// [ sin 6 cos 14 ]
|
||||
// [ 3 7 11 15 ]
|
||||
|
||||
mtx[ 0] = mtx[10] = cosf(rad);
|
||||
mtx[ 2] = sinf(rad);
|
||||
mtx[ 8] = -mtx[2];
|
||||
|
||||
mtx[ 5] = mtx[15] = 1.0;
|
||||
|
||||
mtx[ 1] = mtx[ 3] = mtx[ 4] = mtx[ 6] =
|
||||
mtx[ 7] = mtx[ 9] = mtx[11] = mtx[12] =
|
||||
mtx[13] = mtx[14] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
void mtxLoadRotateZ(float* mtx, float rad)
|
||||
{
|
||||
// [ cos -sin 8 12 ]
|
||||
// [ sin cos 9 13 ]
|
||||
// [ 2 6 10 14 ]
|
||||
// [ 3 7 11 15 ]
|
||||
|
||||
mtx[ 0] = mtx[ 5] = cosf(rad);
|
||||
mtx[ 1] = sinf(rad);
|
||||
mtx[ 4] = -mtx[1];
|
||||
|
||||
mtx[10] = mtx[15] = 1.0;
|
||||
|
||||
mtx[ 2] = mtx[ 3] = mtx[ 6] = mtx[ 7] =
|
||||
mtx[ 8] = mtx[ 9] = mtx[11] = mtx[12] =
|
||||
mtx[13] = mtx[14] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
void mtxLoadRotate(float* mtx, float deg, float xAxis, float yAxis, float zAxis)
|
||||
{
|
||||
float rad = deg * M_PI/180.0f;
|
||||
|
||||
float sin_a = sinf(rad);
|
||||
float cos_a = cosf(rad);
|
||||
|
||||
// Calculate coeffs. No need to check for zero magnitude because we wouldn't be here.
|
||||
float magnitude = sqrtf(xAxis * xAxis + yAxis * yAxis + zAxis * zAxis);
|
||||
|
||||
float p = 1.0f / magnitude;
|
||||
float cos_am = 1.0f - cos_a;
|
||||
|
||||
float xp = xAxis * p;
|
||||
float yp = yAxis * p;
|
||||
float zp = zAxis * p;
|
||||
|
||||
float xx = xp * xp;
|
||||
float yy = yp * yp;
|
||||
float zz = zp * zp;
|
||||
|
||||
float xy = xp * yp * cos_am;
|
||||
float yz = yp * zp * cos_am;
|
||||
float zx = zp * xp * cos_am;
|
||||
|
||||
xp *= sin_a;
|
||||
yp *= sin_a;
|
||||
zp *= sin_a;
|
||||
|
||||
// Load coefs
|
||||
float m0 = xx + cos_a * (1.0f - xx);
|
||||
float m1 = xy + zp;
|
||||
float m2 = zx - yp;
|
||||
float m4 = xy - zp;
|
||||
float m5 = yy + cos_a * (1.0f - yy);
|
||||
float m6 = yz + xp;
|
||||
float m8 = zx + yp;
|
||||
float m9 = yz - xp;
|
||||
float m10 = zz + cos_a * (1.0f - zz);
|
||||
|
||||
// Apply rotation
|
||||
float c1 = mtx[0];
|
||||
float c2 = mtx[4];
|
||||
float c3 = mtx[8];
|
||||
mtx[0] = c1 * m0 + c2 * m1 + c3 * m2;
|
||||
mtx[4] = c1 * m4 + c2 * m5 + c3 * m6;
|
||||
mtx[8] = c1 * m8 + c2 * m9 + c3 * m10;
|
||||
|
||||
c1 = mtx[1];
|
||||
c2 = mtx[5];
|
||||
c3 = mtx[9];
|
||||
mtx[1] = c1 * m0 + c2 * m1 + c3 * m2;
|
||||
mtx[5] = c1 * m4 + c2 * m5 + c3 * m6;
|
||||
mtx[9] = c1 * m8 + c2 * m9 + c3 * m10;
|
||||
|
||||
c1 = mtx[2];
|
||||
c2 = mtx[6];
|
||||
c3 = mtx[10];
|
||||
mtx[2] = c1 * m0 + c2 * m1 + c3 * m2;
|
||||
mtx[6] = c1 * m4 + c2 * m5 + c3 * m6;
|
||||
mtx[10] = c1 * m8 + c2 * m9 + c3 * m10;
|
||||
|
||||
c1 = mtx[3];
|
||||
c2 = mtx[7];
|
||||
c3 = mtx[11];
|
||||
mtx[3] = c1 * m0 + c2 * m1 + c3 * m2;
|
||||
mtx[7] = c1 * m4 + c2 * m5 + c3 * m6;
|
||||
mtx[11] = c1 * m8 + c2 * m9 + c3 * m10;
|
||||
|
||||
mtx[12] = mtx[13] = mtx[14] = 0.0;
|
||||
mtx[15] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
void mtxTranslateApply(float* mtx, float xTrans, float yTrans, float zTrans)
|
||||
{
|
||||
// [ 0 4 8 12 ] [ 1 0 0 x ]
|
||||
// [ 1 5 9 13 ] x [ 0 1 0 y ]
|
||||
// [ 2 6 10 14 ] [ 0 0 1 z ]
|
||||
// [ 3 7 11 15 ] [ 0 0 0 1 ]
|
||||
|
||||
mtx[12] += mtx[0]*xTrans + mtx[4]*yTrans + mtx[ 8]*zTrans;
|
||||
mtx[13] += mtx[1]*xTrans + mtx[5]*yTrans + mtx[ 9]*zTrans;
|
||||
mtx[14] += mtx[2]*xTrans + mtx[6]*yTrans + mtx[10]*zTrans;
|
||||
}
|
||||
|
||||
|
||||
void mtxScaleApply(float* mtx, float xScale, float yScale, float zScale)
|
||||
{
|
||||
// [ 0 4 8 12 ] [ x 0 0 0 ]
|
||||
// [ 1 5 9 13 ] x [ 0 y 0 0 ]
|
||||
// [ 2 6 10 14 ] [ 0 0 z 0 ]
|
||||
// [ 3 7 11 15 ] [ 0 0 0 1 ]
|
||||
|
||||
mtx[ 0] *= xScale;
|
||||
mtx[ 4] *= yScale;
|
||||
mtx[ 8] *= zScale;
|
||||
|
||||
mtx[ 1] *= xScale;
|
||||
mtx[ 5] *= yScale;
|
||||
mtx[ 9] *= zScale;
|
||||
|
||||
mtx[ 2] *= xScale;
|
||||
mtx[ 6] *= yScale;
|
||||
mtx[10] *= zScale;
|
||||
|
||||
mtx[ 3] *= xScale;
|
||||
mtx[ 7] *= yScale;
|
||||
mtx[11] *= xScale;
|
||||
}
|
||||
|
||||
|
||||
void mtxTranslateMatrix(float* mtx, float xTrans, float yTrans, float zTrans)
|
||||
{
|
||||
// [ 1 0 0 x ] [ 0 4 8 12 ]
|
||||
// [ 0 1 0 y ] x [ 1 5 9 13 ]
|
||||
// [ 0 0 1 z ] [ 2 6 10 14 ]
|
||||
// [ 0 0 0 1 ] [ 3 7 11 15 ]
|
||||
|
||||
mtx[ 0] += xTrans * mtx[ 3];
|
||||
mtx[ 1] += yTrans * mtx[ 3];
|
||||
mtx[ 2] += zTrans * mtx[ 3];
|
||||
|
||||
mtx[ 4] += xTrans * mtx[ 7];
|
||||
mtx[ 5] += yTrans * mtx[ 7];
|
||||
mtx[ 6] += zTrans * mtx[ 7];
|
||||
|
||||
mtx[ 8] += xTrans * mtx[11];
|
||||
mtx[ 9] += yTrans * mtx[11];
|
||||
mtx[10] += zTrans * mtx[11];
|
||||
|
||||
mtx[12] += xTrans * mtx[15];
|
||||
mtx[13] += yTrans * mtx[15];
|
||||
mtx[14] += zTrans * mtx[15];
|
||||
}
|
||||
|
||||
|
||||
void mtxRotateXApply(float* mtx, float deg)
|
||||
{
|
||||
// [ 0 4 8 12 ] [ 1 0 0 0 ]
|
||||
// [ 1 5 9 13 ] x [ 0 cos -sin 0 ]
|
||||
// [ 2 6 10 14 ] [ 0 sin cos 0 ]
|
||||
// [ 3 7 11 15 ] [ 0 0 0 1 ]
|
||||
|
||||
float rad = deg * (M_PI/180.0f);
|
||||
|
||||
float cosrad = cosf(rad);
|
||||
float sinrad = sinf(rad);
|
||||
|
||||
float mtx04 = mtx[4];
|
||||
float mtx05 = mtx[5];
|
||||
float mtx06 = mtx[6];
|
||||
float mtx07 = mtx[7];
|
||||
|
||||
mtx[ 4] = mtx[ 8]*sinrad + mtx04*cosrad;
|
||||
mtx[ 8] = mtx[ 8]*cosrad - mtx04*sinrad;
|
||||
|
||||
mtx[ 5] = mtx[ 9]*sinrad + mtx05*cosrad;
|
||||
mtx[ 9] = mtx[ 9]*cosrad - mtx05*sinrad;
|
||||
|
||||
mtx[ 6] = mtx[10]*sinrad + mtx06*cosrad;
|
||||
mtx[10] = mtx[10]*cosrad - mtx06*sinrad;
|
||||
|
||||
mtx[ 7] = mtx[11]*sinrad + mtx07*cosrad;
|
||||
mtx[11] = mtx[11]*cosrad - mtx07*sinrad;
|
||||
}
|
||||
|
||||
|
||||
void mtxRotateYApply(float* mtx, float deg)
|
||||
{
|
||||
// [ 0 4 8 12 ] [ cos 0 -sin 0 ]
|
||||
// [ 1 5 9 13 ] x [ 0 1 0 0 ]
|
||||
// [ 2 6 10 14 ] [ sin 0 cos 0 ]
|
||||
// [ 3 7 11 15 ] [ 0 0 0 1 ]
|
||||
|
||||
float rad = deg * (M_PI/180.0f);
|
||||
|
||||
float cosrad = cosf(rad);
|
||||
float sinrad = sinf(rad);
|
||||
|
||||
float mtx00 = mtx[0];
|
||||
float mtx01 = mtx[1];
|
||||
float mtx02 = mtx[2];
|
||||
float mtx03 = mtx[3];
|
||||
|
||||
mtx[ 0] = mtx[ 8]*sinrad + mtx00*cosrad;
|
||||
mtx[ 8] = mtx[ 8]*cosrad - mtx00*sinrad;
|
||||
|
||||
mtx[ 1] = mtx[ 9]*sinrad + mtx01*cosrad;
|
||||
mtx[ 9] = mtx[ 9]*cosrad - mtx01*sinrad;
|
||||
|
||||
mtx[ 2] = mtx[10]*sinrad + mtx02*cosrad;
|
||||
mtx[10] = mtx[10]*cosrad - mtx02*sinrad;
|
||||
|
||||
mtx[ 3] = mtx[11]*sinrad + mtx03*cosrad;
|
||||
mtx[11] = mtx[11]*cosrad - mtx03*sinrad;
|
||||
}
|
||||
|
||||
|
||||
void mtxRotateZApply(float* mtx, float deg)
|
||||
{
|
||||
// [ 0 4 8 12 ] [ cos -sin 0 0 ]
|
||||
// [ 1 5 9 13 ] x [ sin cos 0 0 ]
|
||||
// [ 2 6 10 14 ] [ 0 0 1 0 ]
|
||||
// [ 3 7 11 15 ] [ 0 0 0 1 ]
|
||||
|
||||
float rad = deg * (M_PI/180.0f);
|
||||
|
||||
float cosrad = cosf(rad);
|
||||
float sinrad = sinf(rad);
|
||||
|
||||
float mtx00 = mtx[0];
|
||||
float mtx01 = mtx[1];
|
||||
float mtx02 = mtx[2];
|
||||
float mtx03 = mtx[3];
|
||||
|
||||
mtx[ 0] = mtx[ 4]*sinrad + mtx00*cosrad;
|
||||
mtx[ 4] = mtx[ 4]*cosrad - mtx00*sinrad;
|
||||
|
||||
mtx[ 1] = mtx[ 5]*sinrad + mtx01*cosrad;
|
||||
mtx[ 5] = mtx[ 5]*cosrad - mtx01*sinrad;
|
||||
|
||||
mtx[ 2] = mtx[ 6]*sinrad + mtx02*cosrad;
|
||||
mtx[ 6] = mtx[ 6]*cosrad - mtx02*sinrad;
|
||||
|
||||
mtx[ 3] = mtx[ 7]*sinrad + mtx03*cosrad;
|
||||
mtx[ 7] = mtx[ 7]*cosrad - mtx03*sinrad;
|
||||
}
|
||||
|
||||
void mtxRotateApply(float* mtx, float deg, float xAxis, float yAxis, float zAxis)
|
||||
{
|
||||
if(yAxis == 0.0f && zAxis == 0.0f)
|
||||
{
|
||||
mtxRotateXApply(mtx, deg);
|
||||
}
|
||||
else if(xAxis == 0.0f && zAxis == 0.0f)
|
||||
{
|
||||
mtxRotateYApply(mtx, deg);
|
||||
}
|
||||
else if(xAxis == 0.0f && yAxis == 0.0f)
|
||||
{
|
||||
mtxRotateZApply(mtx, deg);
|
||||
}
|
||||
else
|
||||
{
|
||||
float rad = deg * M_PI/180.0f;
|
||||
|
||||
float sin_a = sinf(rad);
|
||||
float cos_a = cosf(rad);
|
||||
|
||||
// Calculate coeffs. No need to check for zero magnitude because we wouldn't be here.
|
||||
float magnitude = sqrtf(xAxis * xAxis + yAxis * yAxis + zAxis * zAxis);
|
||||
|
||||
float p = 1.0f / magnitude;
|
||||
float cos_am = 1.0f - cos_a;
|
||||
|
||||
float xp = xAxis * p;
|
||||
float yp = yAxis * p;
|
||||
float zp = zAxis * p;
|
||||
|
||||
float xx = xp * xp;
|
||||
float yy = yp * yp;
|
||||
float zz = zp * zp;
|
||||
|
||||
float xy = xp * yp * cos_am;
|
||||
float yz = yp * zp * cos_am;
|
||||
float zx = zp * xp * cos_am;
|
||||
|
||||
xp *= sin_a;
|
||||
yp *= sin_a;
|
||||
zp *= sin_a;
|
||||
|
||||
// Load coefs
|
||||
float m0 = xx + cos_a * (1.0f - xx);
|
||||
float m1 = xy + zp;
|
||||
float m2 = zx - yp;
|
||||
float m4 = xy - zp;
|
||||
float m5 = yy + cos_a * (1.0f - yy);
|
||||
float m6 = yz + xp;
|
||||
float m8 = zx + yp;
|
||||
float m9 = yz - xp;
|
||||
float m10 = zz + cos_a * (1.0f - zz);
|
||||
|
||||
// Apply rotation
|
||||
float c1 = mtx[0];
|
||||
float c2 = mtx[4];
|
||||
float c3 = mtx[8];
|
||||
mtx[0] = c1 * m0 + c2 * m1 + c3 * m2;
|
||||
mtx[4] = c1 * m4 + c2 * m5 + c3 * m6;
|
||||
mtx[8] = c1 * m8 + c2 * m9 + c3 * m10;
|
||||
|
||||
c1 = mtx[1];
|
||||
c2 = mtx[5];
|
||||
c3 = mtx[9];
|
||||
mtx[1] = c1 * m0 + c2 * m1 + c3 * m2;
|
||||
mtx[5] = c1 * m4 + c2 * m5 + c3 * m6;
|
||||
mtx[9] = c1 * m8 + c2 * m9 + c3 * m10;
|
||||
|
||||
c1 = mtx[2];
|
||||
c2 = mtx[6];
|
||||
c3 = mtx[10];
|
||||
mtx[2] = c1 * m0 + c2 * m1 + c3 * m2;
|
||||
mtx[6] = c1 * m4 + c2 * m5 + c3 * m6;
|
||||
mtx[10] = c1 * m8 + c2 * m9 + c3 * m10;
|
||||
|
||||
c1 = mtx[3];
|
||||
c2 = mtx[7];
|
||||
c3 = mtx[11];
|
||||
mtx[3] = c1 * m0 + c2 * m1 + c3 * m2;
|
||||
mtx[7] = c1 * m4 + c2 * m5 + c3 * m6;
|
||||
mtx[11] = c1 * m8 + c2 * m9 + c3 * m10;
|
||||
}
|
||||
}
|
||||
|
||||
void mtxScaleMatrix(float* mtx, float xScale, float yScale, float zScale)
|
||||
{
|
||||
// [ x 0 0 0 ] [ 0 4 8 12 ]
|
||||
// [ 0 y 0 0 ] x [ 1 5 9 13 ]
|
||||
// [ 0 0 z 0 ] [ 2 6 10 14 ]
|
||||
// [ 0 0 0 1 ] [ 3 7 11 15 ]
|
||||
|
||||
mtx[ 0] *= xScale;
|
||||
mtx[ 4] *= xScale;
|
||||
mtx[ 8] *= xScale;
|
||||
mtx[12] *= xScale;
|
||||
|
||||
mtx[ 1] *= yScale;
|
||||
mtx[ 5] *= yScale;
|
||||
mtx[ 9] *= yScale;
|
||||
mtx[13] *= yScale;
|
||||
|
||||
mtx[ 2] *= zScale;
|
||||
mtx[ 6] *= zScale;
|
||||
mtx[10] *= zScale;
|
||||
mtx[14] *= zScale;
|
||||
}
|
||||
|
||||
|
||||
void mtxRotateXMatrix(float* mtx, float rad)
|
||||
{
|
||||
// [ 1 0 0 0 ] [ 0 4 8 12 ]
|
||||
// [ 0 cos -sin 0 ] x [ 1 5 9 13 ]
|
||||
// [ 0 sin cos 0 ] [ 2 6 10 14 ]
|
||||
// [ 0 0 0 1 ] [ 3 7 11 15 ]
|
||||
|
||||
float cosrad = cosf(rad);
|
||||
float sinrad = sinf(rad);
|
||||
|
||||
float mtx01 = mtx[ 1];
|
||||
float mtx05 = mtx[ 5];
|
||||
float mtx09 = mtx[ 9];
|
||||
float mtx13 = mtx[13];
|
||||
|
||||
mtx[ 1] = cosrad*mtx01 - sinrad*mtx[ 2];
|
||||
mtx[ 2] = sinrad*mtx01 + cosrad*mtx[ 2];
|
||||
|
||||
mtx[ 5] = cosrad*mtx05 - sinrad*mtx[ 6];
|
||||
mtx[ 6] = sinrad*mtx05 + cosrad*mtx[ 6];
|
||||
|
||||
mtx[ 9] = cosrad*mtx09 - sinrad*mtx[10];
|
||||
mtx[10] = sinrad*mtx09 + cosrad*mtx[10];
|
||||
|
||||
mtx[13] = cosrad*mtx13 - sinrad*mtx[14];
|
||||
mtx[14] = sinrad*mtx13 + cosrad*mtx[14];
|
||||
}
|
||||
|
||||
|
||||
void mtxRotateYMatrix(float* mtx, float rad)
|
||||
{
|
||||
// [ cos 0 -sin 0 ] [ 0 4 8 12 ]
|
||||
// [ 0 1 0 0 ] x [ 1 5 9 13 ]
|
||||
// [ sin 0 cos 0 ] [ 2 6 10 14 ]
|
||||
// [ 0 0 0 1 ] [ 3 7 11 15 ]
|
||||
|
||||
float cosrad = cosf(rad);
|
||||
float sinrad = sinf(rad);
|
||||
|
||||
float mtx00 = mtx[ 0];
|
||||
float mtx04 = mtx[ 4];
|
||||
float mtx08 = mtx[ 8];
|
||||
float mtx12 = mtx[12];
|
||||
|
||||
mtx[ 0] = cosrad*mtx00 - sinrad*mtx[ 2];
|
||||
mtx[ 2] = sinrad*mtx00 + cosrad*mtx[ 2];
|
||||
|
||||
mtx[ 4] = cosrad*mtx04 - sinrad*mtx[ 6];
|
||||
mtx[ 6] = sinrad*mtx04 + cosrad*mtx[ 6];
|
||||
|
||||
mtx[ 8] = cosrad*mtx08 - sinrad*mtx[10];
|
||||
mtx[10] = sinrad*mtx08 + cosrad*mtx[10];
|
||||
|
||||
mtx[12] = cosrad*mtx12 - sinrad*mtx[14];
|
||||
mtx[14] = sinrad*mtx12 + cosrad*mtx[14];
|
||||
}
|
||||
|
||||
|
||||
void mtxRotateZMatrix(float* mtx, float rad)
|
||||
{
|
||||
// [ cos -sin 0 0 ] [ 0 4 8 12 ]
|
||||
// [ sin cos 0 0 ] x [ 1 5 9 13 ]
|
||||
// [ 0 0 1 0 ] [ 2 6 10 14 ]
|
||||
// [ 0 0 0 1 ] [ 3 7 11 15 ]
|
||||
|
||||
float cosrad = cosf(rad);
|
||||
float sinrad = sinf(rad);
|
||||
|
||||
float mtx00 = mtx[ 0];
|
||||
float mtx04 = mtx[ 4];
|
||||
float mtx08 = mtx[ 8];
|
||||
float mtx12 = mtx[12];
|
||||
|
||||
mtx[ 0] = cosrad*mtx00 - sinrad*mtx[ 1];
|
||||
mtx[ 1] = sinrad*mtx00 + cosrad*mtx[ 1];
|
||||
|
||||
mtx[ 4] = cosrad*mtx04 - sinrad*mtx[ 5];
|
||||
mtx[ 5] = sinrad*mtx04 + cosrad*mtx[ 5];
|
||||
|
||||
mtx[ 8] = cosrad*mtx08 - sinrad*mtx[ 9];
|
||||
mtx[ 9] = sinrad*mtx08 + cosrad*mtx[ 9];
|
||||
|
||||
mtx[12] = cosrad*mtx12 - sinrad*mtx[13];
|
||||
mtx[13] = sinrad*mtx12 + cosrad*mtx[13];
|
||||
}
|
||||
|
||||
void mtxRotateMatrix(float* mtx, float rad, float xAxis, float yAxis, float zAxis)
|
||||
{
|
||||
float rotMtx[16];
|
||||
|
||||
mtxLoadRotate(rotMtx, rad, xAxis, yAxis, zAxis);
|
||||
|
||||
mtxMultiply(mtx, rotMtx, mtx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void mtx3x3LoadIdentity(float* mtx)
|
||||
{
|
||||
mtx[0] = mtx[4] = mtx[8] = 1.0f;
|
||||
|
||||
mtx[1] = mtx[2] = mtx[3] =
|
||||
mtx[5] = mtx[6] = mtx[7] = 0.0f;
|
||||
|
||||
}
|
||||
|
||||
void mtx3x3FromTopLeftOf4x4(float* mtx, const float* src)
|
||||
{
|
||||
mtx[0] = src[0];
|
||||
mtx[1] = src[1];
|
||||
mtx[2] = src[2];
|
||||
mtx[3] = src[4];
|
||||
mtx[4] = src[5];
|
||||
mtx[5] = src[6];
|
||||
mtx[6] = src[8];
|
||||
mtx[7] = src[9];
|
||||
mtx[8] = src[10];
|
||||
}
|
||||
|
||||
void mtx3x3Transpose(float* mtx, const float* src)
|
||||
{
|
||||
float tmp;
|
||||
mtx[0] = src[0];
|
||||
mtx[4] = src[4];
|
||||
mtx[8] = src[8];
|
||||
|
||||
tmp = src[1];
|
||||
mtx[1] = src[3];
|
||||
mtx[3] = tmp;
|
||||
|
||||
tmp = src[2];
|
||||
mtx[2] = src[6];
|
||||
mtx[6] = tmp;
|
||||
|
||||
tmp = src[5];
|
||||
mtx[5] = src[7];
|
||||
mtx[7] = tmp;
|
||||
}
|
||||
|
||||
|
||||
void mtx3x3Invert(float* mtx, const float* src)
|
||||
{
|
||||
float cpy[9];
|
||||
float det =
|
||||
src[0] * (src[4]*src[8] - src[7]*src[5]) -
|
||||
src[1] * (src[3]*src[8] - src[6]*src[5]) +
|
||||
src[2] * (src[3]*src[7] - src[6]*src[4]);
|
||||
|
||||
if ( fabs( det ) < 0.0005 )
|
||||
{
|
||||
mtx3x3LoadIdentity(mtx);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(cpy, src, 9 * sizeof(float));
|
||||
|
||||
mtx[0] = cpy[4]*cpy[8] - cpy[5]*cpy[7] / det;
|
||||
mtx[1] = -(cpy[1]*cpy[8] - cpy[7]*cpy[2]) / det;
|
||||
mtx[2] = cpy[1]*cpy[5] - cpy[4]*cpy[2] / det;
|
||||
|
||||
mtx[3] = -(cpy[3]*cpy[8] - cpy[5]*cpy[6]) / det;
|
||||
mtx[4] = cpy[0]*cpy[8] - cpy[6]*cpy[2] / det;
|
||||
mtx[5] = -(cpy[0]*cpy[5] - cpy[3]*cpy[2]) / det;
|
||||
|
||||
mtx[6] = cpy[3]*cpy[7] - cpy[6]*cpy[4] / det;
|
||||
mtx[7] = -(cpy[0]*cpy[7] - cpy[6]*cpy[1]) / det;
|
||||
mtx[8] = cpy[0]*cpy[4] - cpy[1]*cpy[3] / det;
|
||||
}
|
||||
|
||||
void mtx3x3Multiply(float* mtx, const float* lhs, const float* rhs)
|
||||
{
|
||||
mtx[0] = lhs[0]*rhs[0] + lhs[3] * rhs[1] + lhs[6] * rhs[2];
|
||||
mtx[1] = lhs[1]*rhs[0] + lhs[4] * rhs[1] + lhs[7] * rhs[2];
|
||||
mtx[2] = lhs[2]*rhs[0] + lhs[5] * rhs[1] + lhs[8] * rhs[2];
|
||||
|
||||
mtx[3] = lhs[0]*rhs[3] + lhs[3] * rhs[4] + lhs[6] * rhs[5];
|
||||
mtx[4] = lhs[1]*rhs[3] + lhs[4] * rhs[4] + lhs[7] * rhs[5];
|
||||
mtx[5] = lhs[2]*rhs[3] + lhs[5] * rhs[4] + lhs[8] * rhs[5];
|
||||
|
||||
mtx[6] = lhs[0]*rhs[6] + lhs[3] * rhs[7] + lhs[6] * rhs[8];
|
||||
mtx[7] = lhs[1]*rhs[6] + lhs[4] * rhs[7] + lhs[7] * rhs[8];
|
||||
mtx[8] = lhs[2]*rhs[6] + lhs[5] * rhs[7] + lhs[8] * rhs[8];
|
||||
}
|
||||
|
158
src/video_util/matrixUtil.h
Normal file
158
src/video_util/matrixUtil.h
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
File: matrixUtil.h
|
||||
Abstract:
|
||||
Functions for performing matrix math.
|
||||
|
||||
Version: 1.7
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __MATRIX_UTIL_H__
|
||||
#define __MATRIX_UTIL_H__
|
||||
|
||||
// Matrix is a column major floating point array
|
||||
|
||||
// All matrices are 4x4 by unless the mtx3x3 prefix is specified in the function name
|
||||
|
||||
// [ 0 4 8 12 ]
|
||||
// [ 1 5 9 13 ]
|
||||
// [ 2 6 10 14 ]
|
||||
// [ 3 7 11 15 ]
|
||||
|
||||
// MTX = LeftHandSideMatrix * RightHandSideMatrix
|
||||
void mtxMultiply(float* ret, const float* lhs, const float* rhs);
|
||||
|
||||
// MTX = IdentityMatrix
|
||||
void mtxLoadIdentity(float* mtx);
|
||||
|
||||
// MTX = Transpos(SRC)
|
||||
void mtxTranspose(float* mtx, const float* src);
|
||||
|
||||
// MTX = src^-1
|
||||
void mtxInvert(float* mtx, const float* src);
|
||||
|
||||
// MTX = PerspectiveProjectionMatrix
|
||||
void mtxLoadPerspective(float* mtx, float fov, float aspect, float nearZ, float farZ);
|
||||
|
||||
// MTX = OrthographicProjectionMatrix
|
||||
void mtxLoadOrthographic(float* mtx,
|
||||
float left, float right,
|
||||
float bottom, float top,
|
||||
float nearZ, float farZ);
|
||||
|
||||
// MTX = ObliqueProjectionMatrix(src, clipPlane)
|
||||
void mtxModifyObliqueProjection(float* mtx, const float* src, const float* plane);
|
||||
|
||||
// MTX = TranlationMatrix
|
||||
void mtxLoadTranslate(float* mtx, float xTrans, float yTrans, float zTrans);
|
||||
|
||||
// MTX = ScaleMatrix
|
||||
void mtxLoadScale(float* mtx, float xScale, float yScale, float zScale);
|
||||
|
||||
// MTX = RotateXYZMatrix
|
||||
void mtxLoadRotate(float*mtx, float deg, float xAxis, float , float zAxis);
|
||||
|
||||
// MTX = RotateXMatrix
|
||||
void mtxLoadRotateX(float* mtx, float deg);
|
||||
|
||||
// MTX = RotateYMatrix
|
||||
void mtxLoadRotateY(float* mtx, float deg);
|
||||
|
||||
// MTX = RotateZMatrix
|
||||
void mtxLoadRotateZ(float* mtx, float deg);
|
||||
|
||||
// MTX = MTX * TranslationMatrix - Similar to glTranslate
|
||||
void mtxTranslateApply(float* mtx, float xTrans, float yTrans, float zTrans);
|
||||
|
||||
// MTX = MTX * ScaleMatrix - Similar to glScale
|
||||
void mtxScaleApply(float* mtx, float xScale, float yScale, float zScale);
|
||||
|
||||
// MTX = MTX * RotateXYZMatrix - Similar to glRotate
|
||||
void mtxRotateApply(float* mtx, float deg, float xAxis, float yAxis, float zAxis);
|
||||
|
||||
// MTX = MTX * RotateXMatrix
|
||||
void mtxRotateXApply(float* mtx, float rad);
|
||||
|
||||
// MTX = MTX * RotateYMatrix
|
||||
void mtxRotateYApply(float* mtx, float rad);
|
||||
|
||||
// MTX = MTX * RotateZMatrix
|
||||
void mtxRotateZApply(float* mtx, float rad);
|
||||
|
||||
// MTX = TranslationMatrix * MTX
|
||||
void mtxTranslateMatrix(float* mtx, float xTrans, float yTrans, float zTrans);
|
||||
|
||||
// MTX = ScaleMatrix * MTX
|
||||
void mtxScaleMatrix(float* mtx, float xScale, float yScale, float zScale);
|
||||
|
||||
// MTX = RotateXYZMatrix * MTX
|
||||
void mtxRotateMatrix(float* mtx, float rad, float xAxis, float yAxis, float zAxis);
|
||||
|
||||
// MTX = RotateXMatrix * MTX
|
||||
void mtxRotateXMatrix(float* mtx, float rad);
|
||||
|
||||
// MTX = RotateYMatrix * MTX
|
||||
void mtxRotateYMatrix(float* mtx, float rad);
|
||||
|
||||
// MTX = RotateZMatrix * MTX
|
||||
void mtxRotateZMatrix(float* mtx, float rad);
|
||||
|
||||
// 3x3 MTX = 3x3 IdendityMatrix
|
||||
void mtx3x3LoadIdentity(float* mtx);
|
||||
|
||||
|
||||
// 3x3 MTX = 3x3 LHS x 3x3 RHS
|
||||
void mtx3x3Multiply(float* mtx, const float* lhs, const float* rhs);
|
||||
|
||||
|
||||
// 3x3 MTX = TopLeft of MTX
|
||||
void mtx3x3FromTopLeftOf4x4(float* mtx, const float* src);
|
||||
|
||||
// 3x3 MTX = Transpose(3x3 SRC)
|
||||
void mtx3x3Transpose(float* mtx, const float* src);
|
||||
|
||||
// 3x3 MTX = 3x3 SRC^-1
|
||||
void mtx3x3Invert(float* mtx, const float* src);
|
||||
|
||||
#endif //__MATRIX_UTIL_H__
|
||||
|
422
src/video_util/modelUtil.c
Normal file
422
src/video_util/modelUtil.c
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
File: modelUtil.c
|
||||
Abstract:
|
||||
Functions for loading a model file for vertex arrays. The model file
|
||||
format used is a simple "binary blob" invented for the purpose of
|
||||
this sample code.
|
||||
|
||||
Version: 1.7
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#include "modelUtil.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct modelHeaderRec
|
||||
{
|
||||
char fileIdentifier[30];
|
||||
unsigned int majorVersion;
|
||||
unsigned int minorVersion;
|
||||
} modelHeader;
|
||||
|
||||
typedef struct modelTOCRec
|
||||
{
|
||||
unsigned int attribHeaderSize;
|
||||
unsigned int byteElementOffset;
|
||||
unsigned int bytePositionOffset;
|
||||
unsigned int byteTexcoordOffset;
|
||||
unsigned int byteNormalOffset;
|
||||
} modelTOC;
|
||||
|
||||
typedef struct modelAttribRec
|
||||
{
|
||||
unsigned int byteSize;
|
||||
GLenum datatype;
|
||||
GLenum primType; //If index data
|
||||
unsigned int sizePerElement;
|
||||
unsigned int numElements;
|
||||
} modelAttrib;
|
||||
|
||||
demoModel* mdlLoadModel(const char* filepathname)
|
||||
{
|
||||
if(NULL == filepathname)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
demoModel* model = (demoModel*) calloc(sizeof(demoModel), 1);
|
||||
|
||||
if(NULL == model)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
size_t sizeRead;
|
||||
int error;
|
||||
FILE* curFile = fopen(filepathname, "r");
|
||||
|
||||
if(!curFile)
|
||||
{
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
modelHeader header;
|
||||
|
||||
sizeRead = fread(&header, 1, sizeof(modelHeader), curFile);
|
||||
|
||||
if(sizeRead != sizeof(modelHeader))
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(strncmp(header.fileIdentifier, "AppleOpenGLDemoModelWWDC2010", sizeof(header.fileIdentifier)))
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(header.majorVersion != 0 && header.minorVersion != 1)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
modelTOC toc;
|
||||
|
||||
sizeRead = fread(&toc, 1, sizeof(modelTOC), curFile);
|
||||
|
||||
if(sizeRead != sizeof(modelTOC))
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(toc.attribHeaderSize > sizeof(modelAttrib))
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
modelAttrib attrib;
|
||||
|
||||
error = fseek(curFile, toc.byteElementOffset, SEEK_SET);
|
||||
|
||||
if(error < 0)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sizeRead = fread(&attrib, 1, toc.attribHeaderSize, curFile);
|
||||
|
||||
if(sizeRead != toc.attribHeaderSize)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
model->elementArraySize = attrib.byteSize;
|
||||
model->elementType = attrib.datatype;
|
||||
model->numElements = attrib.numElements;
|
||||
|
||||
// OpenGL ES cannot use UNSIGNED_INT elements
|
||||
// So if the model has UI element...
|
||||
if(GL_UNSIGNED_INT == model->elementType)
|
||||
{
|
||||
//...Load the UI elements and convert to UNSIGNED_SHORT
|
||||
|
||||
GLubyte* uiElements = (GLubyte*) malloc(model->elementArraySize);
|
||||
size_t ushortElementArraySize = model->numElements * sizeof(GLushort);
|
||||
model->elements = (GLubyte*)malloc(ushortElementArraySize);
|
||||
|
||||
sizeRead = fread(uiElements, 1, model->elementArraySize, curFile);
|
||||
|
||||
if(sizeRead != model->elementArraySize)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GLuint elemNum = 0;
|
||||
for(elemNum = 0; elemNum < model->numElements; elemNum++)
|
||||
{
|
||||
//We can't handle this model if an element is out of the UNSIGNED_INT range
|
||||
if(((GLuint*)uiElements)[elemNum] >= 0xFFFF)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
((GLushort*)model->elements)[elemNum] = ((GLuint*)uiElements)[elemNum];
|
||||
}
|
||||
|
||||
free(uiElements);
|
||||
|
||||
|
||||
model->elementType = GL_UNSIGNED_SHORT;
|
||||
model->elementArraySize = model->numElements * sizeof(GLushort);
|
||||
}
|
||||
else
|
||||
{
|
||||
model->elements = (GLubyte*)malloc(model->elementArraySize);
|
||||
|
||||
sizeRead = fread(model->elements, 1, model->elementArraySize, curFile);
|
||||
|
||||
if(sizeRead != model->elementArraySize)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
fseek(curFile, toc.bytePositionOffset, SEEK_SET);
|
||||
|
||||
sizeRead = fread(&attrib, 1, toc.attribHeaderSize, curFile);
|
||||
|
||||
if(sizeRead != toc.attribHeaderSize)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
model->positionArraySize = attrib.byteSize;
|
||||
model->positionType = attrib.datatype;
|
||||
model->positionSize = attrib.sizePerElement;
|
||||
model->numVertices = attrib.numElements;
|
||||
model->positions = (GLubyte*) malloc(model->positionArraySize);
|
||||
|
||||
sizeRead = fread(model->positions, 1, model->positionArraySize, curFile);
|
||||
|
||||
if(sizeRead != model->positionArraySize)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
error = fseek(curFile, toc.byteTexcoordOffset, SEEK_SET);
|
||||
|
||||
if(error < 0)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sizeRead = fread(&attrib, 1, toc.attribHeaderSize, curFile);
|
||||
|
||||
if(sizeRead != toc.attribHeaderSize)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
model->texcoordArraySize = attrib.byteSize;
|
||||
model->texcoordType = attrib.datatype;
|
||||
model->texcoordSize = attrib.sizePerElement;
|
||||
|
||||
//Must have the same number of texcoords as positions
|
||||
if(model->numVertices != attrib.numElements)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
model->texcoords = (GLubyte*) malloc(model->texcoordArraySize);
|
||||
|
||||
sizeRead = fread(model->texcoords, 1, model->texcoordArraySize, curFile);
|
||||
|
||||
if(sizeRead != model->texcoordArraySize)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
error = fseek(curFile, toc.byteNormalOffset, SEEK_SET);
|
||||
|
||||
if(error < 0)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sizeRead = fread(&attrib, 1, toc.attribHeaderSize, curFile);
|
||||
|
||||
if(sizeRead != toc.attribHeaderSize)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
model->normalArraySize = attrib.byteSize;
|
||||
model->normalType = attrib.datatype;
|
||||
model->normalSize = attrib.sizePerElement;
|
||||
|
||||
//Must have the same number of normals as positions
|
||||
if(model->numVertices != attrib.numElements)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
model->normals = (GLubyte*) malloc(model->normalArraySize );
|
||||
|
||||
sizeRead = fread(model->normals, 1, model->normalArraySize , curFile);
|
||||
|
||||
if(sizeRead != model->normalArraySize)
|
||||
{
|
||||
fclose(curFile);
|
||||
mdlDestroyModel(model);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose(curFile);
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
demoModel* mdlLoadQuadModel()
|
||||
{
|
||||
GLfloat posArray[] = {
|
||||
-200.0f, 0.0f, -200.0f,
|
||||
200.0f, 0.0f, -200.0f,
|
||||
200.0f, 0.0f, 200.0f,
|
||||
-200.0f, 0.0f, 200.0f
|
||||
};
|
||||
|
||||
GLfloat texcoordArray[] = {
|
||||
0.0f, 1.0f,
|
||||
1.0f, 1.0f,
|
||||
1.0f, 0.0f,
|
||||
0.0f, 0.0f
|
||||
};
|
||||
|
||||
GLfloat normalArray[] = {
|
||||
0.0f, 0.0f, 1.0,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
0.0f, 0.0f, 1.0f,
|
||||
};
|
||||
|
||||
GLushort elementArray[] =
|
||||
{
|
||||
0, 2, 1,
|
||||
0, 3, 2
|
||||
};
|
||||
|
||||
demoModel* model = (demoModel*) calloc(sizeof(demoModel), 1);
|
||||
|
||||
if(NULL == model)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
model->positionType = GL_FLOAT;
|
||||
model->positionSize = 3;
|
||||
model->positionArraySize = sizeof(posArray);
|
||||
model->positions = (GLubyte*)malloc(model->positionArraySize);
|
||||
memcpy(model->positions, posArray, model->positionArraySize);
|
||||
|
||||
model->texcoordType = GL_FLOAT;
|
||||
model->texcoordSize = 2;
|
||||
model->texcoordArraySize = sizeof(texcoordArray);
|
||||
model->texcoords = (GLubyte*)malloc(model->texcoordArraySize);
|
||||
memcpy(model->texcoords, texcoordArray, model->texcoordArraySize );
|
||||
|
||||
model->normalType = GL_FLOAT;
|
||||
model->normalSize = 3;
|
||||
model->normalArraySize = sizeof(normalArray);
|
||||
model->normals = (GLubyte*)malloc(model->normalArraySize);
|
||||
memcpy(model->normals, normalArray, model->normalArraySize);
|
||||
|
||||
model->elementArraySize = sizeof(elementArray);
|
||||
model->elements = (GLubyte*)malloc(model->elementArraySize);
|
||||
memcpy(model->elements, elementArray, model->elementArraySize);
|
||||
|
||||
model->primType = GL_TRIANGLES;
|
||||
|
||||
|
||||
model->numElements = sizeof(elementArray) / sizeof(GLushort);
|
||||
model->elementType = GL_UNSIGNED_SHORT;
|
||||
model->numVertices = model->positionArraySize / (model->positionSize * sizeof(GLfloat));
|
||||
|
||||
return model;
|
||||
}
|
||||
|
||||
void mdlDestroyModel(demoModel* model)
|
||||
{
|
||||
if(NULL == model)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
free(model->elements);
|
||||
free(model->positions);
|
||||
free(model->normals);
|
||||
free(model->texcoords);
|
||||
|
||||
free(model);
|
||||
}
|
||||
|
91
src/video_util/modelUtil.h
Normal file
91
src/video_util/modelUtil.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
File: modelUtil.h
|
||||
Abstract:
|
||||
Functions for loading a model file for vertex arrays. The model file
|
||||
format used is a simple "binary blob" invented for the purpose of
|
||||
this sample code.
|
||||
|
||||
Version: 1.7
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __MODEL_UTIL_H__
|
||||
#define __MODEL_UTIL_H__
|
||||
|
||||
#include "glUtil.h"
|
||||
|
||||
typedef struct demoModelRec
|
||||
{
|
||||
GLuint numVertices;
|
||||
|
||||
GLubyte *positions;
|
||||
GLenum positionType;
|
||||
GLuint positionSize;
|
||||
GLsizei positionArraySize;
|
||||
|
||||
GLubyte *texcoords;
|
||||
GLenum texcoordType;
|
||||
GLuint texcoordSize;
|
||||
GLsizei texcoordArraySize;
|
||||
|
||||
GLubyte *normals;
|
||||
GLenum normalType;
|
||||
GLuint normalSize;
|
||||
GLsizei normalArraySize;
|
||||
|
||||
GLubyte *elements;
|
||||
GLenum elementType;
|
||||
GLuint numElements;
|
||||
GLsizei elementArraySize;
|
||||
|
||||
GLenum primType;
|
||||
|
||||
} demoModel;
|
||||
|
||||
demoModel* mdlLoadModel(const char* filepathname);
|
||||
|
||||
demoModel* mdlLoadQuadModel();
|
||||
|
||||
void mdlDestroyModel(demoModel* model);
|
||||
|
||||
#endif //__MODEL_UTIL_H__
|
105
src/video_util/sourceUtil.c
Normal file
105
src/video_util/sourceUtil.c
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
File: sourceUtil.c
|
||||
Abstract:
|
||||
Functions for loading source files for shaders.
|
||||
|
||||
Version: 1.7
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#include "sourceUtil.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
demoSource* srcLoadSource(const char* filepathname)
|
||||
{
|
||||
demoSource* source = (demoSource*) calloc(sizeof(demoSource), 1);
|
||||
|
||||
// Check the file name suffix to determine what type of shader this is
|
||||
const char* suffixBegin = filepathname + strlen(filepathname) - 4;
|
||||
|
||||
if(0 == strncmp(suffixBegin, ".fsh", 4))
|
||||
{
|
||||
source->shaderType = GL_FRAGMENT_SHADER;
|
||||
}
|
||||
else if(0 == strncmp(suffixBegin, ".vsh", 4))
|
||||
{
|
||||
source->shaderType = GL_VERTEX_SHADER;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unknown suffix
|
||||
source->shaderType = 0;
|
||||
}
|
||||
|
||||
FILE* curFile = fopen(filepathname, "r");
|
||||
|
||||
// Get the size of the source
|
||||
fseek(curFile, 0, SEEK_END);
|
||||
GLsizei fileSize = ftell (curFile);
|
||||
|
||||
// Add 1 to the file size to include the null terminator for the string
|
||||
source->byteSize = fileSize + 1;
|
||||
|
||||
// Alloc memory for the string
|
||||
source->string = malloc(source->byteSize);
|
||||
|
||||
// Read entire file into the string from beginning of the file
|
||||
fseek(curFile, 0, SEEK_SET);
|
||||
fread(source->string, 1, fileSize, curFile);
|
||||
|
||||
fclose(curFile);
|
||||
|
||||
// Insert null terminator
|
||||
source->string[fileSize] = 0;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
void srcDestroySource(demoSource* source)
|
||||
{
|
||||
free(source->string);
|
||||
free(source);
|
||||
}
|
69
src/video_util/sourceUtil.h
Normal file
69
src/video_util/sourceUtil.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
File: sourceUtil.h
|
||||
Abstract:
|
||||
Functions for loading source files for shaders.
|
||||
|
||||
Version: 1.7
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __SOURCE_UTIL_H__
|
||||
#define __SOURCE_UTIL_H__
|
||||
|
||||
#include "glUtil.h"
|
||||
|
||||
typedef struct demoSourceRec
|
||||
{
|
||||
GLchar* string;
|
||||
|
||||
GLsizei byteSize;
|
||||
|
||||
GLenum shaderType; // Vertex or Fragment
|
||||
|
||||
} demoSource;
|
||||
|
||||
demoSource* srcLoadSource(const char* filepathname);
|
||||
|
||||
void srcDestroySource(demoSource* source);
|
||||
|
||||
#endif // __SOURCE_UTIL_H__
|
157
src/video_util/vectorUtil.c
Executable file
157
src/video_util/vectorUtil.c
Executable file
@ -0,0 +1,157 @@
|
||||
/*
|
||||
File: vectorUtil.c
|
||||
Abstract:
|
||||
Functions for performing vector math.
|
||||
|
||||
Version: 1.7
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#include "vectorUtil.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <memory.h>
|
||||
|
||||
void vec4Add(float* vec, const float* lhs, const float* rhs)
|
||||
{
|
||||
vec[0] = lhs[0] + rhs[0];
|
||||
vec[1] = lhs[1] + rhs[1];
|
||||
vec[2] = lhs[2] + rhs[2];
|
||||
vec[3] = lhs[3] + rhs[3];
|
||||
}
|
||||
|
||||
void vec4Subtract(float* vec, const float* lhs, const float* rhs)
|
||||
{
|
||||
vec[0] = lhs[0] - rhs[0];
|
||||
vec[1] = lhs[1] - rhs[1];
|
||||
vec[2] = lhs[2] - rhs[2];
|
||||
vec[3] = lhs[3] - rhs[3];
|
||||
}
|
||||
|
||||
|
||||
void vec4Multiply(float* vec, const float* lhs, const float* rhs)
|
||||
{
|
||||
vec[0] = lhs[0] * rhs[0];
|
||||
vec[1] = lhs[1] * rhs[1];
|
||||
vec[2] = lhs[2] * rhs[2];
|
||||
vec[3] = lhs[3] * rhs[3];
|
||||
}
|
||||
|
||||
void vec4Divide(float* vec, const float* lhs, const float* rhs)
|
||||
{
|
||||
vec[0] = lhs[0] / rhs[0];
|
||||
vec[1] = lhs[1] / rhs[1];
|
||||
vec[2] = lhs[2] / rhs[2];
|
||||
vec[3] = lhs[3] / rhs[3];
|
||||
}
|
||||
|
||||
|
||||
void vec3Add(float* vec, const float* lhs, const float* rhs)
|
||||
{
|
||||
vec[0] = lhs[0] + rhs[0];
|
||||
vec[1] = lhs[1] + rhs[1];
|
||||
vec[2] = lhs[2] + rhs[2];
|
||||
}
|
||||
|
||||
void vec3Subtract(float* vec, const float* lhs, const float* rhs)
|
||||
{
|
||||
vec[0] = lhs[0] - rhs[0];
|
||||
vec[1] = lhs[1] - rhs[1];
|
||||
vec[2] = lhs[2] - rhs[2];
|
||||
}
|
||||
|
||||
|
||||
void vec3Multiply(float* vec, const float* lhs, const float* rhs)
|
||||
{
|
||||
vec[0] = lhs[0] * rhs[0];
|
||||
vec[1] = lhs[1] * rhs[1];
|
||||
vec[2] = lhs[2] * rhs[2];
|
||||
}
|
||||
|
||||
void vec3Divide(float* vec, const float* lhs, const float* rhs)
|
||||
{
|
||||
vec[0] = lhs[0] / rhs[0];
|
||||
vec[1] = lhs[1] / rhs[1];
|
||||
vec[2] = lhs[2] / rhs[2];
|
||||
}
|
||||
|
||||
float vec3DotProduct(const float* lhs, const float* rhs)
|
||||
{
|
||||
return lhs[0]*rhs[0] + lhs[1]*rhs[1] + lhs[2]*rhs[2];
|
||||
}
|
||||
|
||||
float vec4DotProduct(const float* lhs, const float* rhs)
|
||||
{
|
||||
return lhs[0]*rhs[0] + lhs[1]*rhs[1] + lhs[2]*rhs[2] + lhs[3]*rhs[3];
|
||||
}
|
||||
|
||||
void vec3CrossProduct(float* vec, const float* lhs, const float* rhs)
|
||||
{
|
||||
vec[0] = lhs[1] * rhs[2] - lhs[2] * rhs[1];
|
||||
vec[1] = lhs[2] * rhs[0] - lhs[0] * rhs[2];
|
||||
vec[2] = lhs[0] * rhs[1] - lhs[1] * rhs[0];
|
||||
}
|
||||
|
||||
float vec3Length(const float* vec)
|
||||
{
|
||||
return sqrtf(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
|
||||
}
|
||||
|
||||
float vec3Distance(const float* pointA, const float* pointB)
|
||||
{
|
||||
float diffx = pointA[0]-pointB[0];
|
||||
float diffy = pointA[1]-pointB[1];
|
||||
float diffz = pointA[2]-pointB[2];
|
||||
return sqrtf(diffx*diffx + diffy*diffy + diffz*diffz);
|
||||
}
|
||||
|
||||
void vec3Normalize(float* vec, const float* src)
|
||||
{
|
||||
float length = vec3Length(src);
|
||||
|
||||
vec[0] = src[0]/length;
|
||||
vec[1] = src[1]/length;
|
||||
vec[2] = src[2]/length;
|
||||
}
|
||||
|
||||
|
100
src/video_util/vectorUtil.h
Executable file
100
src/video_util/vectorUtil.h
Executable file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
File: vectorUtil.h
|
||||
Abstract:
|
||||
Functions for performing vector math.
|
||||
|
||||
Version: 1.7
|
||||
|
||||
Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
|
||||
Inc. ("Apple") in consideration of your agreement to the following
|
||||
terms, and your use, installation, modification or redistribution of
|
||||
this Apple software constitutes acceptance of these terms. If you do
|
||||
not agree with these terms, please do not use, install, modify or
|
||||
redistribute this Apple software.
|
||||
|
||||
In consideration of your agreement to abide by the following terms, and
|
||||
subject to these terms, Apple grants you a personal, non-exclusive
|
||||
license, under Apple's copyrights in this original Apple software (the
|
||||
"Apple Software"), to use, reproduce, modify and redistribute the Apple
|
||||
Software, with or without modifications, in source and/or binary forms;
|
||||
provided that if you redistribute the Apple Software in its entirety and
|
||||
without modifications, you must retain this notice and the following
|
||||
text and disclaimers in all such redistributions of the Apple Software.
|
||||
Neither the name, trademarks, service marks or logos of Apple Inc. may
|
||||
be used to endorse or promote products derived from the Apple Software
|
||||
without specific prior written permission from Apple. Except as
|
||||
expressly stated in this notice, no other rights or licenses, express or
|
||||
implied, are granted by Apple herein, including but not limited to any
|
||||
patent rights that may be infringed by your derivative works or by other
|
||||
works in which the Apple Software may be incorporated.
|
||||
|
||||
The Apple Software is provided by Apple on an "AS IS" basis. APPLE
|
||||
MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
|
||||
THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND
|
||||
OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
|
||||
|
||||
IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL
|
||||
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION,
|
||||
MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
|
||||
AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE),
|
||||
STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
Copyright (C) 2013 Apple Inc. All Rights Reserved.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __VECTOR_UTIL_H__
|
||||
#define __VECTOR_UTIL_H__
|
||||
|
||||
// A Vector is floating point array with either 3 or 4 components
|
||||
// functions with the vec4 prefix require 4 elements in the array
|
||||
// functions with vec3 prefix require only 3 elements in the array
|
||||
|
||||
// Subtracts one 4D vector to another
|
||||
void vec4Add(float* vec, const float* lhs, const float* rhs);
|
||||
|
||||
// Subtracts one 4D vector from another
|
||||
void vec4Subtract(float* vec, const float* lhs, const float* rhs);
|
||||
|
||||
// Multiplys one 4D vector by another
|
||||
void vec4Multiply(float* vec, const float* lhs, const float* rhs);
|
||||
|
||||
// Divides one 4D vector by another
|
||||
void vec4Divide(float* vec, const float* lhs, const float* rhs);
|
||||
|
||||
// Subtracts one 4D vector to another
|
||||
void vec3Add(float* vec, const float* lhs, const float* rhs);
|
||||
|
||||
// Subtracts one 4D vector from another
|
||||
void vec3Subtract(float* vec, const float* lhs, const float* rhs);
|
||||
|
||||
// Multiplys one 4D vector by another
|
||||
void vec3Multiply(float* vec, const float* lhs, const float* rhs);
|
||||
|
||||
// Divides one 4D vector by another
|
||||
void vec3Divide(float* vec, const float* lhs, const float* rhs);
|
||||
|
||||
// Calculates the Cross Product of a 3D vector
|
||||
void vec3CrossProduct(float* vec, const float* lhs, const float* rhs);
|
||||
|
||||
// Normalizes a 3D vector
|
||||
void vec3Normalize(float* vec, const float* src);
|
||||
|
||||
// Returns the Dot Product of 2 3D vectors
|
||||
float vec3DotProduct(const float* lhs, const float* rhs);
|
||||
|
||||
// Returns the Dot Product of 2 4D vectors
|
||||
float vec4DotProduct(const float* lhs, const float* rhs);
|
||||
|
||||
// Returns the length of a 3D vector
|
||||
// (i.e the distance of a point from the origin)
|
||||
float vec3Length(const float* vec);
|
||||
|
||||
// Returns the distance between two 3D points
|
||||
float vec3Distance(const float* pointA, const float* pointB);
|
||||
|
||||
#endif //__VECTOR_UTIL_H__
|
Loading…
x
Reference in New Issue
Block a user