[Duyuru] sdl-painter

Evet, sevgili yazılımperver dostlarım, hatırlarsanız, bir süredir daha basit projeler ile SDL3, CI/CD ve benzeri konulara bakıyor ve cpp-playground reposu üzerinden bunları deniyorduk. Açıkçası o çalışmaları güzel bir noktaya getirdik. Şimdi orada gördüğümüz kavram ve araçları bir sonraki noktaya taşıma vakti geldi. Uzun süredir, hazırlıklarını yaptığım kütüphane, nihayet belirli bir olgunluğa erişti ve artık yeni bir sayfaya geçiyoruz.

Bu doğrultuda da, görselleştirmeye yönelik işler için artık SDLPainter olarak isimlendirdiğim yeni bir proje ile devam etmeye karar verdim.
Neden, sıfırdan böyle bir işe giriştim? Aslında tam olarak sıfırdan diyemeyiz. Daha önce bir çok kez benzeri geliştirme işlerini yaptık, en son uEngine4 ile de uygulama geliştirebiliyorduk.
Bununla birlikte, güncel araçlar ile kütüphane ve araçları hızlı bir şekilde geliştirme olanakları ortaya çıktı. Tahmin edebileceğiniz üzere, elimizin altında olan LLM araçlarının da katkısı büyük 🙂
Bu yazılarımda ve kütüphanemde olabildiğince onlardan faydalanacağım.
Sonuç olarak bu kütüphaneyi biraz daha SDL3’e odaklı yapmak istedim.

SDLPainter nedir?

SDLPainter, Qt’un QPainter sınıfından ilham alan, SDL3 ve OpenGL 3.3 (ve dahi Vulkan) üzerine inşa edilmiş, modern C++ kullanan bir 2B çizim kütüphanesidir.
Temel amacı, bir pencereye çizgi, dikdörtgen, daire, poligon ve resim çizmek için temiz, kullanımı kolay bir API/kütüphane sunmak.
Peki neden QPainter? Tekerleği baştan icat etmek yerine, bana göre C++ ile GUI geliştirme için en iyi alternatiflerden olan Qt’ye bakmak daha anlamlı geldi. Elbette, bu kütüphaneye olan aşinalığımın da bunda etkisi büyük. QPainter’da da, eski OpenGL’dekine benzer bir mantık güdülüyor aslında, bu da işi basitleştiriyor.  begin(), end(), setPen(), setBrush() gibi birkaç satırla ekrana 2B şekiller çizebiliyorsunuz. Bu API’lerin arkasındaki işlevleri Qt hallediyor.
SDL dünyasında, gördüğüm kadarıyla böyle bir kütüphane yok; ben de buraya katkıda bulunmak istedim. SDLPainter da, işte tam olarak bu boşluğu doldurmak için, hem 2B oyun prototiplerinde hem de araç geliştirirken işe yarayacağını düşünüyorum.
Daha önce gerek uEngine ile daha eskiden de yine benzer uEngine kütüphaneleri ile aslında altyapıyı baya hazırladık. Bunu modern C++ pratikleri ile de birleştirip böyle bir kütüphanenin oluşturulmasının faydalı olacağına inandım. Ayrıca 2B çizime yönelik de çeşitli ihtiyaçlarım oluyordu, bu kütüphaneyi oralarda da kullanacağım. İleride, uEngine’in görselleştirme altyapısını tamamen bu kütüphane ile çözüyor olabiliriz ya da uEngine5’e de geçebiliriz, çünkü neden olmasın.
Bunun yanında, CI/CD, conan, cmake, docker ve benzeri birçok teknolojiyi de, kütüphaneme ekleyerek, azami miktarda kullanmaya gayret edeceğim dostlar, bilginiz olsun. Bu sayede, bütün bu araç ve kabiliyetlerin, pratikte nasıl kullanılabileceğine de şahitlik etmiş olacaksınız.
Bu yazımda bu kütüphaneye yönelik temel hususlara değinmeyi planlıyorum. Biraz uzun olabilir ama benimle kalın lütfen.

Tasarımsal Konular

