SDLPainter 0.1.0
QPainter benzeri SDL3 + OpenGL/Vulkan 2D çizim kütüphanesi
Yüklüyor...
Arıyor...
Eşleşme Yok
SDLPainter — Mimari Genel Bakış

Bu belge SDLPainter'ın katmanlı mimarisini, bileşenler arasındaki bağımlılıkları ve veri akışını üst seviyeden tarif eder. Sınıf detayları için Sınıf Diyagramı, çalışma zamanı akışları için Akış Diyagramları belgelerine bakınız.


1. Katmanlı Mimari

SDLPainter dört bağımsız katmandan oluşur. Her katman yalnızca bir altındaki katmanın arayüzüne bağımlıdır; somut implementasyona değil.

flowchart TB
    subgraph user["Kullanıcı Uygulaması"]
        APP["Demo / Editor / Game"]
    end

    subgraph api["1) Public API Katmanı"]
        PAINTER["Painter<br/>(QPainter benzeri API)"]
        STYLE["Pen / Brush / Color<br/>Transform / Image / Font"]
    end

    subgraph mid["2) Geometri Katmanı (backend-agnostik)"]
        TESS["Tessellator<br/>(şekil → vertex)"]
        STATE["RenderState<br/>(transform stack elemanı)"]
        BATCH["RenderBatcher<br/>(draw call coalescing)"]
    end

    subgraph backend["3) Backend Soyutlama"]
        IRENDER["IRenderer<br/>(saf arayüz)"]
    end

    subgraph impl["4) Backend İmplementasyonları"]
        OGL["OpenGLRenderer<br/>(GLAD + GLSL 330)"]
        VK["VulkanRenderer<br/>(Vulkan 1.1 + SPIR-V)"]
    end

    subgraph plat["Platform Katmanı"]
        SDL["SDL3<br/>(pencere, context, input)"]
        GPU["GPU Sürücüsü"]
    end

    APP --> PAINTER
    PAINTER --> STYLE
    PAINTER --> TESS
    PAINTER --> STATE
    PAINTER --> BATCH
    BATCH --> IRENDER
    TESS -.üretir.-> BATCH
    OGL -.uygular.-> IRENDER
    VK -.uygular.-> IRENDER
    OGL --> SDL
    VK --> SDL
    OGL --> GPU
    VK --> GPU

    classDef apiCls fill:#1f6feb,stroke:#0d3a8c,color:#fff
    classDef midCls fill:#2da44e,stroke:#1a6b30,color:#fff
    classDef backCls fill:#bf8700,stroke:#7a5a00,color:#fff
    classDef implCls fill:#cf222e,stroke:#7a0a14,color:#fff
    classDef platCls fill:#6e7781,stroke:#3a3f44,color:#fff

    class PAINTER,STYLE apiCls
    class TESS,STATE,BATCH midCls
    class IRENDER backCls
    class OGL,VK implCls
    class SDL,GPU platCls

Katmanların Sorumlulukları

Katman Sorumluluk Neyi BİLMEZ
Public API Kullanıcı API'sı, stil ve transform yönetimi GPU, vertex formatı, batch detayı
Geometri Şekilleri vertex'e çevirir, draw call'ları biriktirir OpenGL/Vulkan komutları
Backend Soyutlama Renderer arayüzü (sözleşme) İmplementasyon detayı
Backend İmpl. GPU komutları, shader, buffer, texture Tessellation, stil, transform stack

Bu ayrımın somut etkisi: OpenGLRendererVulkanRenderer ile değiştirmek **sadece constructor argümanını değiştirmek**ten ibarettir. Painter, Tessellator, RenderBatcher, RenderState dosyalarında tek satır değişiklik yapılmaz.


2. Bileşen Bağımlılıkları

Her bileşenin başka hangi bileşenleri kullandığını gösteren bağımlılık grafiği:

