Vulkan을 이용한 고속 GUI 라이브러리 Duxel

안녕하세요 .앞 전에 공유 드렸던 라이브러리를

좀 더 개선해서 버전 0.1.5-preview를 출시했습니다.

깃허브 저장소는 다음과 같습니다.

Duxel은 Dear ImGui와 유사한 즉시 렌더링 모델을 GPT-5.2-Codex를 이용해 .NET 10용으로 구현했습니다. GUI를 구성하는 별도의 논리적 트리가 없으므로 구조가 단순하며, GPU를 활용해 화면을 빠르게 다시 렌더링하는 데 집중합니다.

최신 버전은 v0.1.5-preview로, 알파 단계에 있어 제품에 사용할 만큼 안정적이지는 않지만 대부분의 기능이 정상적으로 동작합니다.

주요 특징으로는 다음과 같습니다.

  • 즉시 모드 UI — Dear ImGui 스타일의 Begin/End 패턴 기반 위젯 API
  • Vulkan 렌더러 — MSAA 4x, VSync 토글, Triple Buffering, Persistent Mapped Buffers
  • GLFW 윈도우/입력 — 키보드·마우스·스크롤·IME 입력 지원
  • 스크롤바/팝업 — 통합 스크롤바 렌더러 (Child/Combo/ListBox/InputMultiline), 팝업 차단 레이어
  • NativeAOT 지원PublishAot=true 배포 가능 (리플렉션/동적 로딩 없음)
  • UI DSL.ui 파일로 선언적 UI 정의, 소스 생성기 기반 빌드 타임 코드 생성, 핫리로드 지원
  • 폰트 아틀라스 — TTF 파싱(컴파운드 글리프 포함), HiDPI 스케일링, 빠른 시작을 위한 Built-in ASCII 폰트
  • ImGui API 전체 커버리지 — 400+ API 구현 완료 (상세 목록)

핫리로드를 통해 화면 구성을 지원하기 위해 다음 형태의 DSL(Domain-Specific Language)를 지원하며 좀 더 자세한 지원은 UI DSL 레퍼런스를 참조할 수 있습니다. 아직 구조는 진화 중이며 안정적이지 않습니다.

Window "DSL Showcase"
  MenuBar
    Menu "File"
      MenuItem Id="new" Text="New"
      MenuItem Id="exit" Text="Exit"
  SeparatorText "Inputs"
  InputText Id="name" Text="Name" MaxLength=64
  InputInt Id="age" Text="Age" Value=0
  InputFloat Id="speed" Text="Speed" Format="0.00"
  Checkbox Id="vsync" Text="VSync" Default=true
  SliderFloat Id="volume" Text="Volume" Min=0 Max=1
  Combo Id="preset" Text="Preset" Items="Low|Medium|High"
  SeparatorText "Tabs"
  TabBar "tabs"
    TabItem "Tab A"
      Text "Tab A content"
    TabItem "Tab B"
      Text "Tab B content"
  SeparatorText "Table"
  Table "table" 3
    TableSetupColumn "Name"
    TableSetupColumn "Value"
    TableSetupColumn "Notes"
    TableHeadersRow
    TableNextRow
    TableNextColumn
    Text "Row1"
    TableNextColumn
    Text "42"
    TableNextColumn
    Text "Hello"
  SeparatorText "Tree"
  TreeNode "Node 1"
    Text "Child 1"
    TreeNode "Node 1.1"
      Text "Leaf"
  TreeNode "Node 2"
    Text "Child 2"

DSL을 사용하게 되면 기본적으로 Debug/Release로 실행 시 DSL 파일을 수정할 때 즉시 화면이 갱신됩니다. NativeAOT로 게시하게 되면 소스생성기를 통해 소스코드로 변환하여 가장 빠른 코드로 재구성됩니다.

다음은 여러 기능을 확인할 수 있는 쇼케이스 입니다.

필수 환경

  • .NET 10 SDK
  • Vulkan 1.0+ 지원 (대부분의 GPU에서 지원)

종합 데모

curl -sLO https://raw.githubusercontent.com/dimohy/Duxel/main/samples/fba/all_features.cs && dotnet run all_features.cs

DSL 선언적 UI

