├── .gitignore ├── .gitmodules ├── .vscode ├── launch.json └── settings.json ├── Android ├── .gitignore ├── .idea │ ├── encodings.xml │ ├── gradle.xml │ ├── misc.xml │ ├── modules.xml │ └── vcs.xml ├── Readme.md ├── app │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── home │ │ │ └── Swift_OpenGL_Example │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── home │ │ │ │ └── Swift_OpenGL_Example │ │ │ │ ├── GLView.java │ │ │ │ ├── MainActivity.java │ │ │ │ └── SwiftApp.java │ │ └── res │ │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ │ ├── drawable │ │ │ └── ic_launcher_background.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── colors.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── home │ │ └── Swift_OpenGL_Example │ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── local.properties └── settings.gradle ├── Default-568h@2x.png ├── LICENSE ├── Package.swift ├── README.md ├── Sources └── app │ ├── App.swift │ ├── Cube.swift │ ├── Geometry.swift │ ├── Scene.swift │ ├── Shader.swift │ ├── String_extention.swift │ ├── main.swift │ └── main_android.swift ├── opengl_example.xcodeproj ├── AppBase_Info.plist ├── AppBase_Info_ios.plist ├── Info_ios.plist ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ ├── app.xcscheme │ └── xcschememanagement.plist ├── screen1.png ├── screen2.png └── screen3.png /.gitignore: -------------------------------------------------------------------------------- 1 | .build 2 | build.sh 3 | **.gradle 4 | **.externalNativeBuild 5 | **/build 6 | **.idea 7 | **.swiftpm 8 | **.cxx 9 | **/xcuserdata** 10 | **/xcuserdata** 11 | Package.resolved 12 | Android/app/src/main/jniLibs 13 | Android/app/swiftpm-build/* 14 | swiftpm-build 15 | .DS_Store 16 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "swift-android-toolchain"] 2 | path = swift-android-toolchain 3 | url = git@github.com:sakrist/swift-android-toolchain.git 4 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "type": "lldb", 5 | "request": "launch", 6 | "sourceLanguages": [ 7 | "swift" 8 | ], 9 | "name": "Debug app", 10 | "program": "${workspaceFolder:Swift_OpenGL_Example}/.build/debug/app", 11 | "args": [], 12 | "cwd": "${workspaceFolder:Swift_OpenGL_Example}", 13 | "preLaunchTask": "swift: Build Debug app" 14 | }, 15 | { 16 | "type": "lldb", 17 | "request": "launch", 18 | "sourceLanguages": [ 19 | "swift" 20 | ], 21 | "name": "Release app", 22 | "program": "${workspaceFolder:Swift_OpenGL_Example}/.build/release/app", 23 | "args": [], 24 | "cwd": "${workspaceFolder:Swift_OpenGL_Example}", 25 | "preLaunchTask": "swift: Build Release app" 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "sstream": "cpp" 4 | }, 5 | "lldb.library": "/Applications/Xcode.app/Contents/SharedFrameworks/LLDB.framework/Versions/A/LLDB", 6 | "lldb.launch.expressions": "native" 7 | } -------------------------------------------------------------------------------- /Android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | /.idea/codeStyles/Project.xml 11 | .DS_Store 12 | /build 13 | /.build 14 | /captures 15 | .externalNativeBuild 16 | -------------------------------------------------------------------------------- /Android/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Android/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 19 | 20 | -------------------------------------------------------------------------------- /Android/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | -------------------------------------------------------------------------------- /Android/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Android/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Android/Readme.md: -------------------------------------------------------------------------------- 1 | # swift-everywhere-samples 2 | 3 | ## Requirements 4 | 5 | - macOS 12.x 6 | - Xcode 14.x+ 7 | - Android Studio 8 | - Android NDK 25.2.9519653 9 | 10 | read instructions in swift-android-toolchain submodule -------------------------------------------------------------------------------- /Android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'com.google.protobuf' 4 | 5 | android { 6 | ndkVersion "25.1.8937393" 7 | compileSdk 28 8 | defaultConfig { 9 | applicationId "com.home.Swift_OpenGL_Example" 10 | minSdkVersion 24 11 | targetSdkVersion 28 12 | versionCode 1 13 | versionName "1.0" 14 | testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' 15 | /* 16 | ndk { 17 | abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64' 18 | } 19 | */ 20 | } 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 25 | } 26 | debug { 27 | // The doNotStrip option is not properly scoped to the "debug" build type 28 | // See https://issuetracker.google.com/issues/155215248. 29 | packagingOptions { 30 | doNotStrip '**/*.so' 31 | } 32 | debuggable true 33 | jniDebuggable true 34 | } 35 | } 36 | splits { 37 | abi { 38 | reset() 39 | enable true 40 | universalApk false 41 | include "arm64-v8a" 42 | } 43 | } 44 | compileOptions { 45 | sourceCompatibility 1.8 46 | targetCompatibility 1.8 47 | } 48 | buildToolsVersion '30.0.3' 49 | namespace 'com.home.Swift_OpenGL_Example' 50 | packagingOptions { 51 | jniLibs { 52 | useLegacyPackaging false 53 | } 54 | } 55 | } 56 | 57 | dependencies { 58 | implementation fileTree(dir: 'libs', include: ['*.jar']) 59 | implementation 'androidx.appcompat:appcompat:1.0.0' 60 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 61 | testImplementation 'junit:junit:4.13.1' 62 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 63 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0' 64 | 65 | //protobuf(files("$rootDir/../Models")) 66 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 67 | implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0' 68 | } 69 | 70 | 71 | 72 | task buildSwiftArm64(type: Exec) { 73 | commandLine 'sh', '-c', getSwiftBuildCommand('arm64-v8a') 74 | } 75 | 76 | task buildSwiftIntel64(type: Exec) { 77 | commandLine 'sh', '-c', getSwiftBuildCommand('x86_64') 78 | } 79 | 80 | task cleanSwift(type: Exec) { 81 | commandLine 'sh', '-c', "rm -rf swiftpm-build" 82 | } 83 | 84 | preBuild.dependsOn buildSwiftArm64 85 | preBuild.dependsOn buildSwiftIntel64 86 | 87 | clean.dependsOn cleanSwift 88 | 89 | def getSwiftBuildCommand(abi) { 90 | def buildScript = "../../swift-android-toolchain/swiftpm.sh" 91 | return "ANDROID_ABI=$abi BUILD_TYPE=debug LIBRARY_OUTPUT_DIRECTORY='${projectDir}/src/main/jniLibs/${abi}' $buildScript" 92 | } 93 | 94 | repositories { 95 | mavenCentral() 96 | } 97 | -------------------------------------------------------------------------------- /Android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /Android/app/src/androidTest/java/com/home/Swift_OpenGL_Example/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.home.helloNDK; 2 | 3 | import android.content.Context; 4 | import androidx.test.platform.app.InstrumentationRegistry; 5 | import androidx.test.ext.junit.runners.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() { 21 | // Context of the app under test. 22 | // Context appContext = InstrumentationRegistry.getTargetContext(); 23 | // assertEquals("com.home.hello_ndk", appContext.getPackageName()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /Android/app/src/main/java/com/home/Swift_OpenGL_Example/GLView.java: -------------------------------------------------------------------------------- 1 | package com.home.Swift_OpenGL_Example; 2 | 3 | 4 | /* 5 | * Copyright (C) 2008 The Android Open Source Project 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | // Copy of GL2JNIView from gl2jni. 21 | 22 | import android.content.Context; 23 | import android.graphics.PixelFormat; 24 | import android.opengl.GLSurfaceView; 25 | import android.util.AttributeSet; 26 | import android.util.Log; 27 | import android.view.KeyEvent; 28 | import android.view.MotionEvent; 29 | import javax.microedition.khronos.egl.EGL10; 30 | import javax.microedition.khronos.egl.EGLConfig; 31 | import javax.microedition.khronos.egl.EGLContext; 32 | import javax.microedition.khronos.egl.EGLDisplay; 33 | import javax.microedition.khronos.opengles.GL10; 34 | 35 | class GLView extends GLSurfaceView { 36 | private static String TAG = "GLView"; 37 | private static final boolean DEBUG = false; 38 | 39 | public GLView(Context context) { 40 | super(context); 41 | init(false, 24, 0); 42 | } 43 | 44 | public GLView(Context context, boolean translucent, int depth, int stencil) { 45 | super(context); 46 | init(translucent, depth, stencil); 47 | } 48 | 49 | private void init(boolean translucent, int depth, int stencil) { 50 | 51 | /* By default, GLSurfaceView() creates a RGB_565 opaque surface. 52 | * If we want a translucent one, we should change the surface's 53 | * format here, using PixelFormat.TRANSLUCENT for GL Surfaces 54 | * is interpreted as any 32-bit surface with alpha by SurfaceFlinger. 55 | */ 56 | if (translucent) { 57 | this.getHolder().setFormat(PixelFormat.TRANSLUCENT); 58 | } 59 | 60 | /* Setup the context factory for 2.0 rendering. 61 | * See ContextFactory class definition below 62 | */ 63 | setEGLContextFactory(new ContextFactory()); 64 | 65 | /* We need to choose an EGLConfig that matches the format of 66 | * our surface exactly. This is going to be done in our 67 | * custom config chooser. See ConfigChooser class definition 68 | * below. 69 | */ 70 | setEGLConfigChooser( translucent ? 71 | new ConfigChooser(8, 8, 8, 8, depth, stencil) : 72 | new ConfigChooser(5, 6, 5, 0, depth, stencil) ); 73 | 74 | } 75 | 76 | private static class ContextFactory implements GLSurfaceView.EGLContextFactory { 77 | private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; 78 | public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { 79 | Log.w(TAG, "creating OpenGL ES 3.0 context"); 80 | checkEglError("Before eglCreateContext", egl); 81 | int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE }; 82 | EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); 83 | checkEglError("After eglCreateContext", egl); 84 | return context; 85 | } 86 | 87 | public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) { 88 | egl.eglDestroyContext(display, context); 89 | } 90 | } 91 | 92 | private static void checkEglError(String prompt, EGL10 egl) { 93 | int error; 94 | while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) { 95 | Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error)); 96 | } 97 | } 98 | 99 | private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser { 100 | 101 | public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) { 102 | mRedSize = r; 103 | mGreenSize = g; 104 | mBlueSize = b; 105 | mAlphaSize = a; 106 | mDepthSize = depth; 107 | mStencilSize = stencil; 108 | } 109 | 110 | /* This EGL config specification is used to specify 2.0 rendering. 111 | * We use a minimum size of 4 bits for red/green/blue, but will 112 | * perform actual matching in chooseConfig() below. 113 | */ 114 | private static int EGL_OPENGL_ES2_BIT = 4; 115 | private static int[] s_configAttribs2 = 116 | { 117 | EGL10.EGL_RED_SIZE, 4, 118 | EGL10.EGL_GREEN_SIZE, 4, 119 | EGL10.EGL_BLUE_SIZE, 4, 120 | EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 121 | EGL10.EGL_NONE 122 | }; 123 | 124 | public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { 125 | 126 | /* Get the number of minimally matching EGL configurations 127 | */ 128 | int[] num_config = new int[1]; 129 | egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); 130 | 131 | int numConfigs = num_config[0]; 132 | 133 | if (numConfigs <= 0) { 134 | throw new IllegalArgumentException("No configs match configSpec"); 135 | } 136 | 137 | /* Allocate then read the array of minimally matching EGL configs 138 | */ 139 | EGLConfig[] configs = new EGLConfig[numConfigs]; 140 | egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); 141 | 142 | if (DEBUG) { 143 | printConfigs(egl, display, configs); 144 | } 145 | /* Now return the "best" one 146 | */ 147 | return chooseConfig(egl, display, configs); 148 | } 149 | 150 | public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, 151 | EGLConfig[] configs) { 152 | for(EGLConfig config : configs) { 153 | int d = findConfigAttrib(egl, display, config, 154 | EGL10.EGL_DEPTH_SIZE, 0); 155 | int s = findConfigAttrib(egl, display, config, 156 | EGL10.EGL_STENCIL_SIZE, 0); 157 | 158 | // We need at least mDepthSize and mStencilSize bits 159 | if (d < mDepthSize || s < mStencilSize) 160 | continue; 161 | 162 | // We want an *exact* match for red/green/blue/alpha 163 | int r = findConfigAttrib(egl, display, config, 164 | EGL10.EGL_RED_SIZE, 0); 165 | int g = findConfigAttrib(egl, display, config, 166 | EGL10.EGL_GREEN_SIZE, 0); 167 | int b = findConfigAttrib(egl, display, config, 168 | EGL10.EGL_BLUE_SIZE, 0); 169 | int a = findConfigAttrib(egl, display, config, 170 | EGL10.EGL_ALPHA_SIZE, 0); 171 | 172 | if (r == mRedSize && g == mGreenSize && b == mBlueSize && a == mAlphaSize) 173 | return config; 174 | } 175 | return null; 176 | } 177 | 178 | private int findConfigAttrib(EGL10 egl, EGLDisplay display, 179 | EGLConfig config, int attribute, int defaultValue) { 180 | 181 | if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { 182 | return mValue[0]; 183 | } 184 | return defaultValue; 185 | } 186 | 187 | private void printConfigs(EGL10 egl, EGLDisplay display, 188 | EGLConfig[] configs) { 189 | int numConfigs = configs.length; 190 | Log.w(TAG, String.format("%d configurations", numConfigs)); 191 | for (int i = 0; i < numConfigs; i++) { 192 | Log.w(TAG, String.format("Configuration %d:\n", i)); 193 | printConfig(egl, display, configs[i]); 194 | } 195 | } 196 | 197 | private void printConfig(EGL10 egl, EGLDisplay display, 198 | EGLConfig config) { 199 | int[] attributes = { 200 | EGL10.EGL_BUFFER_SIZE, 201 | EGL10.EGL_ALPHA_SIZE, 202 | EGL10.EGL_BLUE_SIZE, 203 | EGL10.EGL_GREEN_SIZE, 204 | EGL10.EGL_RED_SIZE, 205 | EGL10.EGL_DEPTH_SIZE, 206 | EGL10.EGL_STENCIL_SIZE, 207 | EGL10.EGL_CONFIG_CAVEAT, 208 | EGL10.EGL_CONFIG_ID, 209 | EGL10.EGL_LEVEL, 210 | EGL10.EGL_MAX_PBUFFER_HEIGHT, 211 | EGL10.EGL_MAX_PBUFFER_PIXELS, 212 | EGL10.EGL_MAX_PBUFFER_WIDTH, 213 | EGL10.EGL_NATIVE_RENDERABLE, 214 | EGL10.EGL_NATIVE_VISUAL_ID, 215 | EGL10.EGL_NATIVE_VISUAL_TYPE, 216 | 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, 217 | EGL10.EGL_SAMPLES, 218 | EGL10.EGL_SAMPLE_BUFFERS, 219 | EGL10.EGL_SURFACE_TYPE, 220 | EGL10.EGL_TRANSPARENT_TYPE, 221 | EGL10.EGL_TRANSPARENT_RED_VALUE, 222 | EGL10.EGL_TRANSPARENT_GREEN_VALUE, 223 | EGL10.EGL_TRANSPARENT_BLUE_VALUE, 224 | 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, 225 | 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, 226 | 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, 227 | 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, 228 | EGL10.EGL_LUMINANCE_SIZE, 229 | EGL10.EGL_ALPHA_MASK_SIZE, 230 | EGL10.EGL_COLOR_BUFFER_TYPE, 231 | EGL10.EGL_RENDERABLE_TYPE, 232 | 0x3042 // EGL10.EGL_CONFORMANT 233 | }; 234 | String[] names = { 235 | "EGL_BUFFER_SIZE", 236 | "EGL_ALPHA_SIZE", 237 | "EGL_BLUE_SIZE", 238 | "EGL_GREEN_SIZE", 239 | "EGL_RED_SIZE", 240 | "EGL_DEPTH_SIZE", 241 | "EGL_STENCIL_SIZE", 242 | "EGL_CONFIG_CAVEAT", 243 | "EGL_CONFIG_ID", 244 | "EGL_LEVEL", 245 | "EGL_MAX_PBUFFER_HEIGHT", 246 | "EGL_MAX_PBUFFER_PIXELS", 247 | "EGL_MAX_PBUFFER_WIDTH", 248 | "EGL_NATIVE_RENDERABLE", 249 | "EGL_NATIVE_VISUAL_ID", 250 | "EGL_NATIVE_VISUAL_TYPE", 251 | "EGL_PRESERVED_RESOURCES", 252 | "EGL_SAMPLES", 253 | "EGL_SAMPLE_BUFFERS", 254 | "EGL_SURFACE_TYPE", 255 | "EGL_TRANSPARENT_TYPE", 256 | "EGL_TRANSPARENT_RED_VALUE", 257 | "EGL_TRANSPARENT_GREEN_VALUE", 258 | "EGL_TRANSPARENT_BLUE_VALUE", 259 | "EGL_BIND_TO_TEXTURE_RGB", 260 | "EGL_BIND_TO_TEXTURE_RGBA", 261 | "EGL_MIN_SWAP_INTERVAL", 262 | "EGL_MAX_SWAP_INTERVAL", 263 | "EGL_LUMINANCE_SIZE", 264 | "EGL_ALPHA_MASK_SIZE", 265 | "EGL_COLOR_BUFFER_TYPE", 266 | "EGL_RENDERABLE_TYPE", 267 | "EGL_CONFORMANT" 268 | }; 269 | int[] value = new int[1]; 270 | for (int i = 0; i < attributes.length; i++) { 271 | int attribute = attributes[i]; 272 | String name = names[i]; 273 | if ( egl.eglGetConfigAttrib(display, config, attribute, value)) { 274 | Log.w(TAG, String.format(" %s: %d\n", name, value[0])); 275 | } else { 276 | // Log.w(TAG, String.format(" %s: failed\n", name)); 277 | while (egl.eglGetError() != EGL10.EGL_SUCCESS); 278 | } 279 | } 280 | } 281 | 282 | // Subclasses can adjust these values: 283 | protected int mRedSize; 284 | protected int mGreenSize; 285 | protected int mBlueSize; 286 | protected int mAlphaSize; 287 | protected int mDepthSize; 288 | protected int mStencilSize; 289 | private int[] mValue = new int[1]; 290 | } 291 | 292 | } 293 | -------------------------------------------------------------------------------- /Android/app/src/main/java/com/home/Swift_OpenGL_Example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.home.Swift_OpenGL_Example; 2 | 3 | import android.app.Activity; 4 | import android.opengl.GLSurfaceView; 5 | import android.os.Bundle; 6 | import android.util.Log; 7 | import android.view.MotionEvent; 8 | import android.view.View; 9 | import android.widget.RelativeLayout; 10 | 11 | import javax.microedition.khronos.egl.EGLConfig; 12 | import javax.microedition.khronos.opengles.GL10; 13 | 14 | public class MainActivity extends Activity { 15 | 16 | SwiftApp swiftApp; 17 | GLView mView; 18 | 19 | @Override protected void onCreate(Bundle icicle) { 20 | super.onCreate(icicle); 21 | 22 | if (swiftApp == null) { 23 | swiftApp = new SwiftApp(); 24 | } 25 | 26 | mView = new GLView(getApplication()); 27 | 28 | Renderer render = new MainActivity.Renderer(); 29 | render.swiftApp = swiftApp; 30 | /* Set the renderer responsible for frame rendering */ 31 | mView.setRenderer(render); 32 | 33 | setContentView(mView); 34 | 35 | TouchListener listener = new TouchListener(); 36 | listener.swiftApp = swiftApp; 37 | mView.setOnTouchListener(listener); 38 | } 39 | 40 | @Override protected void onPause() { 41 | super.onPause(); 42 | mView.onPause(); 43 | } 44 | 45 | @Override protected void onResume() { 46 | super.onResume(); 47 | mView.onResume(); 48 | } 49 | 50 | private static class Renderer implements GLSurfaceView.Renderer { 51 | public SwiftApp swiftApp; 52 | 53 | public void onDrawFrame(GL10 gl) { 54 | swiftApp.needsDisplay(); 55 | } 56 | 57 | public void onSurfaceChanged(GL10 gl, int width, int height) { 58 | swiftApp.windowDidResize(width, height); 59 | } 60 | 61 | public void onSurfaceCreated(GL10 gl, EGLConfig config) { 62 | 63 | int result = swiftApp.applicationCreate(); 64 | Log.i("Swift", "applicationCreate " + result); 65 | } 66 | } 67 | 68 | private static class TouchListener implements View.OnTouchListener{ 69 | public SwiftApp swiftApp; 70 | 71 | public boolean onTouch(View view, MotionEvent event) { 72 | final int X = (int) event.getRawX(); 73 | final int Y = (int) event.getRawY(); 74 | switch (event.getAction() & MotionEvent.ACTION_MASK) { 75 | case MotionEvent.ACTION_DOWN: 76 | swiftApp.pointerDown(X, Y); 77 | break; 78 | case MotionEvent.ACTION_UP: 79 | swiftApp.pointerUp(X, Y); 80 | break; 81 | case MotionEvent.ACTION_POINTER_DOWN: 82 | swiftApp.pointerDown(X, Y); 83 | break; 84 | case MotionEvent.ACTION_POINTER_UP: 85 | swiftApp.pointerUp(X, Y); 86 | break; 87 | case MotionEvent.ACTION_MOVE: 88 | swiftApp.pointerMove(X, Y); 89 | break; 90 | } 91 | return true; 92 | } 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /Android/app/src/main/java/com/home/Swift_OpenGL_Example/SwiftApp.java: -------------------------------------------------------------------------------- 1 | package com.home.Swift_OpenGL_Example; 2 | 3 | public class SwiftApp { 4 | 5 | static { 6 | System.loadLibrary("icudata"); 7 | System.loadLibrary("icuuc"); 8 | System.loadLibrary("icui18n"); 9 | System.loadLibrary("Foundation"); 10 | System.loadLibrary("dispatch"); 11 | System.loadLibrary("OpenGLExampleApp"); 12 | } 13 | 14 | public native int applicationCreate(); 15 | public native void needsDisplay(); 16 | public native void windowDidResize(int width, int height); 17 | 18 | public native void pointerDown(int x, int y); 19 | public native void pointerMove(int x, int y); 20 | public native void pointerUp(int x, int y); 21 | } 22 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /Android/app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 11 | 16 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 56 | 61 | 66 | 71 | 76 | 81 | 86 | 91 | 96 | 101 | 106 | 111 | 116 | 121 | 126 | 131 | 136 | 141 | 146 | 151 | 156 | 161 | 166 | 171 | 172 | -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /Android/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #008577 4 | #00574B 5 | #D81B60 6 | 7 | -------------------------------------------------------------------------------- /Android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Swift OpenGL 3 | 4 | -------------------------------------------------------------------------------- /Android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Android/app/src/test/java/com/home/Swift_OpenGL_Example/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.home.helloNDK; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /Android/build.gradle: -------------------------------------------------------------------------------- 1 | import java.nio.file.Paths 2 | 3 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 4 | 5 | buildscript { 6 | ext.kotlin_version = '1.6.21' 7 | ext.protobufVersion = '0.9.0' 8 | repositories { 9 | google() 10 | jcenter() 11 | } 12 | dependencies { 13 | classpath 'com.android.tools.build:gradle:8.1.0' 14 | classpath "com.google.protobuf:protobuf-gradle-plugin:$protobufVersion" 15 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 16 | 17 | // NOTE: Do not place your application dependencies here; they belong 18 | // in the individual module build.gradle files 19 | } 20 | } 21 | 22 | allprojects { 23 | repositories { 24 | google() 25 | jcenter() 26 | } 27 | } 28 | 29 | task clean(type: Delete) { 30 | // See: 31 | // - Logging: https://docs.gradle.org/current/userguide/logging.html 32 | 33 | //logger.lifecycle(String.format("- Deleting %s", rootProject.buildDir.toString())) 34 | delete rootProject.buildDir 35 | 36 | File filePath = new File(Paths.get(rootDir.toString(), "app/src/main/jniLibs").toString()) 37 | //logger.lifecycle(String.format("- Deleting %s", filePath.toString())) 38 | delete filePath 39 | } 40 | -------------------------------------------------------------------------------- /Android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | android.defaults.buildfeatures.buildconfig=true 10 | android.enableJetifier=true 11 | android.nonFinalResIds=false 12 | android.nonTransitiveRClass=false 13 | android.useAndroidX=true 14 | org.gradle.jvmargs=-Xmx1536m 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # See: 21 | # - Build Environment: https://docs.gradle.org/5.1.1/userguide/build_environment.html#sec:gradle_configuration_properties 22 | #org.gradle.logging.level=debug 23 | #org.gradle.daemon=false -------------------------------------------------------------------------------- /Android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /Android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Attempt to set APP_HOME 10 | # Resolve links: $0 may be a link 11 | PRG="$0" 12 | # Need this for relative symlinks. 13 | while [ -h "$PRG" ] ; do 14 | ls=`ls -ld "$PRG"` 15 | link=`expr "$ls" : '.*-> \(.*\)$'` 16 | if expr "$link" : '/.*' > /dev/null; then 17 | PRG="$link" 18 | else 19 | PRG=`dirname "$PRG"`"/$link" 20 | fi 21 | done 22 | SAVED="`pwd`" 23 | cd "`dirname \"$PRG\"`/" >/dev/null 24 | APP_HOME="`pwd -P`" 25 | cd "$SAVED" >/dev/null 26 | 27 | APP_NAME="Gradle" 28 | APP_BASE_NAME=`basename "$0"` 29 | 30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 31 | DEFAULT_JVM_OPTS="" 32 | 33 | # Use the maximum available, or set MAX_FD != -1 to use that value. 34 | MAX_FD="maximum" 35 | 36 | warn () { 37 | echo "$*" 38 | } 39 | 40 | die () { 41 | echo 42 | echo "$*" 43 | echo 44 | exit 1 45 | } 46 | 47 | # OS specific support (must be 'true' or 'false'). 48 | cygwin=false 49 | msys=false 50 | darwin=false 51 | nonstop=false 52 | case "`uname`" in 53 | CYGWIN* ) 54 | cygwin=true 55 | ;; 56 | Darwin* ) 57 | darwin=true 58 | ;; 59 | MINGW* ) 60 | msys=true 61 | ;; 62 | NONSTOP* ) 63 | nonstop=true 64 | ;; 65 | esac 66 | 67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 68 | 69 | # Determine the Java command to use to start the JVM. 70 | if [ -n "$JAVA_HOME" ] ; then 71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 72 | # IBM's JDK on AIX uses strange locations for the executables 73 | JAVACMD="$JAVA_HOME/jre/sh/java" 74 | else 75 | JAVACMD="$JAVA_HOME/bin/java" 76 | fi 77 | if [ ! -x "$JAVACMD" ] ; then 78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 79 | 80 | Please set the JAVA_HOME variable in your environment to match the 81 | location of your Java installation." 82 | fi 83 | else 84 | JAVACMD="java" 85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 86 | 87 | Please set the JAVA_HOME variable in your environment to match the 88 | location of your Java installation." 89 | fi 90 | 91 | # Increase the maximum file descriptors if we can. 92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 93 | MAX_FD_LIMIT=`ulimit -H -n` 94 | if [ $? -eq 0 ] ; then 95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 96 | MAX_FD="$MAX_FD_LIMIT" 97 | fi 98 | ulimit -n $MAX_FD 99 | if [ $? -ne 0 ] ; then 100 | warn "Could not set maximum file descriptor limit: $MAX_FD" 101 | fi 102 | else 103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 104 | fi 105 | fi 106 | 107 | # For Darwin, add options to specify how the application appears in the dock 108 | if $darwin; then 109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 110 | fi 111 | 112 | # For Cygwin, switch paths to Windows format before running java 113 | if $cygwin ; then 114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 116 | JAVACMD=`cygpath --unix "$JAVACMD"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Escape application args 158 | save () { 159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 160 | echo " " 161 | } 162 | APP_ARGS=$(save "$@") 163 | 164 | # Collect all arguments for the java command, following the shell quoting and substitution rules 165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 166 | 167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 169 | cd "$(dirname "$0")" 170 | fi 171 | 172 | exec "$JAVACMD" "$@" 173 | -------------------------------------------------------------------------------- /Android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /Android/local.properties: -------------------------------------------------------------------------------- 1 | ## This file must *NOT* be checked into Version Control Systems, 2 | # as it contains information specific to your local configuration. 3 | # 4 | # Location of the SDK. This is only used by Gradle. 5 | # For customization when using a Version Control System, please read the 6 | # header note. 7 | #Sat Jul 29 22:23:03 IST 2023 8 | sdk.dir=/Users/sakrist/Library/Android/sdk 9 | -------------------------------------------------------------------------------- /Android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/Default-568h@2x.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Volodymyr Boichentsov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.5 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "OpenGLExampleApp", 7 | products: [ 8 | .library(name: "OpenGLExampleApp", type: .dynamic, targets: ["app"]) 9 | ], 10 | dependencies: [ 11 | .package(url: "https://github.com/SwiftGFX/SwiftMath", from: "3.3.1"), 12 | .package(url: "https://github.com/sakrist/GLApplication", branch: "main"), 13 | .package(url: "https://github.com/sakrist/AndroidNDK", branch: "main") 14 | ], 15 | targets: [ 16 | .executableTarget(name: "app", 17 | dependencies: [ "SwiftMath", "GLApplication", "AndroidNDK" ], 18 | cSettings: [.define("GL_GLEXT_PROTOTYPES")]) 19 | ] 20 | ) 21 | 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Swift OpenGL Example 2 | 3 | This project was developed just for proof of concept: Simple application using OpenGL and written with swift - can be compiled and run on Ubuntu (Linux), macOS, iOS and **Android**. And in future on some *X* platform too. 4 | 5 | ### macOS 6 | 7 | Terminal: 8 | 9 | 1. Open a terminal window 10 | 2. Clone repository 11 | 3. Go to the directory to which you clone. 12 | 4. run `swift build` in terminal 13 | 5. run `.build/debug/app` 14 | 15 | or Xcode 16 | 17 | Open `opengl_example.xcodeproj` project. 18 | 19 | ### iOS 20 | 21 | 1. Open `opengl_example.xcodeproj` project. 22 | 2. Select **iOS_example** target and destination 23 | 3. Run 24 | 25 | ### Linux (Ubuntu 64-bit) 26 | 27 | 1. [Install](https://swift.org/getting-started/#installing-swift) swift toolchaine. 28 | 29 | 2. Open a terminal window 30 | 3. Install dependecies packages
31 | `sudo apt-get install libx11-dev libglu1-mesa-dev mesa-common-dev` 32 | 4. Clone repository 33 | 5. Go to the directory with project. 34 | 6. run `swift build` to build 35 | 7. run `.build/debug/app` 36 | 37 | ### Android 38 | 39 | 1. Read [Readme](Android/Readme.md) inside Android folder 40 | 41 | ### Screenshots 42 | 43 | - macOS
44 | 45 | 46 | - iOS
47 | 48 | 49 | - Ubuntu
50 | 51 | 52 | - Android
53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /Sources/app/App.swift: -------------------------------------------------------------------------------- 1 | // 2 | // App.swift 3 | // OpenGL_example 4 | // 5 | // Created by Volodymyr Boichentsov on 29/12/2015. 6 | // 7 | // 8 | 9 | #if os(Linux) 10 | import Glibc 11 | #elseif os(OSX) 12 | import Darwin.C 13 | #elseif os(iOS) 14 | import OpenGLES 15 | #elseif os(Android) 16 | import Glibc 17 | import ndk.GLES3 18 | #endif 19 | 20 | import SwiftMath 21 | import GLApplication 22 | 23 | class App: Application { 24 | 25 | // Scene variable, getter and setter. 26 | var scene:Scene { 27 | get { 28 | return self.renderObject as! Scene 29 | } 30 | set(scene) { 31 | self.renderObject = scene 32 | } 33 | } 34 | 35 | var lastMousePoint:Point = Point() 36 | 37 | var pitch:Float = 0.0 38 | var yaw:Float = 0.0 39 | 40 | override func applicationCreate() { 41 | 42 | if isGLOn() { 43 | // create scene 44 | self.scene = Scene() 45 | scene.size = Size(640, 480) 46 | let rotateX = Matrix4x4f.rotate(x: Angle.init(radians: pitch)) 47 | let rotateY = Matrix4x4f.rotate(y: Angle.init(radians: yaw)) 48 | scene.modelViewMatrix = scene.modelViewMatrix * (rotateX * rotateY) 49 | scene.geometries.append(Cube()) 50 | 51 | // re-draw after init 52 | self.needsDisplay() 53 | } 54 | } 55 | 56 | override func applicationClose() { 57 | 58 | } 59 | 60 | override func windowDidResize(_ size:Size) { 61 | scene.size = size 62 | } 63 | 64 | // mouse events 65 | override func mouseDown(_ point:Point, button:Int) { 66 | lastMousePoint = point 67 | } 68 | 69 | override func mouseMove(_ point:Point) { 70 | 71 | 72 | 73 | let x = Float( (point.x - lastMousePoint.x) * scene.size.height/scene.size.width*0.5 ) 74 | let y = Float( (point.y - lastMousePoint.y) * -(scene.size.width/scene.size.height*0.5) ) 75 | 76 | pitch += -Angle.init(degrees:y).radians 77 | yaw += Angle.init(degrees:x).radians 78 | 79 | let rotateX = Matrix4x4f.rotate(x: Angle.init(radians: pitch)) 80 | let rotateY = Matrix4x4f.rotate(y: Angle.init(radians: yaw)) 81 | scene.modelViewMatrix = Matrix4x4f.translate(tx: 0, ty: 0, tz: -4) * (rotateX * rotateY) 82 | 83 | lastMousePoint = point 84 | 85 | needsDisplay() 86 | } 87 | 88 | override func mouseUp(_ point:Point) { 89 | 90 | } 91 | } 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /Sources/app/Cube.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Cube.swift 3 | // OpenGL_example 4 | // 5 | // Created by Volodymyr Boichentsov on 01/01/2016. 6 | // 7 | // 8 | 9 | #if os(Linux) 10 | import Glibc 11 | import OpenGL 12 | #elseif os(OSX) 13 | import Darwin.C 14 | import Cocoa 15 | #elseif os(iOS) 16 | import OpenGLES 17 | #elseif os(Android) 18 | import Glibc 19 | import ndk.GLES3 20 | #endif 21 | 22 | 23 | class Cube: Geometry { 24 | init() { 25 | super.init(data:gCubeVertexData) 26 | } 27 | } 28 | 29 | 30 | var gCubeVertexData: [Float32] = [ 31 | // Data layout for each line below is: 32 | // positionX, positionY, positionZ, normalX, normalY, normalZ, 33 | 0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 34 | 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 35 | 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 36 | 0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 37 | 0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 38 | 0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 39 | 40 | 0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 41 | -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 42 | 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 43 | 0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 44 | -0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 45 | -0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 46 | 47 | -0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 48 | -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 49 | -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 50 | -0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 51 | -0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 52 | -0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 53 | 54 | -0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 55 | 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 56 | -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 57 | -0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 58 | 0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 59 | 0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 60 | 61 | 0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 62 | -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 63 | 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 64 | 0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 65 | -0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 66 | -0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 67 | 68 | 0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 69 | -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 70 | 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 71 | 0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 72 | -0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 73 | -0.5, 0.5, -0.5, 0.0, 0.0, -1.0 74 | ] 75 | -------------------------------------------------------------------------------- /Sources/app/Geometry.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Geometry.swift 3 | // OpenGL_example 4 | // 5 | // Created by Volodymyr Boichentsov on 01/01/2016. 6 | // 7 | // 8 | 9 | #if os(Linux) 10 | import Glibc 11 | import OpenGL 12 | #elseif os(OSX) 13 | import Darwin.C 14 | import Cocoa 15 | import OpenGL 16 | #elseif os(iOS) 17 | import OpenGLES 18 | #elseif os(Android) 19 | import Glibc 20 | import ndk.GLES3 21 | #endif 22 | 23 | func BUFFER_OFFSET(_ i: Int) -> UnsafeRawPointer? { 24 | let off = UnsafeRawPointer(bitPattern: i) 25 | return off 26 | } 27 | 28 | class Geometry { 29 | 30 | var vertexArray: GLuint = 0 31 | var vertexBuffer: GLuint = 0 32 | 33 | var dataCount:Int32 = 0 34 | var indicesCount:Int32 = 0 35 | 36 | init(data:[Float32]) { 37 | 38 | dataCount = Int32(data.count) 39 | indicesCount = dataCount/6 40 | 41 | glGenVertexArrays(1, &vertexArray) 42 | glBindVertexArray(vertexArray) 43 | 44 | glGenBuffers(1, &vertexBuffer) 45 | glBindBuffer(GLenum(GL_ARRAY_BUFFER), vertexBuffer) 46 | glBufferData(GLenum(GL_ARRAY_BUFFER), GLsizeiptr(MemoryLayout.size * Int(dataCount)), data, GLenum(GL_STATIC_DRAW)) 47 | 48 | glEnableVertexAttribArray(Shader.positionAttribute) 49 | glVertexAttribPointer(Shader.positionAttribute, 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 24, BUFFER_OFFSET(0)) 50 | glEnableVertexAttribArray(Shader.normalAttribute) 51 | glVertexAttribPointer(Shader.normalAttribute, 3, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 24, BUFFER_OFFSET(12)) 52 | 53 | glBindVertexArray(0) 54 | 55 | } 56 | 57 | 58 | func draw() { 59 | glBindVertexArray(vertexArray) 60 | glDrawArrays(GLenum(GL_TRIANGLES), 0, indicesCount) 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /Sources/app/Scene.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Scene.swift 3 | // OpenGL_example 4 | // 5 | // Created by Volodymyr Boichentsov on 29/12/2015. 6 | // 7 | // 8 | 9 | #if os(Linux) 10 | import Glibc 11 | import OpenGL 12 | #elseif os(OSX) 13 | import Darwin.C 14 | import Cocoa 15 | import OpenGL 16 | import simd 17 | #elseif os(iOS) 18 | import OpenGLES 19 | #elseif os(Android) 20 | import Glibc 21 | import ndk.GLES3 22 | #endif 23 | 24 | import GLApplication 25 | import SwiftMath 26 | 27 | extension Matrix4x4f { 28 | 29 | func extract() -> Matrix3x3f { 30 | let P = self[0].xyz 31 | let Q = self[1].xyz 32 | let R = self[2].xyz 33 | return Matrix3x3f.init(P, Q, R) 34 | } 35 | } 36 | 37 | 38 | 39 | public class Scene: RenderObject { 40 | 41 | var shader:Shader! 42 | 43 | var geometries:[Geometry] = [] 44 | 45 | var modelViewProjectionMatrix = Matrix4x4f.identity 46 | var modelViewMatrix = Matrix4x4f.identity 47 | var projectionMatrix = Matrix4x4f.identity 48 | 49 | var normalMatrix = Matrix3x3f.identity 50 | 51 | var fovAngle:Float = 65.0 52 | var farZ:Float = 100.0 53 | var nearZ:Float = 0.1 54 | 55 | var size:Size = Size(640, 480) { 56 | didSet { 57 | let aspect = fabsf(Float(size.width / size.height)) 58 | let angle = Angle.init(degrees: fovAngle) 59 | 60 | let height = 1.0 / tan(angle * 0.5) 61 | let width = height * 1.0/aspect; 62 | 63 | projectionMatrix = Matrix4x4f.projRH(x:0, y:0, 64 | w:width, h:height, 65 | near: nearZ, far: farZ) 66 | } 67 | } 68 | 69 | init() { 70 | 71 | // init shader 72 | self.shader = Shader(vertexShader:vertexShader, fragmentShader:fragmentShader) 73 | 74 | glEnable(GLenum(GL_DEPTH_TEST)) 75 | 76 | modelViewMatrix = Matrix4x4f.translate(tx:0, ty:0, tz:-4.0) 77 | 78 | update() 79 | } 80 | 81 | func update() { 82 | 83 | modelViewProjectionMatrix = projectionMatrix * modelViewMatrix 84 | 85 | normalMatrix = modelViewMatrix.extract() 86 | normalMatrix = normalMatrix.inversed 87 | normalMatrix = normalMatrix.transposed 88 | 89 | } 90 | 91 | public func render() { 92 | 93 | update() 94 | 95 | 96 | glClear(GLbitfield(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) 97 | glClearColor(0.65, 0.65, 0.65, 1.0) 98 | 99 | // Use shader 100 | shader.use() 101 | 102 | withUnsafePointer(to: &modelViewProjectionMatrix, { 103 | $0.withMemoryRebound(to: Float.self, capacity: 16, { 104 | glUniformMatrix4fv(shader.uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, $0) 105 | }) 106 | }) 107 | 108 | withUnsafePointer(to: &normalMatrix, { 109 | $0.withMemoryRebound(to: Float.self, capacity: 9, { 110 | glUniformMatrix3fv(shader.uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, $0) 111 | }) 112 | }) 113 | 114 | // Draw objects 115 | for g in geometries { 116 | g.draw() 117 | } 118 | } 119 | } 120 | 121 | 122 | var vertexShader = "#version 000 \n" 123 | + "// macroses \n" 124 | + "\n" 125 | + "#if defined(GL_ES)\n" 126 | + "precision highp float;\n" 127 | + "#endif\n" 128 | + "#if version>130 \n" 129 | + "#define attribute in \n" 130 | + "#define varying out \n" 131 | + "#endif \n" 132 | + "\n" 133 | + "attribute vec4 position;\n" 134 | + "attribute vec3 normal;\n" 135 | + "\n" 136 | + "varying vec4 colorVarying;\n" 137 | + "\n" 138 | + "uniform mat4 modelViewProjectionMatrix;\n" 139 | + "uniform mat3 normalMatrix;\n" 140 | + "\n" 141 | + "void main()\n" 142 | + " {\n" 143 | + " vec3 eyeNormal = normalize(normalMatrix * normal);\n" 144 | + " vec3 lightPosition = vec3(0.0, 0.0, 1.0);\n" 145 | + " vec4 diffuseColor = vec4(0.4, 0.4, 1.0, 1.0);\n" 146 | + "\n" 147 | + " float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));\n" 148 | + "\n" 149 | + " colorVarying = diffuseColor * nDotVP;\n" 150 | + "\n" 151 | + " gl_Position = modelViewProjectionMatrix * position;\n" 152 | + "}\n " 153 | 154 | 155 | var fragmentShader = "#version 000\n" 156 | + "// macroses \n" 157 | + "\n" 158 | + "#if defined(GL_ES)\n" 159 | + "precision mediump float;\n" 160 | + "#endif\n" 161 | + "\n" 162 | + "#if version>130 \n" 163 | + "#define varying in \n" 164 | + "out vec4 glFragData0;\n" 165 | + "#else\n" 166 | + "#define glFragData0 gl_FragColor \n" 167 | + "#endif \n" 168 | + "\n" 169 | + "varying vec4 colorVarying;\n" 170 | + "\n" 171 | + "void main()\n" 172 | + " {\n" 173 | + " glFragData0 = colorVarying;\n" 174 | + "}\n " 175 | 176 | -------------------------------------------------------------------------------- /Sources/app/Shader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Shader.swift 3 | // OpenGL_example 4 | // 5 | // Created by Volodymyr Boichentsov on 30/12/2015. 6 | // 7 | // 8 | 9 | #if os(Linux) 10 | import Glibc 11 | import OpenGL 12 | #elseif os(OSX) 13 | import Darwin.C 14 | import GLKit 15 | #elseif os(iOS) 16 | import OpenGLES 17 | import OpenGLES.ES3 18 | #elseif os(Android) 19 | import Glibc 20 | import ndk.GLES3 21 | #endif 22 | 23 | public func isGLOn() -> Bool { 24 | let v = glGetString(GLenum(GL_VERSION)) 25 | if (v != nil) { 26 | return true 27 | } 28 | return false 29 | } 30 | 31 | 32 | public let UNIFORM_MODELVIEWPROJECTION_MATRIX = 0 33 | public let UNIFORM_NORMAL_MATRIX = 1 34 | 35 | public class Shader { 36 | 37 | public static var positionAttribute:GLuint = 0 38 | public static var normalAttribute:GLuint = 1 39 | 40 | 41 | public var program:UInt32 = 0 42 | public var uniforms = [GLint](repeating: 0, count: 2) 43 | 44 | public init?(vertexShader: String, fragmentShader: String) { 45 | 46 | var vertexShader_ = vertexShader; 47 | var fragmentShader_ = fragmentShader; 48 | 49 | let GL_version_cstring = glGetString(GLenum(GL_VERSION)) as UnsafePointer 50 | let GL_version_string = String(cString:GL_version_cstring) 51 | debugPrint(GL_version_string) 52 | 53 | let glsl_version_cstring = glGetString(GLenum(GL_SHADING_LANGUAGE_VERSION)) as UnsafePointer 54 | var glsl_version_string = String(cString:glsl_version_cstring) 55 | 56 | // test if it's ES 57 | let isES = (glsl_version_string.rangesOfString("ES").count != 0) 58 | 59 | if let lastString = glsl_version_string.split(separator: " ").last { 60 | glsl_version_string = String.init(lastString) 61 | } 62 | glsl_version_string.remove(at:glsl_version_string.index(glsl_version_string.startIndex, offsetBy: 1)) // delete point 1.30 -> 130 63 | 64 | // get version into Int value 65 | let glslVersion = Int(glsl_version_string) ?? 0 66 | 67 | // form string for replacement 68 | glsl_version_string = "version " + glsl_version_string + ((isES && glslVersion > 100) ? " es" : "" ) 69 | 70 | // replace version 71 | var range = vertexShader_.rangesOfString("version 000") 72 | for r in range { 73 | vertexShader_.replaceSubrange(r, with: glsl_version_string) 74 | } 75 | 76 | range = fragmentShader_.rangesOfString("version 000") 77 | for r in range { 78 | fragmentShader_.replaceSubrange(r, with: glsl_version_string) 79 | } 80 | 81 | // create macro for version 82 | let glslVersionMacro = "version \(glslVersion)" 83 | 84 | // create macorses string 85 | let macroses = "#define " + glslVersionMacro + "\n" 86 | 87 | // set macroses 88 | range = vertexShader_.rangesOfString("// macroses") 89 | for r in range { 90 | vertexShader_.replaceSubrange(r, with: macroses) 91 | } 92 | 93 | range = fragmentShader_.rangesOfString("// macroses") 94 | for r in range { 95 | fragmentShader_.replaceSubrange(r, with: macroses) 96 | } 97 | 98 | var vertShader: GLuint = 0 99 | var fragShader: GLuint = 0 100 | 101 | // Create shader program. 102 | program = glCreateProgram() 103 | 104 | // Create and compile vertex shader. 105 | if self.compileShader(shader: &vertShader, type: GLenum(GL_VERTEX_SHADER), shaderString: vertexShader_) == false { 106 | print("Failed to compile vertex shader") 107 | print(vertexShader_) 108 | return nil 109 | } 110 | 111 | // Create and compile fragment shader. 112 | if !self.compileShader(shader: &fragShader, type: GLenum(GL_FRAGMENT_SHADER), shaderString: fragmentShader_) { 113 | print("Failed to compile fragment shader") 114 | return nil 115 | } 116 | 117 | // Attach vertex shader to program. 118 | glAttachShader(self.program, vertShader) 119 | 120 | // Attach fragment shader to program. 121 | glAttachShader(self.program, fragShader) 122 | 123 | // Bind attribute locations. 124 | // This needs to be done prior to linking. 125 | glBindAttribLocation(self.program, Shader.positionAttribute, "position") 126 | glBindAttribLocation(self.program, Shader.normalAttribute, "normal") 127 | 128 | #if os(iOS) || os(Android) 129 | glGetFragDataLocation(self.program, "glFragData0"); 130 | #else 131 | glBindFragDataLocation(self.program, 0, "glFragData0"); 132 | #endif 133 | // Link program. 134 | if !self.linkProgram(self.program) { 135 | print("Failed to link program: \(self.program)") 136 | 137 | if vertShader != 0 { 138 | glDeleteShader(vertShader) 139 | vertShader = 0 140 | } 141 | if fragShader != 0 { 142 | glDeleteShader(fragShader) 143 | fragShader = 0 144 | } 145 | if program != 0 { 146 | glDeleteProgram(self.program) 147 | self.program = 0 148 | } 149 | 150 | return nil 151 | } 152 | 153 | // Get uniform locations. 154 | self.uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX] = glGetUniformLocation(program, "modelViewProjectionMatrix") 155 | self.uniforms[UNIFORM_NORMAL_MATRIX] = glGetUniformLocation(program, "normalMatrix") 156 | 157 | // Release vertex and fragment shaders. 158 | if vertShader != 0 { 159 | glDetachShader(program, vertShader) 160 | glDeleteShader(vertShader) 161 | } 162 | if fragShader != 0 { 163 | glDetachShader(program, fragShader) 164 | glDeleteShader(fragShader) 165 | } 166 | 167 | // self.validateProgram(program) 168 | } 169 | 170 | func compileShader(shader: inout GLuint, type: GLenum, shaderString: String) -> Bool { 171 | var status: GLint = 0 172 | 173 | let source = UnsafeMutablePointer.allocate(capacity: shaderString.count) 174 | let size = shaderString.count 175 | var idx = 0 176 | for u in shaderString.utf8 { 177 | if idx == size - 1 { break } 178 | source[idx] = Int8(u) 179 | idx += 1 180 | } 181 | source[idx] = 0 // NUL-terminate the C string in the array. 182 | 183 | var castSource: UnsafePointer? = UnsafePointer(source) 184 | 185 | shader = glCreateShader(type) 186 | glShaderSource(shader, 1, &castSource, nil) 187 | glCompileShader(shader) 188 | 189 | source.deallocate() 190 | 191 | // #if defined(DEBUG) 192 | var logLength: GLint = 0 193 | glGetShaderiv(shader, GLenum(GL_INFO_LOG_LENGTH), &logLength) 194 | if logLength > 0 { 195 | var log = [GLchar](repeating: 0, count: 512) 196 | glGetShaderInfoLog(shader, 512, &logLength, &log) 197 | 198 | let logString = String(cString:log) 199 | print(logString) 200 | 201 | } 202 | // #endif 203 | 204 | glGetShaderiv(shader, GLenum(GL_COMPILE_STATUS), &status) 205 | if status == 0 { 206 | glDeleteShader(shader) 207 | return false 208 | } 209 | return true 210 | } 211 | 212 | func linkProgram(_ prog: GLuint) -> Bool { 213 | var status: GLint = 0 214 | glLinkProgram(prog) 215 | 216 | glGetProgramiv(prog, GLenum(GL_LINK_STATUS), &status) 217 | if status == 0 { 218 | return false 219 | } 220 | 221 | return true 222 | } 223 | 224 | func validateProgram(prog: GLuint) -> Bool { 225 | var logLength: GLsizei = 0 226 | var status: GLint = 0 227 | 228 | glValidateProgram(prog) 229 | glGetProgramiv(prog, GLenum(GL_INFO_LOG_LENGTH), &logLength) 230 | if logLength > 0 { 231 | var log: [GLchar] = [GLchar](repeating: 0, count: Int(logLength)) 232 | glGetProgramInfoLog(prog, logLength, &logLength, &log) 233 | print("Program validate log: \n\(String(cString:log))") 234 | } 235 | 236 | glGetProgramiv(prog, GLenum(GL_VALIDATE_STATUS), &status) 237 | var returnVal = true 238 | if status == 0 { 239 | returnVal = false 240 | } 241 | return returnVal 242 | } 243 | 244 | func use() { 245 | glUseProgram(self.program) 246 | } 247 | 248 | } 249 | -------------------------------------------------------------------------------- /Sources/app/String_extention.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String_extention.swift 3 | // 4 | // Created by Volodymyr Boichentsov on 01/01/2016. 5 | // 6 | // 7 | 8 | public extension String { 9 | func rangesOfString(_ findStr:String) -> [Range] { 10 | var arr = [Range]() 11 | var startInd = self.startIndex 12 | // check first that the first character of search string exists 13 | if self.contains(findStr.first!) { 14 | // if so set this as the place to start searching 15 | startInd = self.firstIndex(of:findStr.first!)! 16 | } 17 | else { 18 | // if not return empty array 19 | return arr 20 | } 21 | var i = distance(from:self.startIndex, to:startInd) 22 | while i<=self.count-findStr.count { 23 | if self[self.index(self.startIndex, offsetBy:i)..) -> String { 36 | var ucstring_ = ucstring; 37 | var array : [Int8] = [] 38 | while (ucstring_[0] != UInt8(ascii:"\0")){ 39 | array.append(Int8(ucstring_[0])) 40 | ucstring_ = ucstring_.advanced(by:1) 41 | } 42 | array.append(Int8(0)) 43 | let newstring = String(validatingUTF8:array) 44 | return newstring! 45 | } 46 | 47 | static func fromCString(string:UnsafeMutablePointer) -> String { 48 | var array : [Int8] = [] 49 | var string_ = string 50 | while (UInt8(string_[0]) != UInt8(ascii:"\0")){ 51 | array.append(Int8(string_[0])) 52 | string_ = string_.advanced(by:1) 53 | } 54 | array.append(Int8(0)) 55 | let newstring = String(validatingUTF8:array) 56 | return newstring! 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /Sources/app/main.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main.swift 3 | // OpenGL_example 4 | // 5 | // Created by Volodymyr Boichentsov on 29/12/2015. 6 | // 7 | // 8 | 9 | // This file only for macOS and iOS 10 | 11 | #if os(Linux) 12 | import Glibc 13 | #elseif os(OSX) 14 | import Darwin.C 15 | import Cocoa 16 | #endif 17 | 18 | 19 | #if os(Linux) || os(macOS) 20 | import GLApplication 21 | func main() { 22 | let app = App() 23 | app.run() 24 | 25 | } 26 | main() 27 | 28 | #elseif os(iOS) 29 | import UIKit 30 | UIApplicationMain( CommandLine.argc, 31 | CommandLine.unsafeArgv, 32 | nil, 33 | NSStringFromClass(App.self)) 34 | #endif 35 | 36 | -------------------------------------------------------------------------------- /Sources/app/main_android.swift: -------------------------------------------------------------------------------- 1 | // 2 | // main_android.swift 3 | // Swift_OpenGL_Example 4 | // 5 | // Created by Volodymyr Boichentsov on 01/06/2019. 6 | // 7 | // 8 | 9 | #if os(Android) 10 | import Foundation 11 | import GLApplication 12 | import SwiftMath 13 | 14 | import ndk 15 | 16 | var app:App? 17 | 18 | func os_log(_ string:String) { 19 | _ = string.withCString { 20 | // TODO: pass app name to tag 21 | android_log(ANDROID_LOG_DEBUG, "swift", $0) 22 | } 23 | } 24 | 25 | @_cdecl("Java_com_home_Swift_1OpenGL_1Example_SwiftApp_applicationCreate") 26 | public func applicationCreate() -> Int32 { 27 | os_log("applicationCreate") 28 | if (app == nil) { 29 | app = App() 30 | app!.applicationCreate() 31 | return ( isGLOn() ? 1 : 0 ) 32 | } 33 | return 0 34 | } 35 | 36 | @_cdecl("Java_com_home_Swift_1OpenGL_1Example_SwiftApp_needsDisplay") 37 | public func needsDisplay() { 38 | app?.needsDisplay() 39 | } 40 | 41 | @_cdecl("Java_com_home_Swift_1OpenGL_1Example_SwiftApp_windowDidResize") 42 | public func windowDidResize(w:Int32, h:Int32) { 43 | let size = Size(w, h) 44 | app?.windowDidResize(size) 45 | 46 | os_log("windowDidResize \(size)") 47 | } 48 | 49 | 50 | @_cdecl("Java_com_home_Swift_1OpenGL_1Example_SwiftApp_pointerDown") 51 | public func pointerDown(x:Int32, y:Int32) { 52 | app?.mouseDown(Point(x, y), button:0) 53 | } 54 | 55 | @_cdecl("Java_com_home_Swift_1OpenGL_1Example_SwiftApp_pointerMove") 56 | public func pointerMove(x:Int32, y:Int32) { 57 | app?.mouseMove(Point(x, y)) 58 | } 59 | 60 | @_cdecl("Java_com_home_Swift_1OpenGL_1Example_SwiftApp_pointerUp") 61 | public func pointerUp(x:Int32, y:Int32) { 62 | app?.mouseUp(Point(x, y)) 63 | } 64 | 65 | 66 | #endif 67 | 68 | 69 | -------------------------------------------------------------------------------- /opengl_example.xcodeproj/AppBase_Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CFBundleDevelopmentRegion 5 | en 6 | CFBundleExecutable 7 | $(EXECUTABLE_NAME) 8 | CFBundleIdentifier 9 | $(PRODUCT_BUNDLE_IDENTIFIER) 10 | CFBundleInfoDictionaryVersion 11 | 6.0 12 | CFBundleName 13 | $(PRODUCT_NAME) 14 | CFBundlePackageType 15 | FMWK 16 | CFBundleShortVersionString 17 | 1.0 18 | CFBundleSignature 19 | ???? 20 | CFBundleVersion 21 | $(CURRENT_PROJECT_VERSION) 22 | NSPrincipalClass 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /opengl_example.xcodeproj/AppBase_Info_ios.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CFBundleDevelopmentRegion 5 | en 6 | CFBundleExecutable 7 | $(EXECUTABLE_NAME) 8 | CFBundleIdentifier 9 | $(PRODUCT_BUNDLE_IDENTIFIER) 10 | CFBundleInfoDictionaryVersion 11 | 6.0 12 | CFBundleName 13 | $(PRODUCT_NAME) 14 | CFBundlePackageType 15 | FMWK 16 | CFBundleShortVersionString 17 | 1.0 18 | CFBundleSignature 19 | ???? 20 | CFBundleVersion 21 | $(CURRENT_PROJECT_VERSION) 22 | NSPrincipalClass 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /opengl_example.xcodeproj/Info_ios.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UIRequiredDeviceCapabilities 24 | 25 | armv7 26 | 27 | UIStatusBarHidden 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /opengl_example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 52; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 35BCE6C7229D70D30097A61A /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* main.swift */; }; 11 | 4F21F0352A75513300C6F659 /* GLApplication in Frameworks */ = {isa = PBXBuildFile; productRef = 4F21F0342A75513300C6F659 /* GLApplication */; }; 12 | D21C37C4207DFA790074470D /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = D21C37C3207DFA790074470D /* Default-568h@2x.png */; }; 13 | D24EFDC125CF2900001BB280 /* SwiftMath in Frameworks */ = {isa = PBXBuildFile; productRef = D24EFDC025CF2900001BB280 /* SwiftMath */; }; 14 | D24EFDD425CF2C17001BB280 /* SwiftMath in Frameworks */ = {isa = PBXBuildFile; productRef = D24EFDD325CF2C17001BB280 /* SwiftMath */; }; 15 | D24EFDE025CF316A001BB280 /* GLApplication in Frameworks */ = {isa = PBXBuildFile; productRef = D24EFDDF25CF316A001BB280 /* GLApplication */; }; 16 | D266351D1FF82A6F00E5BDAF /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* App.swift */; }; 17 | D266351E1FF82A6F00E5BDAF /* Cube.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* Cube.swift */; }; 18 | D266351F1FF82A6F00E5BDAF /* Geometry.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_22 /* Geometry.swift */; }; 19 | D26635211FF82A6F00E5BDAF /* Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_24 /* Scene.swift */; }; 20 | D26635221FF82A6F00E5BDAF /* Shader.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_25 /* Shader.swift */; }; 21 | D26A51CF25CF27B000B0EFD3 /* String_extention.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26A51CE25CF27B000B0EFD3 /* String_extention.swift */; }; 22 | D26A51D025CF27B000B0EFD3 /* String_extention.swift in Sources */ = {isa = PBXBuildFile; fileRef = D26A51CE25CF27B000B0EFD3 /* String_extention.swift */; }; 23 | OBJ_43 /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_20 /* App.swift */; }; 24 | OBJ_44 /* Cube.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_21 /* Cube.swift */; }; 25 | OBJ_45 /* Geometry.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_22 /* Geometry.swift */; }; 26 | OBJ_47 /* Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_24 /* Scene.swift */; }; 27 | OBJ_48 /* Shader.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_25 /* Shader.swift */; }; 28 | OBJ_49 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* main.swift */; }; 29 | /* End PBXBuildFile section */ 30 | 31 | /* Begin PBXCopyFilesBuildPhase section */ 32 | 35BCE6C5229D6F950097A61A /* CopyFiles */ = { 33 | isa = PBXCopyFilesBuildPhase; 34 | buildActionMask = 2147483647; 35 | dstPath = ""; 36 | dstSubfolderSpec = 10; 37 | files = ( 38 | ); 39 | runOnlyForDeploymentPostprocessing = 0; 40 | }; 41 | /* End PBXCopyFilesBuildPhase section */ 42 | 43 | /* Begin PBXFileReference section */ 44 | D21C37C3207DFA790074470D /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 45 | D22B30DB1FF828D0005D5394 /* iOS_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOS_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | D26A51CE25CF27B000B0EFD3 /* String_extention.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = String_extention.swift; sourceTree = ""; }; 47 | D2DF327625BC43E5002AA42F /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 48 | OBJ_20 /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; }; 49 | OBJ_21 /* Cube.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cube.swift; sourceTree = ""; }; 50 | OBJ_22 /* Geometry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Geometry.swift; sourceTree = ""; }; 51 | OBJ_24 /* Scene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scene.swift; sourceTree = ""; }; 52 | OBJ_25 /* Shader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shader.swift; sourceTree = ""; }; 53 | OBJ_26 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; 54 | OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; 55 | "opengl_example::app::Product" /* app */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; path = app; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | /* End PBXFileReference section */ 57 | 58 | /* Begin PBXFrameworksBuildPhase section */ 59 | D22B30D81FF828D0005D5394 /* Frameworks */ = { 60 | isa = PBXFrameworksBuildPhase; 61 | buildActionMask = 2147483647; 62 | files = ( 63 | 4F21F0352A75513300C6F659 /* GLApplication in Frameworks */, 64 | D24EFDD425CF2C17001BB280 /* SwiftMath in Frameworks */, 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | OBJ_50 /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 0; 71 | files = ( 72 | D24EFDE025CF316A001BB280 /* GLApplication in Frameworks */, 73 | D24EFDC125CF2900001BB280 /* SwiftMath in Frameworks */, 74 | ); 75 | runOnlyForDeploymentPostprocessing = 0; 76 | }; 77 | /* End PBXFrameworksBuildPhase section */ 78 | 79 | /* Begin PBXGroup section */ 80 | D22B30D51FF828AA005D5394 /* Frameworks */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | ); 84 | name = Frameworks; 85 | sourceTree = ""; 86 | }; 87 | OBJ_19 /* app */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | OBJ_20 /* App.swift */, 91 | OBJ_21 /* Cube.swift */, 92 | OBJ_22 /* Geometry.swift */, 93 | OBJ_24 /* Scene.swift */, 94 | OBJ_25 /* Shader.swift */, 95 | OBJ_26 /* main.swift */, 96 | D26A51CE25CF27B000B0EFD3 /* String_extention.swift */, 97 | ); 98 | name = app; 99 | path = Sources/app; 100 | sourceTree = SOURCE_ROOT; 101 | }; 102 | OBJ_27 /* Tests */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | ); 106 | name = Tests; 107 | sourceTree = SOURCE_ROOT; 108 | }; 109 | OBJ_28 /* Products */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | "opengl_example::app::Product" /* app */, 113 | D22B30DB1FF828D0005D5394 /* iOS_example.app */, 114 | ); 115 | name = Products; 116 | sourceTree = BUILT_PRODUCTS_DIR; 117 | }; 118 | OBJ_5 = { 119 | isa = PBXGroup; 120 | children = ( 121 | D21C37C3207DFA790074470D /* Default-568h@2x.png */, 122 | D2DF327625BC43E5002AA42F /* README.md */, 123 | OBJ_6 /* Package.swift */, 124 | OBJ_7 /* Sources */, 125 | OBJ_27 /* Tests */, 126 | OBJ_28 /* Products */, 127 | D22B30D51FF828AA005D5394 /* Frameworks */, 128 | ); 129 | sourceTree = ""; 130 | }; 131 | OBJ_7 /* Sources */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | OBJ_19 /* app */, 135 | ); 136 | name = Sources; 137 | sourceTree = SOURCE_ROOT; 138 | }; 139 | /* End PBXGroup section */ 140 | 141 | /* Begin PBXNativeTarget section */ 142 | D22B30DA1FF828D0005D5394 /* iOS_example */ = { 143 | isa = PBXNativeTarget; 144 | buildConfigurationList = D22B30EA1FF828D1005D5394 /* Build configuration list for PBXNativeTarget "iOS_example" */; 145 | buildPhases = ( 146 | D22B30D71FF828D0005D5394 /* Sources */, 147 | D22B30D81FF828D0005D5394 /* Frameworks */, 148 | D22B30D91FF828D0005D5394 /* Resources */, 149 | 35BCE6C5229D6F950097A61A /* CopyFiles */, 150 | ); 151 | buildRules = ( 152 | ); 153 | dependencies = ( 154 | D24EFDD925CF2C23001BB280 /* PBXTargetDependency */, 155 | D24EFDB925CF28B6001BB280 /* PBXTargetDependency */, 156 | ); 157 | name = iOS_example; 158 | packageProductDependencies = ( 159 | D24EFDD325CF2C17001BB280 /* SwiftMath */, 160 | 4F21F0342A75513300C6F659 /* GLApplication */, 161 | ); 162 | productName = iOS_example; 163 | productReference = D22B30DB1FF828D0005D5394 /* iOS_example.app */; 164 | productType = "com.apple.product-type.application"; 165 | }; 166 | "opengl_example::app" /* app */ = { 167 | isa = PBXNativeTarget; 168 | buildConfigurationList = OBJ_39 /* Build configuration list for PBXNativeTarget "app" */; 169 | buildPhases = ( 170 | OBJ_42 /* Sources */, 171 | OBJ_50 /* Frameworks */, 172 | ); 173 | buildRules = ( 174 | ); 175 | dependencies = ( 176 | D24EFDC325CF2908001BB280 /* PBXTargetDependency */, 177 | D24EFDC525CF2908001BB280 /* PBXTargetDependency */, 178 | ); 179 | name = app; 180 | packageProductDependencies = ( 181 | D24EFDC025CF2900001BB280 /* SwiftMath */, 182 | D24EFDDF25CF316A001BB280 /* GLApplication */, 183 | ); 184 | productName = app; 185 | productReference = "opengl_example::app::Product" /* app */; 186 | productType = "com.apple.product-type.tool"; 187 | }; 188 | /* End PBXNativeTarget section */ 189 | 190 | /* Begin PBXProject section */ 191 | OBJ_1 /* Project object */ = { 192 | isa = PBXProject; 193 | attributes = { 194 | LastSwiftUpdateCheck = 0920; 195 | LastUpgradeCheck = 1240; 196 | TargetAttributes = { 197 | D22B30DA1FF828D0005D5394 = { 198 | CreatedOnToolsVersion = 9.2; 199 | DevelopmentTeam = 578DNB2BJ7; 200 | LastSwiftMigration = 1020; 201 | ProvisioningStyle = Automatic; 202 | }; 203 | "opengl_example::app" = { 204 | LastSwiftMigration = 1020; 205 | }; 206 | }; 207 | }; 208 | buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "opengl_example" */; 209 | compatibilityVersion = "Xcode 3.2"; 210 | developmentRegion = en; 211 | hasScannedForEncodings = 0; 212 | knownRegions = ( 213 | en, 214 | Base, 215 | ); 216 | mainGroup = OBJ_5; 217 | packageReferences = ( 218 | D26A51D625CF286D00B0EFD3 /* XCRemoteSwiftPackageReference "SwiftMath" */, 219 | D24EFDDE25CF316A001BB280 /* XCRemoteSwiftPackageReference "GLApplication" */, 220 | ); 221 | productRefGroup = OBJ_28 /* Products */; 222 | projectDirPath = ""; 223 | projectRoot = ""; 224 | targets = ( 225 | "opengl_example::app" /* app */, 226 | D22B30DA1FF828D0005D5394 /* iOS_example */, 227 | ); 228 | }; 229 | /* End PBXProject section */ 230 | 231 | /* Begin PBXResourcesBuildPhase section */ 232 | D22B30D91FF828D0005D5394 /* Resources */ = { 233 | isa = PBXResourcesBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | D21C37C4207DFA790074470D /* Default-568h@2x.png in Resources */, 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | }; 240 | /* End PBXResourcesBuildPhase section */ 241 | 242 | /* Begin PBXSourcesBuildPhase section */ 243 | D22B30D71FF828D0005D5394 /* Sources */ = { 244 | isa = PBXSourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | D26635221FF82A6F00E5BDAF /* Shader.swift in Sources */, 248 | 35BCE6C7229D70D30097A61A /* main.swift in Sources */, 249 | D266351F1FF82A6F00E5BDAF /* Geometry.swift in Sources */, 250 | D26A51D025CF27B000B0EFD3 /* String_extention.swift in Sources */, 251 | D26635211FF82A6F00E5BDAF /* Scene.swift in Sources */, 252 | D266351D1FF82A6F00E5BDAF /* App.swift in Sources */, 253 | D266351E1FF82A6F00E5BDAF /* Cube.swift in Sources */, 254 | ); 255 | runOnlyForDeploymentPostprocessing = 0; 256 | }; 257 | OBJ_42 /* Sources */ = { 258 | isa = PBXSourcesBuildPhase; 259 | buildActionMask = 0; 260 | files = ( 261 | OBJ_43 /* App.swift in Sources */, 262 | OBJ_44 /* Cube.swift in Sources */, 263 | OBJ_45 /* Geometry.swift in Sources */, 264 | D26A51CF25CF27B000B0EFD3 /* String_extention.swift in Sources */, 265 | OBJ_47 /* Scene.swift in Sources */, 266 | OBJ_48 /* Shader.swift in Sources */, 267 | OBJ_49 /* main.swift in Sources */, 268 | ); 269 | runOnlyForDeploymentPostprocessing = 0; 270 | }; 271 | /* End PBXSourcesBuildPhase section */ 272 | 273 | /* Begin PBXTargetDependency section */ 274 | D24EFDB925CF28B6001BB280 /* PBXTargetDependency */ = { 275 | isa = PBXTargetDependency; 276 | productRef = D24EFDB825CF28B6001BB280 /* GLApplication */; 277 | }; 278 | D24EFDC325CF2908001BB280 /* PBXTargetDependency */ = { 279 | isa = PBXTargetDependency; 280 | productRef = D24EFDC225CF2908001BB280 /* GLApplication */; 281 | }; 282 | D24EFDC525CF2908001BB280 /* PBXTargetDependency */ = { 283 | isa = PBXTargetDependency; 284 | productRef = D24EFDC425CF2908001BB280 /* SwiftMath */; 285 | }; 286 | D24EFDD925CF2C23001BB280 /* PBXTargetDependency */ = { 287 | isa = PBXTargetDependency; 288 | productRef = D24EFDD825CF2C23001BB280 /* SwiftMath */; 289 | }; 290 | /* End PBXTargetDependency section */ 291 | 292 | /* Begin XCBuildConfiguration section */ 293 | D22B30EB1FF828D1005D5394 /* Debug */ = { 294 | isa = XCBuildConfiguration; 295 | buildSettings = { 296 | ALWAYS_SEARCH_USER_PATHS = NO; 297 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 298 | CLANG_ANALYZER_NONNULL = YES; 299 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 300 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 301 | CLANG_CXX_LIBRARY = "libc++"; 302 | CLANG_ENABLE_MODULES = YES; 303 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 304 | CLANG_WARN_BOOL_CONVERSION = YES; 305 | CLANG_WARN_COMMA = YES; 306 | CLANG_WARN_CONSTANT_CONVERSION = YES; 307 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 308 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 309 | CLANG_WARN_EMPTY_BODY = YES; 310 | CLANG_WARN_ENUM_CONVERSION = YES; 311 | CLANG_WARN_INFINITE_RECURSION = YES; 312 | CLANG_WARN_INT_CONVERSION = YES; 313 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 314 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 315 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 316 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 317 | CLANG_WARN_STRICT_PROTOTYPES = YES; 318 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 319 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 320 | CLANG_WARN_UNREACHABLE_CODE = YES; 321 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 322 | CODE_SIGN_IDENTITY = "iPhone Developer"; 323 | CODE_SIGN_STYLE = Automatic; 324 | DEVELOPMENT_TEAM = 578DNB2BJ7; 325 | ENABLE_STRICT_OBJC_MSGSEND = YES; 326 | ENABLE_TESTABILITY = YES; 327 | GCC_C_LANGUAGE_STANDARD = gnu11; 328 | GCC_DYNAMIC_NO_PIC = NO; 329 | GCC_NO_COMMON_BLOCKS = YES; 330 | GCC_PREPROCESSOR_DEFINITIONS = ( 331 | "DEBUG=1", 332 | "$(inherited)", 333 | ); 334 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 335 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 336 | GCC_WARN_UNDECLARED_SELECTOR = YES; 337 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 338 | GCC_WARN_UNUSED_FUNCTION = YES; 339 | GCC_WARN_UNUSED_VARIABLE = YES; 340 | INFOPLIST_FILE = opengl_example.xcodeproj/Info_ios.plist; 341 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 342 | LD_RUNPATH_SEARCH_PATHS = ( 343 | "$(inherited)", 344 | "@executable_path/Frameworks", 345 | ); 346 | MTL_ENABLE_DEBUG_INFO = YES; 347 | PRODUCT_BUNDLE_IDENTIFIER = "com.sakrist.iOS-example"; 348 | PRODUCT_NAME = "$(TARGET_NAME)"; 349 | SDKROOT = iphoneos; 350 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 351 | SWIFT_VERSION = 5.0; 352 | TARGETED_DEVICE_FAMILY = "1,2"; 353 | }; 354 | name = Debug; 355 | }; 356 | D22B30EC1FF828D1005D5394 /* Release */ = { 357 | isa = XCBuildConfiguration; 358 | buildSettings = { 359 | ALWAYS_SEARCH_USER_PATHS = NO; 360 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 361 | CLANG_ANALYZER_NONNULL = YES; 362 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 363 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 364 | CLANG_CXX_LIBRARY = "libc++"; 365 | CLANG_ENABLE_MODULES = YES; 366 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 367 | CLANG_WARN_BOOL_CONVERSION = YES; 368 | CLANG_WARN_COMMA = YES; 369 | CLANG_WARN_CONSTANT_CONVERSION = YES; 370 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 371 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 372 | CLANG_WARN_EMPTY_BODY = YES; 373 | CLANG_WARN_ENUM_CONVERSION = YES; 374 | CLANG_WARN_INFINITE_RECURSION = YES; 375 | CLANG_WARN_INT_CONVERSION = YES; 376 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 377 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 378 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 379 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 380 | CLANG_WARN_STRICT_PROTOTYPES = YES; 381 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 382 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 383 | CLANG_WARN_UNREACHABLE_CODE = YES; 384 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 385 | CODE_SIGN_IDENTITY = "iPhone Developer"; 386 | CODE_SIGN_STYLE = Automatic; 387 | COPY_PHASE_STRIP = NO; 388 | DEVELOPMENT_TEAM = 578DNB2BJ7; 389 | ENABLE_NS_ASSERTIONS = NO; 390 | ENABLE_STRICT_OBJC_MSGSEND = YES; 391 | GCC_C_LANGUAGE_STANDARD = gnu11; 392 | GCC_NO_COMMON_BLOCKS = YES; 393 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 394 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 395 | GCC_WARN_UNDECLARED_SELECTOR = YES; 396 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 397 | GCC_WARN_UNUSED_FUNCTION = YES; 398 | GCC_WARN_UNUSED_VARIABLE = YES; 399 | INFOPLIST_FILE = opengl_example.xcodeproj/Info_ios.plist; 400 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 401 | LD_RUNPATH_SEARCH_PATHS = ( 402 | "$(inherited)", 403 | "@executable_path/Frameworks", 404 | ); 405 | MTL_ENABLE_DEBUG_INFO = NO; 406 | PRODUCT_BUNDLE_IDENTIFIER = "com.sakrist.iOS-example"; 407 | PRODUCT_NAME = "$(TARGET_NAME)"; 408 | SDKROOT = iphoneos; 409 | SWIFT_VERSION = 5.0; 410 | TARGETED_DEVICE_FAMILY = "1,2"; 411 | VALIDATE_PRODUCT = YES; 412 | }; 413 | name = Release; 414 | }; 415 | OBJ_3 /* Debug */ = { 416 | isa = XCBuildConfiguration; 417 | buildSettings = { 418 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 419 | CLANG_ENABLE_OBJC_ARC = YES; 420 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 421 | CLANG_WARN_BOOL_CONVERSION = YES; 422 | CLANG_WARN_COMMA = YES; 423 | CLANG_WARN_CONSTANT_CONVERSION = YES; 424 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 425 | CLANG_WARN_EMPTY_BODY = YES; 426 | CLANG_WARN_ENUM_CONVERSION = YES; 427 | CLANG_WARN_INFINITE_RECURSION = YES; 428 | CLANG_WARN_INT_CONVERSION = YES; 429 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 430 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 431 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 432 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 433 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 434 | CLANG_WARN_STRICT_PROTOTYPES = YES; 435 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 436 | CLANG_WARN_UNREACHABLE_CODE = YES; 437 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 438 | COMBINE_HIDPI_IMAGES = YES; 439 | COPY_PHASE_STRIP = NO; 440 | DEBUG_INFORMATION_FORMAT = dwarf; 441 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 442 | ENABLE_NS_ASSERTIONS = YES; 443 | ENABLE_STRICT_OBJC_MSGSEND = YES; 444 | ENABLE_TESTABILITY = YES; 445 | GCC_NO_COMMON_BLOCKS = YES; 446 | GCC_OPTIMIZATION_LEVEL = 0; 447 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 448 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 449 | GCC_WARN_UNDECLARED_SELECTOR = YES; 450 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 451 | GCC_WARN_UNUSED_FUNCTION = YES; 452 | GCC_WARN_UNUSED_VARIABLE = YES; 453 | MACOSX_DEPLOYMENT_TARGET = 10.10; 454 | ONLY_ACTIVE_ARCH = YES; 455 | OTHER_SWIFT_FLAGS = "-DXcode"; 456 | PRODUCT_NAME = "$(TARGET_NAME)"; 457 | SDKROOT = macosx; 458 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; 459 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; 460 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 461 | USE_HEADERMAP = NO; 462 | }; 463 | name = Debug; 464 | }; 465 | OBJ_4 /* Release */ = { 466 | isa = XCBuildConfiguration; 467 | buildSettings = { 468 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 469 | CLANG_ENABLE_OBJC_ARC = YES; 470 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 471 | CLANG_WARN_BOOL_CONVERSION = YES; 472 | CLANG_WARN_COMMA = YES; 473 | CLANG_WARN_CONSTANT_CONVERSION = YES; 474 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 475 | CLANG_WARN_EMPTY_BODY = YES; 476 | CLANG_WARN_ENUM_CONVERSION = YES; 477 | CLANG_WARN_INFINITE_RECURSION = YES; 478 | CLANG_WARN_INT_CONVERSION = YES; 479 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 480 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 481 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 482 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 483 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 484 | CLANG_WARN_STRICT_PROTOTYPES = YES; 485 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 486 | CLANG_WARN_UNREACHABLE_CODE = YES; 487 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 488 | COMBINE_HIDPI_IMAGES = YES; 489 | COPY_PHASE_STRIP = YES; 490 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 491 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 492 | ENABLE_STRICT_OBJC_MSGSEND = YES; 493 | GCC_NO_COMMON_BLOCKS = YES; 494 | GCC_OPTIMIZATION_LEVEL = s; 495 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 496 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 497 | GCC_WARN_UNDECLARED_SELECTOR = YES; 498 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 499 | GCC_WARN_UNUSED_FUNCTION = YES; 500 | GCC_WARN_UNUSED_VARIABLE = YES; 501 | MACOSX_DEPLOYMENT_TARGET = 10.10; 502 | OTHER_SWIFT_FLAGS = "-DXcode"; 503 | PRODUCT_NAME = "$(TARGET_NAME)"; 504 | SDKROOT = macosx; 505 | SUPPORTED_PLATFORMS = "macosx iphoneos iphonesimulator appletvos appletvsimulator watchos watchsimulator"; 506 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = SWIFT_PACKAGE; 507 | SWIFT_COMPILATION_MODE = wholemodule; 508 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 509 | USE_HEADERMAP = NO; 510 | }; 511 | name = Release; 512 | }; 513 | OBJ_40 /* Debug */ = { 514 | isa = XCBuildConfiguration; 515 | buildSettings = { 516 | CODE_SIGN_IDENTITY = "-"; 517 | FRAMEWORK_SEARCH_PATHS = ( 518 | "$(inherited)", 519 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 520 | ); 521 | HEADER_SEARCH_PATHS = "$(inherited)"; 522 | INFOPLIST_FILE = opengl_example.xcodeproj/app_Info.plist; 523 | LD_RUNPATH_SEARCH_PATHS = ( 524 | "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx", 525 | "@executable_path", 526 | ); 527 | MACOSX_DEPLOYMENT_TARGET = 11.0; 528 | OTHER_LDFLAGS = "$(inherited)"; 529 | OTHER_SWIFT_FLAGS = "$(inherited)"; 530 | SWIFT_FORCE_DYNAMIC_LINK_STDLIB = YES; 531 | SWIFT_FORCE_STATIC_LINK_STDLIB = NO; 532 | SWIFT_VERSION = 5.0; 533 | TARGET_NAME = app; 534 | }; 535 | name = Debug; 536 | }; 537 | OBJ_41 /* Release */ = { 538 | isa = XCBuildConfiguration; 539 | buildSettings = { 540 | CODE_SIGN_IDENTITY = "-"; 541 | FRAMEWORK_SEARCH_PATHS = ( 542 | "$(inherited)", 543 | "$(PLATFORM_DIR)/Developer/Library/Frameworks", 544 | ); 545 | HEADER_SEARCH_PATHS = "$(inherited)"; 546 | INFOPLIST_FILE = opengl_example.xcodeproj/app_Info.plist; 547 | LD_RUNPATH_SEARCH_PATHS = ( 548 | "$(TOOLCHAIN_DIR)/usr/lib/swift/macosx", 549 | "@executable_path", 550 | ); 551 | MACOSX_DEPLOYMENT_TARGET = 11.0; 552 | OTHER_LDFLAGS = "$(inherited)"; 553 | OTHER_SWIFT_FLAGS = "$(inherited)"; 554 | SWIFT_FORCE_DYNAMIC_LINK_STDLIB = YES; 555 | SWIFT_FORCE_STATIC_LINK_STDLIB = NO; 556 | SWIFT_VERSION = 5.0; 557 | TARGET_NAME = app; 558 | }; 559 | name = Release; 560 | }; 561 | /* End XCBuildConfiguration section */ 562 | 563 | /* Begin XCConfigurationList section */ 564 | D22B30EA1FF828D1005D5394 /* Build configuration list for PBXNativeTarget "iOS_example" */ = { 565 | isa = XCConfigurationList; 566 | buildConfigurations = ( 567 | D22B30EB1FF828D1005D5394 /* Debug */, 568 | D22B30EC1FF828D1005D5394 /* Release */, 569 | ); 570 | defaultConfigurationIsVisible = 0; 571 | defaultConfigurationName = Debug; 572 | }; 573 | OBJ_2 /* Build configuration list for PBXProject "opengl_example" */ = { 574 | isa = XCConfigurationList; 575 | buildConfigurations = ( 576 | OBJ_3 /* Debug */, 577 | OBJ_4 /* Release */, 578 | ); 579 | defaultConfigurationIsVisible = 0; 580 | defaultConfigurationName = Debug; 581 | }; 582 | OBJ_39 /* Build configuration list for PBXNativeTarget "app" */ = { 583 | isa = XCConfigurationList; 584 | buildConfigurations = ( 585 | OBJ_40 /* Debug */, 586 | OBJ_41 /* Release */, 587 | ); 588 | defaultConfigurationIsVisible = 0; 589 | defaultConfigurationName = Debug; 590 | }; 591 | /* End XCConfigurationList section */ 592 | 593 | /* Begin XCRemoteSwiftPackageReference section */ 594 | D24EFDDE25CF316A001BB280 /* XCRemoteSwiftPackageReference "GLApplication" */ = { 595 | isa = XCRemoteSwiftPackageReference; 596 | repositoryURL = "https://github.com/sakrist/GLApplication.git"; 597 | requirement = { 598 | branch = main; 599 | kind = branch; 600 | }; 601 | }; 602 | D26A51D625CF286D00B0EFD3 /* XCRemoteSwiftPackageReference "SwiftMath" */ = { 603 | isa = XCRemoteSwiftPackageReference; 604 | repositoryURL = "https://github.com/sakrist/SwiftMath"; 605 | requirement = { 606 | branch = "feature/matrix3x3-tests"; 607 | kind = branch; 608 | }; 609 | }; 610 | D2DF328A25BC53AB002AA42F /* XCRemoteSwiftPackageReference "GLAppBase" */ = { 611 | isa = XCRemoteSwiftPackageReference; 612 | repositoryURL = "https://github.com/sakrist/GLAppBase"; 613 | requirement = { 614 | branch = "feature/build-with-spm"; 615 | kind = branch; 616 | }; 617 | }; 618 | /* End XCRemoteSwiftPackageReference section */ 619 | 620 | /* Begin XCSwiftPackageProductDependency section */ 621 | 4F21F0342A75513300C6F659 /* GLApplication */ = { 622 | isa = XCSwiftPackageProductDependency; 623 | package = D24EFDDE25CF316A001BB280 /* XCRemoteSwiftPackageReference "GLApplication" */; 624 | productName = GLApplication; 625 | }; 626 | D24EFDB825CF28B6001BB280 /* GLApplication */ = { 627 | isa = XCSwiftPackageProductDependency; 628 | package = D2DF328A25BC53AB002AA42F /* XCRemoteSwiftPackageReference "GLAppBase" */; 629 | productName = GLApplication; 630 | }; 631 | D24EFDC025CF2900001BB280 /* SwiftMath */ = { 632 | isa = XCSwiftPackageProductDependency; 633 | package = D26A51D625CF286D00B0EFD3 /* XCRemoteSwiftPackageReference "SwiftMath" */; 634 | productName = SwiftMath; 635 | }; 636 | D24EFDC225CF2908001BB280 /* GLApplication */ = { 637 | isa = XCSwiftPackageProductDependency; 638 | package = D2DF328A25BC53AB002AA42F /* XCRemoteSwiftPackageReference "GLAppBase" */; 639 | productName = GLApplication; 640 | }; 641 | D24EFDC425CF2908001BB280 /* SwiftMath */ = { 642 | isa = XCSwiftPackageProductDependency; 643 | package = D26A51D625CF286D00B0EFD3 /* XCRemoteSwiftPackageReference "SwiftMath" */; 644 | productName = SwiftMath; 645 | }; 646 | D24EFDD325CF2C17001BB280 /* SwiftMath */ = { 647 | isa = XCSwiftPackageProductDependency; 648 | package = D26A51D625CF286D00B0EFD3 /* XCRemoteSwiftPackageReference "SwiftMath" */; 649 | productName = SwiftMath; 650 | }; 651 | D24EFDD825CF2C23001BB280 /* SwiftMath */ = { 652 | isa = XCSwiftPackageProductDependency; 653 | package = D26A51D625CF286D00B0EFD3 /* XCRemoteSwiftPackageReference "SwiftMath" */; 654 | productName = SwiftMath; 655 | }; 656 | D24EFDDF25CF316A001BB280 /* GLApplication */ = { 657 | isa = XCSwiftPackageProductDependency; 658 | package = D24EFDDE25CF316A001BB280 /* XCRemoteSwiftPackageReference "GLApplication" */; 659 | productName = GLApplication; 660 | }; 661 | /* End XCSwiftPackageProductDependency section */ 662 | }; 663 | rootObject = OBJ_1 /* Project object */; 664 | } 665 | -------------------------------------------------------------------------------- /opengl_example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /opengl_example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /opengl_example.xcodeproj/xcshareddata/xcschemes/app.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 45 | 51 | 52 | 53 | 54 | 60 | 62 | 68 | 69 | 70 | 71 | 73 | 74 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /opengl_example.xcodeproj/xcshareddata/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | SchemeUserState 5 | 6 | opengl_example-Package.xcscheme 7 | 8 | 9 | SuppressBuildableAutocreation 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /screen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/screen1.png -------------------------------------------------------------------------------- /screen2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/screen2.png -------------------------------------------------------------------------------- /screen3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sakrist/Swift_OpenGL_Example/b6bfef2f48e68364e79ca6580c5440ca7a443775/screen3.png --------------------------------------------------------------------------------