graph LR
    Painter --> RenderState
    Painter --> Tessellator
    Painter --> RenderBatcher
    Painter --> IRenderer
    Painter --> Image
    Painter --> Font

    RenderState --> Transform
    RenderState --> Pen
    RenderState --> Brush
    RenderState --> Rect

    Tessellator --> Vertex
    Tessellator --> TexturedVertex
    Tessellator --> Geometry["Point / Rect"]

    RenderBatcher --> IRenderer
    RenderBatcher --> Vertex
    RenderBatcher --> TexturedVertex

    Image --> stbImage["stb_image"]
    Image --> Texture["Texture (RAII)"]
    Texture --> IRenderer

    Font --> SDLttf["SDL_ttf"]
    Font --> Glyph
    Glyph --> Texture

    OpenGLRenderer -.implements.-> IRenderer
    VulkanRenderer -.implements.-> IRenderer
    OpenGLRenderer --> ShaderProgram
    OpenGLRenderer --> SDL3
    VulkanRenderer --> VkContext
    VulkanRenderer --> VkSwapchain
    VulkanRenderer --> VkFrameSync
    VulkanRenderer --> VulkanPipeline
    VulkanRenderer --> VulkanTexturedPipeline
    VulkanRenderer --> SDL3

    style IRenderer fill:#bf8700,color:#fff
    style Painter fill:#1f6feb,color:#fff
    style OpenGLRenderer fill:#cf222e,color:#fff
    style VulkanRenderer fill:#cf222e,color:#fff

Kesintisiz oklar doğrudan kullanım, kesik oklar arayüz uygulaması (implements) ilişkisini gösterir.


3. Veri Akışı: Tek Bir DrawRect Çağrısı

painter.DrawRect(x, y, w, h) çağrısının kütüphane içinde izlediği yol:

flowchart LR
    A["Kullanıcı:<br/>painter.DrawRect(...)"]
    B["RenderState'i oku<br/>(pen, opacity, transform)"]
    C["Tessellator::<br/>TessellateStrokedRect"]
    D["std::vector<Vertex><br/>(4 quad / 8 üçgen)"]
    E["RenderBatcher::<br/>PushTriangles"]
    F{"Mode/opacity<br/>değişti mi?<br/>VEYA buffer<br/>doldu mu?"}
    G["Flush():<br/>renderer.DrawTriangles"]
    H["Buffer'a ekle<br/>(GPU çağrısı YOK)"]
    I["OpenGL/Vulkan<br/>vertex upload + draw"]

    A --> B --> C --> D --> E --> F
    F -- "Hayır" --> H
    F -- "Evet" --> G --> I
    H -.batch sonra.-> G

    style A fill:#1f6feb,color:#fff
    style I fill:#cf222e,color:#fff
    style F fill:#bf8700,color:#fff

Önemli not: Tipik bir frame'de birçok DrawRect/DrawCircle çağrısı aynı pen ve opacity ile gelir. Bu durumda Flush() tetiklenmez; tüm vertex'ler tek bir GPU draw call'ında gönderilir. Detaylar için akislar.md → Batch Flush Koşulları.


4. Modül Haritası — Kaynak Ağacı