curl -sLO https://raw.githubusercontent.com/dimohy/Duxel/main/samples/fba/dsl_showcase.cs && dotnet run dsl_showcase.cs

DSL 인터랙션

curl -sLO https://raw.githubusercontent.com/dimohy/Duxel/main/samples/fba/dsl_interaction.cs && dotnet run dsl_interaction.cs

기타 샘플 실행 방법은 Duxel FBA 샘플 — 바로 실행하기를 참고하세요.

10개의 좋아요

0.1.6-preview로 업데이트 하였습니다.

  • 빠른 시작을 위해 사용했던 어색한 아스키 폰트를 더 이상 사용하지 않습니다.
  • 시작 시간을 최적화했습니다.
  • 이제 한글도 빠르게 표시됩니다.
  • 한글 입력 시 다른 포커스로 이동할 때 입력 중인 글자가 이동하는 문제를 수정했습니다.
  • 한글 입력을 텍스트 박스 내부로 옮겼습니다.
3개의 좋아요

0.1.7-preview 업데이트

curl -sLO https://raw.githubusercontent.com/dimohy/Duxel/main/samples/fba/image_widget_effects_fba.cs && dotnet run image_widget_effects_fba.cs

  • Vulkan AA 파이프라인 강화: TAA/FXAA 토글 경로 보강, 전환 시 리소스/파이프라인 재구성 안정화
  • AA 검증 체계 추가: MSAA↔FXAA 비교 체크리스트 및 성능 샘플 정비
  • 이미지 API 라이브러리화: Core에 플랫폼 중립 이미지 API 추가 UiImageTexture, UiImageEffects, IUiImageDecoder
  • 플랫폼 분리 강화: Windows 디코더를 플랫폼 계층으로 분리, App 런타임 등록 방식으로 Core 종속성 제거
  • 신규 FBA 샘플: 웹 PNG/JPG/GIF 로드 + GIF 애니메이션 + 이미지 효과(Zoom/Rotation/Alpha/Brightness/Contrast/Pixelate)
  • UI 동작 수정: 창 접힘 시 3px 본문 peek 유지 + 캔버스 돌출/클립 이슈 수정
3개의 좋아요

Duxel 0.1.10-preview 주요 변경

렌더링

  • 레이어 정적 지오메트리 캐시 추가 — 콘텐츠 해시 기반 GPU 상주 버퍼로 프레임마다 재업로드 제거
  • Texture compose 캐시 경로 기초 구현 및 opacity 포함 태그 판별 버그 수정
  • 드로우 리스트 빌더에 translation-aware 클리핑/머지 지원

코어 / 플랫폼

  • 레이어 캡처·리플레이·정적 태그 생성 시스템 구현
  • 아이들 프레임 스킵 메커니즘 추가 (이벤트/요청 기반 자동 웨이크)
  • 플랫폼 서비스 주입 구조 도입 및 Windows 직접 종속 제거

패키지

샘플

  • idle_layer_validation 신규 — 레이어 캐시/GPU 버퍼 벤치 (백엔드·opacity·레이아웃 환경변수 제어)
  • Duxel_perf_test_fba 확장 — 공간 해시 충돌 최적화, 충돌 시각/회전 효과 추가
  • image_widget_effects_fba 신규 — 웹 이미지 + GIF 애니메이션 + 이미지 효과 데모
  • 레거시 프로젝트 샘플 삭제 → FBA로 통합
curl -sLO https://raw.githubusercontent.com/dimohy/Duxel/main/samples/fba/idle_layer_validation.cs && dotnet run idle_layer_validation.cs

1개의 좋아요

Duxel 0.1.11-preview 주요 변경

  • 이제 Duxel.App.Run() 은 플렛폼에 맞게 알아서 윈도우의 경우 DuxelWindowsApp.Run()를 알아서 호출함
  • 전역 캐시 지원으로 CPU 사용 효율이 극대화 됨
curl -sLO https://raw.githubusercontent.com/dimohy/Duxel/main/samples/fba/Duxel_perf_test_fba.cs && dotnet run Duxel_perf_test_fba.cs

2개의 좋아요

