Evet arkadaşlar başlıktan da anlaşılacağı üzere bu yazımda sizler ile SDL 2.0.7. (mevcut yayınlanmış son sürüm SDL)’i VS ile Android için oluşturma için gerekli adımlardan bahsedeceğim.
Öncelikle bu yazımda kullandığım kodları ve temel alt yapıyı Matt Style’s ın şu yazısından aldığımı söylemem gerek. Kendisi oldukça güzel bir şekilde gerekli adımlardan kısaca bahsetmiş. Ben ona ek olarak SDL 2.0.7. kullanacağım (o 2.0.5’i derlemişti, ufak ta olsa bazı farklılıklar var) ayrıca kullanım esnasında bence işinizi daha fazla kolaylaştıracak bir iki husustan bahsedecek ve Matt’in yazısında çok açık olarak ifade etmediğini düşündüğüm bir iki noktaya değineceğim. Bu ve benzeri yazılarımda yapılması gerekenleri uzun uzadıya açıklamaktansa madde madde anlatmayı tercih edeceğim. VS ve NDK ile ilgili genel bilgiler için bir önceki yazımı okumanızı tavsiye ediyorum.
Giriş
- Masaüstü SDL uygulamalarından farklı (bunlar için ilgili kütüphaneleri direk ekleyip yazılımlarınız oluşturabilirsiniz) olarak android için SDL kullanmak için bir kaç nokta var göz önünde bulundurulması gereken:
- NDK’de SDL native bir uygulama olarak değil bir Java aktivitesi ile haberleşerek kullanılmakta (donanım olayları ve girdilerini alabilmek için)
- Örnek bir şablon her SDL sürümü ile yazarlar tarafından sunuluyor ama büyük değişiklikler olabiliyor (2.0.6 da olduğu gibi). O sebeple yeni SDL’e geçmeden önce bu değişiklikleri incelemeniz faydalı olabilir,
- Temel olarak üç adet VS projesine ihtiyacınız var:
- Bir basit android java uygulaması. Bu sizin cihaza yüklenecek olan android uygulamanızı oluşturacak.
- SDL projesi. Bunu dinamik kütüphane olarak oluşturup ekleyeceğiz.
- Son olarak native uygulamanız. Bunu da genelde dinamik kütüphane olarak oluşturuyoruz.
SDL 2 Dinamik Kütüphanesini Oluşturma
- Bir VS solution’ı oluşturuyoruz (bir önceki yazımda belirtilen şekilde VS’in kurulduğundan emin olunuz lütfen). İsmine SDL2_Vs diyebilirsiniz.
- New Project -> Installed -> Templates -> Visual C++ -> Cross Platform -> Android -> Dynamic Shared Library (Android) projesi oluşturup ismine SDL2 diyebilirsiniz.
- Precompiled header’ları ve otomatik gelen dosyaları kullanmayacağımız için oluşturulan SDL2.h/cpp ve pch.h dosyalarını silin.
- Percompiled header kullanımını kapatın.
- Projenin altında Include ve Source isimli iki dizin oluşturun.
- SDL 2 Sayfasından ilgili kaynak kodları (Source Code başlığı altında) indirin ve bunları bir yere açın.
- Bu dosyalar ile gelen include dizini içeriğini bir önceki adımda oluşturduğumuz Include dizini içerisine kopyalayın.
- Bu dosyalar ile gelen src dizini içeriğini bir önceki adımda oluşturduğumuz Source dizini içerisine kopyalayın ama VS’e henüz eklemeyin.
- Şimdi Source dizini altındaki hangi dosyaları VS’e ekleyeceğimize bakalım. Aslında burada izleyeceğimiz adımları diğer kütüphaneler için de izleyebilirsiniz.
- Öncelikle derleme için gerekli bilgilerin birçoğu Android.mk içerisinde bulunur.
- LOCAL_C_INCLUDES anahtar kelimeleri sizlerin VS içerisine eklemeniz gereken Include dizinlerini belirtir (Property Pages->Configuration Properties->C/C++ -> General -> Additional Include Directories)
- LOCAL_SRC_FILES anahtar kelimesi sizlerin VS içerisine eklemeniz gereken C/C++ dosyalarını belirtir. Bunları VS’e eklemeniz gerekmekte. Not. Burada bazen “exclude” kelimeleri kullanılabilir, bu dosyaları eklemeyiniz.
- LOCAL_CFLAGS anahtar kelimesi derleme ayarlarını ifade eder ve genelde Linux makefile için kullandıklarınıza benzerlik gösterirler. Ör. -D ile başlayanları (Property Pages->Configuration Properties->C/C++ -> Preprocessor -> Preprocessor Definitions altına ekleyiniz.
- LOCAL_LDFLAGS anahtar kelimesi linker kapsamında eklenmesi gereken kütüphaneleri belirtir. (Property Pages->Configuration Properties->Linker -> Input -> Additional Dependencies) altına ekleyiniz. Ayrıca matematik ve android kütüphanelerini de eklemelisiniz.
- Tabi bütün anahtar kelimeler bu kadar değil. Diğerlerini öğrenmek için https://developer.android.com/ndk/guides/android_mk.html sayfasına başvurabilirsiniz.
- Bütün bunların yanında bir önceki yazımda bahsettiğim STL, derleyici ve C++ ayarlarını da orada belirttiğim şekilde yapmanızı öneririm (derleyici => CLang, STL => LLVM Shared STL (libc).
- Bu ayarları bütün platform ve konfigürasyon seçenekleri için de yapmayı unutmayınız.
- Bütün bunları yaptıktan sonra ilgili projeyi derlediğinizde libSDL2.so dosyasının oluştuğunu göreceksiniz.
- Aşağıda bu adımlara ilişkin ekran görüntülerini görebilirsiniz:
-
- Şimdi SDL kodlarını bu projeye ekleyeceğiz.
Android Uygulamasını Oluşturma
- New Project -> Installed -> Templates -> Visual C++ -> Cross Platform -> Android -> Basic Application (Android, Ant) projesi oluşturup ismine SDL2_Application diyebilirsiniz.
- Bu uygulama içerisine ekleyeceğimiz Java tabanlı aktivite bizim native kodumuz çağırıyor olacak.
- Öncelikle VS’den yeni oluşturduğumuz projenin üzerine gelip References’i seçip SDL2 yi ekleyelim. Bu bir önceki başlıkta oluşturduğumuz SDL2 nin android paketi içerisine eklenmesini sağlayacak.
- Şimdi daha önce kodlarını indirdiğimiz SDL 2.0.7 dizinine gidip içerisinde bulunan android-project dizinine gidiyoruz. Buradaki bütün dosyaları yeni oluşturduğumuz proje içerisinde bulunan src dizinine kopyalıyoruz. Bu dizin içerisinde bir android uygulaması için gereken bütün dosyalar bulunmakta. Daha sonra VS içerisinden bütün dosyaları göster seçeneğini seçip jni dışındaki bütün dizin ve dosyaları ekleyelim.
- org/libsdl/app altında bulunan SDL/SDLActivity, SDLAudioManager, SDLControllerManager.java dosyalarını ve res dizini altındaki dosya ve dizinlerin eklendiğinden emin olunuz.
- src/com/SDL2_Application altında oluşturulan SDL2_Application.java dosyasının içeriğini aşağıdaki gibi güncelleyiniz. Bu bizim native SDL aktivitesinin çalışmasını sağlayacak olan kodu içermekte.
-
1234567891011121314package com.SDL2_Application;import android.os.Bundle;import org.libsdl.app.SDLActivity;public class SDL2_Application extends SDLActivity{/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);}}
- Nihayetinde aşağıdaki gibi bir proje yapısı elde ediyor olmalısınız.
- Burada AndroidManifest.xml içerisinde bulunan <activity andrroid:name=”SDL2_Application” isminin aktive ismi ile aynı olduğundan emin olunuz.
SDL 2 Kullanan Uygulamanızın Oluşturulması
- Evet, SDL i oluşturduk, Android uygulamasını oluşturduk. Şimdi geldi sıra kendi uygulamamıza.
- Yukarıda da bahsettiğim gibi kendi uygulamamızı da Dynamic Shared Library olarak ekliyoruz.
- New Project -> Installed -> Templates -> Visual C++ -> Cross Platform -> Android -> Dynamic Shared Library (Android) projesi oluşturup ismine main deyiniz.
- SDL varsayılan olarak main dinamik kütüphanesinin yüklenmesini bekliyor android içerisinde ama bunu değiştirebilirsiniz. Ben genelde ellemiyorum ama değiştirmek için SDLActivity.java dosyası içerisindeki 100. satırın oralarda yüklenecek olan kütüphaneler gösterilmiş oradaki main i istediğiniz isim ile değiştirebilirsiniz. Bu arada bu yazımda bahsetmedim ama SDL2_Image da kullanacak iseniz buradan ilgili commentli satırın commentini kaldırmanız gerekmekte.
- Precompiled header’ları ve otomatik gelen dosyaları kullanmayacağımız için oluşturulan SDL2.h ve pch.h dosyalarını silin.
- Percompiled header kullanımını kapatın.
- SDL2’nin Include dizinini (Property Pages->Configuration Properties->C/C++ -> General -> Additional Include Directories) ayarları üzerinden ekleyin,
- Benzer şekilde dinamik kütüphane olarak oluşturduğumuz SDL2 kütüphanesinin bulunduğu dizini linker ayarları üzerinden ekleyiniz ve sonrasında SDL2 Input kısmına ekleyiniz.
-
- Main.cpp içerisini temizleyin ve aşağıdaki örnek kodu ekleyin
-
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081#include <SDL.h>#include <GLES/gl.h>#include <GLES/glext.h>#include <SDL_opengl.h>#include <jni.h>#include <android/asset_manager.h>#include <android/asset_manager_jni.h>#include <string>int main(int argc, char** argsv){//put your SDL / game code hereSDL_Window *window; // Declare a pointerSDL_Init(SDL_INIT_VIDEO); // Initialize SDL2SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);// Turn on double buffering with a 24bit Z buffer.// May need to change this to 16 or 32SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);// Create an application window with the following settings:window = SDL_CreateWindow("An SDL 2.0.7", // window titleSDL_WINDOWPOS_UNDEFINED, // initial x positionSDL_WINDOWPOS_UNDEFINED, // initial y position640, // width, in pixels480, // height, in pixelsSDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN | SDL_WINDOW_BORDERLESS);// Check that the window was successfully createdif (window == NULL) {// In the case that the window could not be made...printf("Could not create window: %s\n", SDL_GetError());return 1;}// Create our opengl contex t and attach it to our windowvoid* mMainGLContext = SDL_GL_CreateContext(window);glClearColor(0, 0, 0, 0);glEnable(GL_CULL_FACE);glShadeModel(GL_SMOOTH);glEnable(GL_DEPTH_TEST);//Initialize Projection MatrixglMatrixMode(GL_PROJECTION);glLoadIdentity();//Initialize Modelview MatrixglMatrixMode(GL_MODELVIEW);glLoadIdentity();while (true){glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glClearColor(255, 0, 0, 255);SDL_GL_SwapWindow(window);}SDL_Delay(3000); // Pause execution for 3000 milliseconds, for example// Close and destroy the windowSDL_DestroyWindow(window);// Clean upSDL_Quit();return 0;}
- Burada eklemiş olduğumuz kod bizim uygulamamızın kodu olacak (Örnek olarak eklenmiş kodta basit bir OpenGL contexti oluşturulmakta ve arka plan kırmızı olarak boyanmaktadır). Uygulama çalıştırılıp SDL ilklendirmeleri bittikten sonra bu kısım çağrılıyor olacak. Buradaki main fonksiyonunu çoklu platformlar için uyarlayarak kullanabilirsiniz.
- Bu projeyi de derlediğiniz zaman main.so dosyası oluşmuş olacak ama işimiz henüz bitmedi.
- Şimdi tekrar SDL2_Application üzerine gelip References’i seçip main i ekleyelim. Bu bizim en son oluşturduğumuz uygulamamızın da android paketi içerisine eklenmesini sağlayacak.
- Evet aktif proje olarak SDL2_Application ı seçip Ctrl + F5 yaptığınız zaman uygulamamız bağlamış olduğunuz emülatör veya mobil cihaz üzerinde çalışmaya başlayacak. Kırmızı bir ekran görmeniz lazım.
Evet arkadaşlar bu adım ile birlikte bundan sonraki SDL projelerinizde kullanabileceğiniz minimum bir SDL uygulama şablonu oluşturmuş olduk. Benzeri şekilde siz de SDL uygulamaları oluşturabilir ya da diğer benzeri C++ kütüphanelerini Andriod için VS de derleyebilirsiniz.
Bu arada son bir not SDL2’yi bir kere bütün platformlar ve konfigürasyonlar için derledikten sonra sizlere önerim bu kütüphaneleri NDK Yazımda bahsettiğim şekilde libs üzerinden uygulamanıza dahil etmeniz. Bazı durumlarda (ben oldukça sık rastlıyorum) VS her uygulamayı oluşturmaya çalıştığınızda veya yanlışlıkla SDL2 yi tekrar oluştur dediğiniz bütün kodları baştan derlemeye çalışacak ve bu da size baya zaman kaybettirebilir. libs üzerinden ekleyerek bunun önüne geçebilirsiniz.
Bu arada Visual Studio 2017 ile SDL 2.0.7 için hazırlanmış örnek proje ve ilgili kodlara buradan ulaşabilirsiniz. Ayrıca repository içerisindeki SDL2 dizininde oluşturulan kütüphaneleri vereceğiniz dizinlere otomatik kopyalamak için bir script te ekledim (PrepareSDL.bat). İhtiyacınız olabilir 🙂
Kendinize iyi bakın bir sonraki yazıda görüşmek dileğiyle.