sdl-painter/
├── include/sdl_painter/ ← Public API (kullanıcı bu header'ları görür)
│ ├── painter.h · Ana çizim sınıfı
│ ├── pen.h, brush.h, color.h · Stil tipleri
│ ├── transform.h · 3×3 affine matris
│ ├── geometry.h · Point, Rect, Size
│ ├── image.h, texture.h · Görsel + RAII texture sarmalayıcı
│ ├── font.h · SDL_ttf wrapper, Alignment
│ ├── renderer.h · IRenderer arayüzü + RendererBackend enum
│ └── vertex.h · Vertex, TexturedVertex
├── src/ ← İmplementasyon (kullanıcıya kapalı)
│ ├── painter.cpp · API ↔ batcher/tessellator köprüsü
│ ├── render_batcher.{h,cpp} · Draw call coalescing
│ ├── tessellator.{h,cpp} · Şekil → vertex
│ ├── renderer.cpp · CreateRenderer factory
│ ├── opengl/ · OpenGL 3.3 backend
│ │ ├── opengl_renderer.{h,cpp}
│ │ ├── shader_program.{h,cpp}
│ │ └── shaders/*.{vert,frag}
│ └── vulkan/ · Vulkan 1.1 backend
│ ├── vulkan_renderer.{h,cpp} · IRenderer impl
│ ├── vk_context.{h,cpp} · Instance, device, queue
│ ├── vk_swapchain.{h,cpp} · Swapchain + image view
│ ├── vk_frame_sync.{h,cpp} · Semaphore, fence
│ ├── vk_memory.{h,cpp} · Buffer/image bellek
│ ├── vulkan_pipeline.{h,cpp} · Untextured pipeline
│ ├── vulkan_textured_pipeline.{h,cpp}
│ ├── vulkan_buffer.{h,cpp} · Vertex ring buffer
│ ├── vulkan_texture.{h,cpp} · Texture + descriptor set
│ └── shaders/*.spv · SPIR-V derlenmiş shader'lar
├── examples/ ← Faz bazlı demo uygulamaları
│ ├── phase1_demo.cpp · Primitifler
│ ├── phase2_demo.cpp · Transform stack
│ ├── phase3_demo.cpp · Image
│ ├── phase4_demo.cpp · Text
│ └── phase5*_vulkan_*.cpp · Vulkan örnekleri
└── tests/ ← GTest birim testleri
├── mock_renderer.h · IRenderer mock'u
├── test_tessellator.cpp
├── test_render_batcher.cpp
├── test_transform.cpp
└── ...

Public ve Private Ayırımı

  • include/sdl_painter/*.hKullanıcıya açık. ABI/API stabilite hedefi var.
  • src/*.h (tessellator.h, render_batcher.h) → İç implementasyon. Kullanıcı bu header'ları include etmemeli.
  • src/opengl/*.h, src/vulkan/*.h → Backend'e özel iç tipler.

5. Bağımlılık Yönetimi (Conan 2)

graph TB
    Painter["sdl_painter"]

    subgraph zorunlu["Zorunlu — her zaman çekilir"]
        SDL3["SDL3 (sdl/3.2.x)"]
        GLAD["GLAD (glad/0.1.x)"]
        STB["stb_image (stb/cci.*)"]
    end

    subgraph ops["Opsiyonel — option ile etkinleştirilir"]
        TTF["SDL_ttf"]
        VK["Vulkan loader/headers (with_vulkan)"]
        GTEST["GTest (build_tests)"]
    end

    Painter --> SDL3
    Painter --> GLAD
    Painter --> STB
    Painter -.opt.-> TTF
    Painter -.opt.-> VK
    Painter -.opt.-> GTEST

    style zorunlu fill:#2da44e20,stroke:#2da44e
    style ops fill:#bf870020,stroke:#bf8700

with_vulkan=False olduğunda Vulkan loader hiç indirilmez; CI süresi ve container imaj boyutu küçük kalır. Detaylar için .claude/rules/build-deps.md ve conanfile.py.


6. Sözleşmeler ve Değişmez Kurallar (Invariants)

Mimarinin tutarlı kalması için bileşenler arasında uyulan kurallar:

Sözleşme Açıklama
Tessellator stateless Aynı input → aynı output, her zaman. GPU bağımlılığı yok.
IRenderer salt arayüz Hiçbir state (transform, opacity stack) tutmaz; sadece komut alır.
Painter, IRenderer'a sahiptir unique_ptr<IRenderer>; yaşam döngüsü Painter'a bağlı.
RenderBatcher Painter'a aittir Painter dışında erişilemez; arayüzü internal.
Texture handle opak uint32_t; backend bunu kendi haritasında çözer.
Y ekseni Painter'da yukarı pozitif değil Painter Y=0 üstte; OpenGL scissor'unda flip ApplyScissor'da uygulanır.
Frame sınırı: Begin/End İki çağrı arasında transform/state biriktirilir, End'te flush.

Bu değişmezler bozulduğunda mimari avantajları (test edilebilirlik, backend değiştirilebilirliği, performans öngörülebilirliği) kaybolur.


7. Sonraki Adımlar