Duxel 0.1.12-preview 주요 변경

  • [기능] DirectWrite 기반 텍스트 렌더링 시스템 추가 — WindowsDirectWriteGlyphRasterizer 신규 구현, Direct Text 런타임 토글 API(SetDirectTextEnabled/GetDirectTextEnabled), DUXEL_DIRECT_TEXT 환경변수 지원, 텍스트 캐시 관리(LRU 256엔트리)

  • [기능] Windows 플랫폼 백엔드 독립 분리 — WindowsPlatformBackend(975줄) 신규 구현, GLFW 플랫폼(Duxel.Platform.Glfw) 완전 제거

  • [기능] 즉시 모드 애니메이션 프레임워크 추가 — AnimateFloat API(easing: OutCubic 등), RequestFrame 연속 렌더 요청, 애니메이션 트랙 상태 관리

  • [기능] 폰트 크기 런타임 제어 API 추가 — PushFontSize/PopFontSize, DrawTextAlignedfontSize 파라미터, 폰트 아틀라스 래스터라이저 분리(UiFontAtlas.Rasterizers.cs)

  • [기능] 위젯/벤치 헬퍼 API 대량 승격 — BeginWindowCanvas/EndWindowCanvas, DrawOverlayText, UiFpsCounter, DrawKeyValueRow, BenchOptions, DrawLayerCardSkeleton/DrawLayerCard/DrawLayerCardInteractive(UiLayerCardInteraction 구조체)

  • [기능] 레이아웃 시스템 확장 — EnableRootViewportContentLayout, AlignRect, SetNextItemVerticalAlign, SameLine 수직 정렬 지원

  • [기능] 아이콘 시스템 추가 — UiImmediateContext.Icons 내장 아이콘 렌더 지원

  • [기능] Windows 계산기 FBA — 사이버 backdrop/리플 효과/FX 버튼/반투명 UI 시연(windows_calculator_fba.cs), RPN 트레이스/멀티베이스 쇼케이스(windows_calculator_duxel_showcase_fba.cs)

  • [개선] 위젯 API 시그니처 통일 — Combo/ListBox/Table/Tree에 string? id 파라미터 추가로 ID 충돌 방지

  • [개선] IME 처리 안정성 개선 — WindowsImeHandler 리팩토링

  • [개선] 10개+ FBA 샘플에서 보일러플레이트(FPS 측정/오버레이/벤치파서/카드렌더)를 라이브러리 API 호출로 전환, 코드 간결성 대폭 향상

  • [개선] Direct Text ON/OFF A/B 벤치에서 평균 FPS +5.87% 개선 확인 (375→397 FPS)

바이브 코딩이라 하더라도… 개발이 빨라지는 것일 뿐 공은 여전히 들어가네요 ^^;

curl -sL https://raw.githubusercontent.com/dimohy/Duxel/refs/heads/main/samples/fba/windows_calculator_fba.cs -o - | dotnet run -

3개의 좋아요

다음부터는 슬로그에서 작업 내용을 기록할께요. 어느정도 안정화가 되면 다시 이곳에 글을 쓰도록 하겠습니다.

하고자 하는 것

  • 현재 평면적 API 사용이 어려움. (예: BeginWindow() … EndWindow()) 이를 using과 Fluent API를 이용해서 좀 더 사용하기 쉽도록 함
using var frame = ui.Frame();

using var main = frame.Windows.Begin("Main")
    .Size(900, 600)
    .Padding(12);

main.Layout
    .Vertical(spacing: 8)
    .Section("검색", section =>
    {
        section.Forms.TextBox("Query", ref query);
        section.Forms.Button("Search", onClick: Search);
    })
    .Section("결과", section =>
    {
        using var table = section.Widgets.Tables.Begin("results", columns: 4)
            .Header("ID")
            .Header("Name")
            .Header("Score")
            .Header("Action");

        foreach (var item in items)
        {
            table.Row(row =>
            {
                row.Cell.Text(item.IdText);
                row.Cell.Text(item.Name);
                row.Cell.Text(item.ScoreText);
                row.Cell.Button("Open", () => Open(item));
            });
        }
    });
  • Silk.NET의 의존성을 완전히 제거해서 최종 3 MB 미만의 독립 실행 파일 생성
  • LLM Agent가 이해할 수 있도록 문서화, Github Skills 준비
2개의 좋아요