OpenGL ve arka plan ile ilgilenenler bu başlığa dikkat, diğerleri diğer başlığa geçebilir.
Projenin en önemli kararı backend soyutlaması oldu açıkçası. Önce direk OpenGL ile ilerlemeyi düşünüyordum ama sonra Vulkan’ı da desteklemenin, hem öğrenme hem de ileride esneklik anlamında faydası olacağını düşündüm, bu sebeple ekledim.
Şu an OpenGL 3.3 Core Profile ve Vulkan 1.1’i backend olarak kullanıyorum. Bunu gerçekleştirmek adına IRenderer adında soyut bir arayüz ekledim. Genel kullanım mimarisi aşağıdaki gibi:
SDLPainter (Public API)
  → Transform Stack / State
    → Shape Tessellator (backend-agnostic vertex üretimi)
      → IRenderer (soyut arayüz)
        → OpenGLRenderer  | VulkanRenderer
          → SDL3 Platform Layer
Tessellator sınıfı temelde şekilleri vertex’lere dönüştürüyor ve backend’den tamamen bağımsız. Hem OpenGL hem de Vulkan ile kullanılabilecek. Aşağıda mimarinin daha detaylı görünümünü bulabilirsiniz (detaylar için https://github.com/yazilimperver/sdl-painter/blob/main/doc/mimari-genel-bakis.md)

Çizim altyapısına yönelik konular:
  • glLineWidth kullanmıyorum: OpenGL’de glLineWidth ile kalın çizgi çizmek platformdan platforma değişebildiği için, bu API direk kullanılmıyor, tavsiye de edilmiyor. Bunun yerine geometri tabanlı quad çizim yaklaşımı kullanılıyor (çizginin yönüne dik normal hesaplayıp her iki yöne kalınlığın yarısı kadar genişletiliyor ve  iki üçgenden oluşan bir quad olarak render ediliyor) ki bu kütüphanede de o yaklaşım izlendi.
  • Adaptif segment sayısı: Daire ve elips çizmek için OpenGL’de triangle fan kullanılıyor. Segment sayısı sabit değil, yarıçapa göre değişiyor:
    • Küçük daireler az segment, büyük daireler daha fazla — hem performans hem görsel kaliteyi koruma adına böyle bir yol izliyoruz.
  • Ear Clipping triangulation: Konkav poligonlar için basit triangle fan kullanılamadığı için Tessellator sınıfı içinde ear clipping algoritması implement edildi.
  • GLM yok (şimdilik), kendi transform matrisimiz var. Transform stack için 3×3 affine matris kullanılıyor. uEngine’de glm kullanıyordum, buraya da ekleyeceğim ama acil değil.
  • Resim/Doku yükleme kütüphanesi: Bir diğer konu doku/texture/imaj dosyalarının okunması için kullanılacak kütüphane. Açıkçası bu zamana kadar hep SDL_Image kullandım. Bu kütüphane için stb_image kütüphanesi kullanacağım.
Bu ve buna benzer konulara yönelik ADR’leri de adr dizini altına ekledim. Bu dizini de inşallah zamanla zenginleştireceğim 🙂

Genel Özellikler

Özellik anlamında, kütüphanede birçok kabiliyet bulunuyor. Aşağıda bunları özetlemeye çalıştım. Ayrıca repo içerisinde de, doc dizini altında, sizlere yol gösterebilecek bir çok dosya mevcut.
Ayrıca, yazılım oluşturma aşamasında doxygen dokümanları da oluşturuluyor.

Çizim Primitifleri

  • Çizgi (DrawLine)
  • Dikdörtgen — stroke ve fill (DrawRect / FillRect)
  • Daire — stroke ve fill (DrawCircle / FillCircle)
  • Elips — stroke ve fill (DrawEllipse / FillEllipse)
  • Çokgen — stroke ve fill (DrawPolygon / FillPolygon)
  • Polyline (DrawPolyline)

Görsel Stiller

  • Pen: renk + kalınlık (geometry-based quad; glLineWidth kullanılmıyor)
  • Brush: dolgu rengi
  • Opacity: global saydamlık [0.0, 1.0]

Transform Stack

  • TranslateRotateScale
  • Save / Restore — QPainter ile birebir aynı semantik
  • ResetTransform
  • 3×3 affine matris

Clipping

  • Scissor-based rect clip (SetClipRect / ClearClip)

Image / Texture

  • PNG ve JPG yükleme (stb_image)
  • Tam kaynak rect → hedef rect ölçekleme
  • Alpha blending desteği

Metin Çizimi

  • SDL_ttf 3.x üzerinden font yükleme
  • Glyph cache
  • Alignment: left / center / right
  • Rect içine metin yerleştirme

Tessellator

  • Backend’den bağımsız vertex üretimi
  • Daire/elips için adaptif segment sayısı: max(16, int(radius * 0.5f))
  • Konkav çokgenler için ear clipping triangulation

Render Batcher

Her çizim çağrısı doğrudan GPU’ya gönderilmiyor; RenderBatcher vertex’leri bir arabellekte biriktiriyor ve yalnızca mod, texture veya opacity değiştiğinde (ya da 8192 vertex limiti dolduğunda) Flush() ile toplu olarak renderer’a iletiyor. Bu yaklaşım, özellikle çok sayıda küçük şeklin ard arda çizildiği sahnelerde draw call sayısını ciddi ölçüde azaltıyor. İhtiyacımız olacak 😉

Backend Desteği

  • OpenGL 3.3 Core — GLAD loader, GLSL shader’lar
  • Vulkan 1.1 — SPIR-V pipeline (Phase 5, opsiyonel)
  • IRenderer arayüzü — yeni backend eklemek için tek implementasyon noktası

Platform Desteği

  • Linux (GCC / Clang, Ninja)
  • Windows (MSVC, Visual Studio 2022)
  • Linux container içinde Windows cross-compile (MinGW-w64), ayrıca windows için native container

Altyapı

  • CMake Presets’ler Mevcut (7 preset: linux-debuglinux-releaselinux-debug-asanwindows-debugwindows-releasewindows-mingw-debugwindows-mingw-release)
  • Conan 2 bağımlılık yönetimi — opsiyonel Vulkan bağımlılıkları
  • Docker multi-stage: geliştirme / headless CI / cross-compile / native window
    • CI/CD’yi hızlandırmak adına conan install adımları da bu imajlar içerisine eklendi
    • Gitlab Container Registry kullanımı
    • Github actions için ise Docker Hub kullanımı
  • GitLab + Github CI/CD: build → test → quality (clang-format zorunlu, clang-tidy soft)
  • AddressSanitizer + UBSan preset (linux-debug-asan)
  • Google C++ Style, clang-format-18

API Nasıl Görünüyor?

API’nin detaylarına sonraki yazılarımda gireceğim ama burada yine de bir göz atmakta sakınca yok bence.

Eğer Qt’yi kullandıysanız, bu API’yi hemen tanıyabilirsiniz 🙂
Kütüphaneye yönelik, örneklere examples/ dizini altından ulaşabilirsiniz. Örnekleri şimdilik faz olarak isimlendirdim. Basit kabiliyetlerden, daha kapsamlı kabliyetlere temel özellikleri gösteriyor. İleride bunları zengileştirebiliriz. Önümüzdeki yazılarımda, kabiliyetlere değinirken bunların üzerinden geçeceğim.
Ayrıca, bir yandan da uygulamaları geliştirmeyi planlıyorum. Onlar muhtemelen farklı repolarda olacak.

Yazı Planım

Gelelim bundan sonra, buna yönelik yazılarıma. Yazılarımı, kabiliyetlere göre bölmeye çalışacağım ve bir geliştirici günlüpü notları tadında olacak. Aslında mevcut örnekler de size bu konua fikir verebilir. İlk yazılarım muhtemelen şu başlıklardan oluşacak:

– CMake, Conan 2, Docker ve CI/CD altyapısı (bu da ciddi zaman aldı)
– OpenGL backend + temel primitifler + Renderer Batcher
– Transform stack (save/restore, rotate, scale)
– Image/texture çizimi
– Metin çizimi
– Vulkan backendi
– Örnek uygulamalar
– Android portu
– vb.

Sonuç

Güzel bir yola girmiş olduk. Sizlere ve nihayetinde SDL topluluğuna faydalı olacak bir kütüphane olur inşallah.
Bununla birlikte Modern C++ yazılım geliştirme pratiklerinin de nasıl hayata geçirildiğini gösterme fırsatı sunacağını düşünüyorum.
Her türlü görüş ve önerinizi beklerim. Projenin güncel haline aşağıdaki repodan ulaşabilirsiniz. Şimdilik ağırlıklı gitlab ile ilerleyeceğim (ama github için de CI/CD adımlarını ekledim). Sadece bunlar da değil, SDL3 projelerini derlemek için (hem CI/CD hem de kendi makinelerinizde) çeşitli docker imajları da hazırladım. Gitlab’ın container repository’si ve DockerHub üzerinden bunlara ulaşabilirsiniz. Aşağıdaki adreslerden projelerin repolarına ulaşabilirsiniz:
https://gitlab.com/yazilimperver/sdl-painter
Kütüphaneye yönelik dokümanlar için ise:
ve
adreslerinden ulaşabilirsiniz.
Sonraki yazılarımda görüşmek dileğiyle.
Takipte kalın.

 

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.