GLFM adalah C API untuk pengembangan aplikasi seluler dengan OpenGL ES. Hal ini sebagian besar terinspirasi oleh GLFW.
GLFM berjalan di iOS 9, tvOS 9, Android 4.1 (API 16), dan WebGL 1.0 (melalui Emscripten).
Selain itu, GLFM menyediakan dukungan Metal di iOS dan tvOS.
iOS | TVOS | Android | jaring | |
---|---|---|---|---|
OpenGL ES 2, OpenGL ES 3 | ✔️ | ✔️ | ✔️ | ✔️ |
Logam | ✔️ | ✔️ | T/A | T/A |
Retina / DPI tinggi | ✔️ | ✔️ | ✔️ | ✔️ |
Orientasi perangkat | ✔️ | T/A | ✔️ | |
Sentuh acara | ✔️ | ✔️ | ✔️ | ✔️ |
Peristiwa mouse melayang | ✔️ 1 | ✔️ | ||
Peristiwa roda tikus | ✔️ | |||
Gaya kursor mouse | ✔️ 1 | ✔️ | ||
Peristiwa kode kunci | ✔️ 2 | ✔️ | ✔️ | ✔️ |
Peristiwa penting yang berulang | ✔️ | ✔️ | ||
Peristiwa masukan karakter | ✔️ | ✔️ 3 | ✔️ | ✔️ |
Papan ketik maya | ✔️ | ✔️ | ||
Peristiwa visibilitas keyboard virtual | ✔️ | ✔️ | ||
Akselerometer, magnetometer, giroskop, rotasi perangkat | ✔️ | T/A | ✔️ | |
Umpan balik haptik | ✔️ 4 | T/A | ✔️ | |
papan klip | ✔️ | T/A | ✔️ | ✔️ |
Sisipan Chrome ("area aman") | ✔️ 5 | ✔️ | ✔️ | |
Insets Chrome mengubah peristiwa | ✔️ 5 | ✔️ | ✔️ | |
Fokus acara | ✔️ | ✔️ | ✔️ | ✔️ |
Ubah ukuran acara | ✔️ | ✔️ | ✔️ | ✔️ |
Peristiwa peringatan memori | ✔️ | ✔️ | ✔️ | |
Peristiwa hilangnya konteks OpenGL (permukaan hancur) | ✔️ | ✔️ | ✔️ | ✔️ |
1. Hanya iPad. Memerlukan iOS 13.4 atau lebih baru
2. Membutuhkan iOS/tvOS 13.4 atau lebih baru
3. Membutuhkan tvOS 13.4 atau lebih baru
4. Memerlukan iOS 13 atau lebih baru
5. Membutuhkan iOS/tvOS 11 atau lebih baru
Selain itu, ada dukungan awal untuk macOS dengan OpenGL 3.2. Versi macOS berguna untuk tujuan pengembangan, tetapi bukan kualitas rilis. Tidak ada fungsi untuk mengatur ukuran jendela, misalnya.
GLFM memiliki cakupan terbatas, dan tidak dirancang untuk menyediakan semua yang diperlukan untuk suatu aplikasi. Misalnya, GLFM tidak menyediakan (dan tidak akan pernah menyediakan) hal berikut:
Sebaliknya, GLFM dapat digunakan dengan perpustakaan lintas platform lain yang menyediakan apa yang dibutuhkan aplikasi.
File CMakeLists.txt
disediakan untuk kenyamanan, meskipun CMake tidak diperlukan.
Tanpa CMake:
include
dan src
) ke proyek Anda.void glfmMain(GLFMDisplay *display)
dalam file C/C++. Untuk versi rilis, tentukan NDEBUG
untuk menghapus pernyataan logging yang berlebihan. NDEBUG
secara otomatis ditentukan untuk build rilis di Android Studio, tetapi tidak di Xcode.
Contoh ini menginisialisasi tampilan di glfmMain()
dan menggambar segitiga di onDraw()
. Contoh yang lebih rinci tersedia di sini.
#include "glfm.h"
static GLint program = 0 ;
static GLuint vertexBuffer = 0 ;
static GLuint vertexArray = 0 ;
static void onDraw ( GLFMDisplay * display );
static void onSurfaceDestroyed ( GLFMDisplay * display );
void glfmMain ( GLFMDisplay * display ) {
glfmSetDisplayConfig ( display ,
GLFMRenderingAPIOpenGLES2 ,
GLFMColorFormatRGBA8888 ,
GLFMDepthFormatNone ,
GLFMStencilFormatNone ,
GLFMMultisampleNone );
glfmSetRenderFunc ( display , onDraw );
glfmSetSurfaceDestroyedFunc ( display , onSurfaceDestroyed );
}
static void onSurfaceDestroyed ( GLFMDisplay * display ) {
// When the surface is destroyed, all existing GL resources are no longer valid.
program = 0 ;
vertexBuffer = 0 ;
vertexArray = 0 ;
}
static GLuint compileShader ( const GLenum type , const GLchar * shaderString , GLint shaderLength ) {
GLuint shader = glCreateShader ( type );
glShaderSource ( shader , 1 , & shaderString , & shaderLength );
glCompileShader ( shader );
return shader ;
}
static void onDraw ( GLFMDisplay * display ) {
if ( program == 0 ) {
const GLchar vertexShader [] =
"#version 100n"
"attribute highp vec4 position;n"
"void main() {n"
" gl_Position = position;n"
"}" ;
const GLchar fragmentShader [] =
"#version 100n"
"void main() {n"
" gl_FragColor = vec4(0.85, 0.80, 0.75, 1.0);n"
"}" ;
program = glCreateProgram ();
GLuint vertShader = compileShader ( GL_VERTEX_SHADER , vertexShader , sizeof ( vertexShader ) - 1 );
GLuint fragShader = compileShader ( GL_FRAGMENT_SHADER , fragmentShader , sizeof ( fragmentShader ) - 1 );
glAttachShader ( program , vertShader );
glAttachShader ( program , fragShader );
glLinkProgram ( program );
glDeleteShader ( vertShader );
glDeleteShader ( fragShader );
}
if ( vertexBuffer == 0 ) {
const GLfloat vertices [] = {
0.0 , 0.5 , 0.0 ,
-0.5 , -0.5 , 0.0 ,
0.5 , -0.5 , 0.0 ,
};
glGenBuffers ( 1 , & vertexBuffer );
glBindBuffer ( GL_ARRAY_BUFFER , vertexBuffer );
glBufferData ( GL_ARRAY_BUFFER , sizeof ( vertices ), vertices , GL_STATIC_DRAW );
}
int width , height ;
glfmGetDisplaySize ( display , & width , & height );
glViewport ( 0 , 0 , width , height );
glClearColor ( 0.08f , 0.07f , 0.07f , 1.0f );
glClear ( GL_COLOR_BUFFER_BIT );
#if defined( GL_VERSION_3_0 ) && GL_VERSION_3_0
if ( vertexArray == 0 ) {
glGenVertexArrays ( 1 , & vertexArray );
}
glBindVertexArray ( vertexArray );
#endif
glUseProgram ( program );
glBindBuffer ( GL_ARRAY_BUFFER , vertexBuffer );
glEnableVertexAttribArray ( 0 );
glVertexAttribPointer ( 0 , 3 , GL_FLOAT , GL_FALSE , 0 , 0 );
glDrawArrays ( GL_TRIANGLES , 0 , 3 );
glfmSwapBuffers ( display );
}
Lihat glfm.h
Gunakan cmake
untuk menghasilkan proyek Xcode:
cmake -D GLFM_BUILD_EXAMPLES=ON -B build/apple -G Xcode
open build/apple/GLFM.xcodeproj
Di Xcode, beralih ke target glfm_touch
dan jalankan di simulator atau perangkat.
Gunakan emcmake
untuk menyetel variabel lingkungan untuk cmake
, lalu buat:
emcmake cmake -D GLFM_BUILD_EXAMPLES=ON -B build/emscripten && cmake --build build/emscripten
Kemudian jalankan secara lokal:
emrun build/emscripten/examples
Atau jalankan contoh spesifik:
emrun build/emscripten/examples/glfm_touch.html
Tidak ada generator CMake untuk proyek Android Studio, tetapi Anda dapat menyertakan CMakeLists.txt
dalam proyek baru atau yang sudah ada.
[path/to/glfm]/build/android
dan tekan "Selesai".AndroidManifest.xml
, tambahkan
utama seperti: xml version = " 1.0 " encoding = " utf-8 " ?>
< manifest xmlns : android = " http://schemas.android.com/apk/res/android " >
< uses-feature android : glEsVersion = " 0x00020000 " android : required = " true " />
< application
android : allowBackup = " true "
android : icon = " @mipmap/ic_launcher "
android : label = " @string/app_name "
android : supportsRtl = " true " >
< activity android : name = " android.app.NativeActivity "
android : exported = " true "
android : configChanges = " orientation|screenLayout|screenSize|keyboardHidden|keyboard " >
< meta-data
android : name = " android.app.lib_name "
android : value = " glfm_touch " />
< intent-filter >
< action android : name = " android.intent.action.MAIN " />
< category android : name = " android.intent.category.LAUNCHER " />
intent-filter >
activity >
application >
manifest >
app/build.gradle
, tambahkan bagian externalNativeBuild
dan sourceSets.main
seperti: apply plugin : ' com.android.application '
android {
compileSdkVersion 34
ndkVersion ' 23.2.8568313 ' // Last version to support API 16, 17, 18
defaultConfig {
applicationId " com.brackeen.glfmexample "
minSdkVersion 16
targetSdkVersion 34
versionCode 1
versionName " 1.0 "
// Add externalNativeBuild in defaultConfig (1/2)
externalNativeBuild {
cmake {
arguments " -DGLFM_BUILD_EXAMPLES=ON "
}
}
}
// Add sourceSets.main and externalNativeBuild (2/2)
sourceSets . main {
assets . srcDirs = [ " ../../../examples/assets " ]
}
externalNativeBuild {
cmake {
path " ../../../CMakeLists.txt "
}
}
namespace ' com.brackeen.glfmexample '
}
glfmMain
atau dari fungsi panggilan balik). IDE apa yang harus saya gunakan? Mengapa tidak ada implementasi desktop? Gunakan Xcode atau Android Studio. Untuk desktop, gunakan GLFW dengan IDE pilihan Anda.
Jika Anda memilih untuk tidak menggunakan simulator seluler untuk pengembangan sehari-hari, solusi yang baik adalah menggunakan GLFW, lalu porting aplikasi Anda ke GLFM. Tidak semua panggilan OpenGL akan di-porting ke OpenGL ES dengan sempurna, namun untuk portabilitas OpenGL yang maksimal, gunakan OpenGL 3.2 Core Profile di desktop dan OpenGL ES 2.0 di seluler.
Mengapa titik masuknya glfmMain()
dan bukan main()
?
Jika tidak, ini tidak akan berfungsi di iOS. Untuk menginisialisasi lingkungan Objective-C, fungsi main()
harus membuat kumpulan rilis otomatis dan memanggil fungsi UIApplicationMain()
, yang tidak pernah mengembalikan . Di iOS, GLFM tidak memanggil glfmMain()
hingga UIApplicationDelegate
dan UIViewController
diinisialisasi.
Mengapa GLFM digerakkan oleh peristiwa? Mengapa GLFM mengambil alih loop utama?
Jika tidak, ini tidak akan berfungsi di iOS (lihat di atas) atau di HTML5, yang digerakkan oleh peristiwa.