Suckless OGL 1.0.0
A lean, high-performance C11 PBR Renderer
Loading...
Searching...
No Matches
ktx_viewer.c File Reference

Viewer minimal KTX2 — Affiche une texture PBR/HDR compressée avec tone-mapping. More...

#include <glad/glad.h>
#include "utils.h"
#include <GLFW/glfw3.h>
#include <ktx.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
Include dependency graph for ktx_viewer.c:

Data Structures

struct  GlContext
 Encapsule la fenêtre système et le contexte de rendu. More...
 
struct  KtxAsset
 Encapsule une ressource KTX2 en RAM. Contient la taille originale du fichier pour les métriques de compression. More...
 
struct  GlTexture
 Encapsule l'objet texture OpenGL résidant en VRAM. More...
 
struct  ShaderProg
 Encapsule le programme GPU lié. More...
 

Enumerations

enum  { WINDOW_W = 1280 , WINDOW_H = 720 , LOG_BUF = 512 , MSG_BUF = 1024 }
 

Functions

static bool gl_context_init (GlContext *ctx, const char *title)
 Initialise GLFW et GLAD pour fournir un contexte OpenGL 3.3 Core.
 
static void gl_context_destroy (GlContext *ctx)
 
static GLuint shader_compile (GLenum type, const char *src)
 Compile un shader GLSL individuel et vérifie les erreurs.
 
static bool shader_program_create (ShaderProg *prog, const char *vs_src, const char *fs_src)
 Lie le Vertex et le Fragment shader dans un programme GPU.
 
static void shader_program_destroy (ShaderProg *prog)
 
static bool ktx_asset_load (KtxAsset *asset, const char *filepath)
 Charge le fichier KTX2 depuis le disque et le rend exploitable pour OpenGL.
 
static void ktx_asset_print_info (const KtxAsset *asset, const char *path)
 Affiche un rapport complet sur les métadonnées et l'efficacité de la compression.
 
static void ktx_asset_destroy (KtxAsset *asset)
 
static void ktx_resolve_gl_format (const KtxAsset *asset, GLint *internal_fmt, GLenum *base_fmt, GLenum *gl_type)
 Lit le DFD (Data Format Descriptor) pour attribuer les formats OpenGL exacts.
 
static bool gl_texture_upload_from_ktx (GlTexture *tex, const KtxAsset *asset)
 Envoie les données CPU (décodées) vers la mémoire de la carte graphique (VRAM).
 
static void gl_texture_destroy (GlTexture *tex)
 
static void render_loop (GLFWwindow *window, const ShaderProg *prog, const GlTexture *tex)
 
int main (int argc, char **argv)
 

Variables

static const float CLEAR_R = 0.07F
 
static const float CLEAR_G = 0.07F
 
static const float CLEAR_B = 0.10F
 
static const float CLEAR_A = 1.00F
 
static const char *const VS_SRC
 Vertex Shader : "Fullscreen Triangle".
 
static const char *const FS_SRC
 Fragment Shader : Échantillonnage HDR et Tone-Mapping.
 

Detailed Description

Viewer minimal KTX2 — Affiche une texture PBR/HDR compressée avec tone-mapping.

Architecture & Pipeline :

  1. Chargement (Disque -> RAM) : Lecture du fichier .ktx2 via l'API libktx. Si le fichier utilise une supercompression (ex: Zstandard), il est déflaté à la volée.
  2. Décompression (Blocs -> Pixels) : Les GPU Desktop (Intel/Nvidia/AMD) ne supportent pas le format ASTC HDR matériellement. Le CPU transcode donc les blocs (Basis/UASTC/ASTC) vers un format SFLOAT brut (Half-Float 16-bit).
  3. Upload (RAM -> VRAM) : Envoi manuel vers GL_TEXTURE_2D. Un soin particulier est apporté à l'alignement mémoire (Row Pitch) car le RGB16F n'est pas un multiple de 4 octets.
  4. Rendu (GPU) : Un shader "Fullscreen Triangle" (sans VBO) lit la texture, applique un tone-mapping de Reinhard (pour ramener le HDR sur un écran LDR) et une correction Gamma.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

PIPELINE DE GÉNÉRATION DES ASSETS GRAPHIQUES (HDR -> KTX2 UASTC + ZSTD)

  • Ce visualiseur est conçu pour exploiter des textures HDR/PBR hautement compressées. Les GPU de bureau (ex: Intel Iris Xe, AMD/Nvidia standards) ne gèrent pas le décodage matériel du format ASTC HDR. La stratégie consiste donc à utiliser le codec UASTC-HDR compressé au format Zstandard sur le disque, puis à transcoder sur le CPU vers du Float 16-bit (SFLOAT) avant l'envoi en VRAM.

— PERFORMANCES ATTENDUES — Source (.hdr) : ~ 40 Ko (Format Radiance classique) Uncompressed (.ktx2): ~ 4.0 Mo (R16G16B16A16_SFLOAT) UASTC-HDR 4x4 : ~ 512 Ko (Format de blocs universel) UASTC-HDR + Zstd 18 : ~ 3 Ko (Taille finale sur le disque)

  • — COMMANDES DE GÉNÉRATION — Outils requis : OpenImageIO (oiiotool) et KTX-Software (ktx).
  • ÉTAPE 1 : Conversion stricte du format Radiance (.hdr) vers OpenEXR linéaire (.exr) (Préserve la plage dynamique et évite le clamping). $ oiiotool assets/textures/hdr/axis_test.hdr -o /tmp/axis_test.exr
  • ÉTAPE 2 : Génération de l'image KTX2 cible (UASTC-HDR-4x4 + Zstd 18) On peut le faire en une seule commande 'create' depuis l'EXR : $ ktx create –format R16G16B16A16_SFLOAT \ –encode uastc-hdr-4x4 \ –zstd 18 \ /tmp/axis_test.exr assets/textures/hdr/axis_test_uastc_hdr4x4_zstd18.ktx2
  • ALTERNATIVE (Utilisée dans les tests) : Via 'ktx encode' depuis un KTX2 non-compressé : $ ktx encode –codec uastc-hdr-4x4 –zstd 18 \ assets/textures/hdr/axis_test_uncompressed.ktx2 \ assets/textures/hdr/axis_test_uastc_hdr4x4_zstd18.ktx2
  • ========================================================================================= Constantes définissant la géométrie de la fenêtre et les buffers textes.
Enumerator
WINDOW_W 
WINDOW_H 
LOG_BUF 

Taille du buffer pour l'extraction des logs de shaders GLSL.

MSG_BUF 

Taille du buffer pour le formatage des impressions console.

Function Documentation

◆ gl_context_destroy()

static void gl_context_destroy ( GlContext *  ctx)
static

◆ gl_context_init()

static bool gl_context_init ( GlContext *  ctx,
const char *  title 
)
static

Initialise GLFW et GLAD pour fournir un contexte OpenGL 3.3 Core.

◆ gl_texture_destroy()

static void gl_texture_destroy ( GlTexture *  tex)
static

◆ gl_texture_upload_from_ktx()

static bool gl_texture_upload_from_ktx ( GlTexture *  tex,
const KtxAsset *  asset 
)
static

Envoie les données CPU (décodées) vers la mémoire de la carte graphique (VRAM).

Here is the call graph for this function:

◆ ktx_asset_destroy()

static void ktx_asset_destroy ( KtxAsset *  asset)
static

◆ ktx_asset_load()

static bool ktx_asset_load ( KtxAsset *  asset,
const char *  filepath 
)
static

Charge le fichier KTX2 depuis le disque et le rend exploitable pour OpenGL.

  • MOTIVATION DE L'ARCHITECTURE : Le format KTX2 supporte l'encodage universel (BasisLZ / UASTC). Normalement, ces blocs sont envoyés tels quels à la VRAM. CEPENDANT, les drivers OpenGL "Desktop" (notamment les puces Intel Iris Xe ou AMD basiques) ne contiennent pas de décodeur matériel pour l'ASTC HDR. Si on envoie les blocs natifs, on obtient un plantage (Segfault du driver) ou une bouillie violette/magenta.
  • SOLUTION : On intercepte toute texture qui est "isCompressed". Si elle est transcodable, on force sa décompression sur le CPU vers de la RAM non compressée (RGBA_HALF), que n'importe quelle carte graphique standard sait avaler et afficher.

◆ ktx_asset_print_info()

static void ktx_asset_print_info ( const KtxAsset *  asset,
const char *  path 
)
static

Affiche un rapport complet sur les métadonnées et l'efficacité de la compression.

Here is the call graph for this function:

◆ ktx_resolve_gl_format()

static void ktx_resolve_gl_format ( const KtxAsset *  asset,
GLint *  internal_fmt,
GLenum *  base_fmt,
GLenum *  gl_type 
)
static

Lit le DFD (Data Format Descriptor) pour attribuer les formats OpenGL exacts.

◆ main()

int main ( int  argc,
char **  argv 
)
Here is the call graph for this function:

◆ render_loop()

static void render_loop ( GLFWwindow *  window,
const ShaderProg *  prog,
const GlTexture *  tex 
)
static

◆ shader_compile()

static GLuint shader_compile ( GLenum  type,
const char *  src 
)
static

Compile un shader GLSL individuel et vérifie les erreurs.

◆ shader_program_create()

static bool shader_program_create ( ShaderProg *  prog,
const char *  vs_src,
const char *  fs_src 
)
static

Lie le Vertex et le Fragment shader dans un programme GPU.

Here is the call graph for this function:

◆ shader_program_destroy()

static void shader_program_destroy ( ShaderProg *  prog)
static

Variable Documentation

◆ CLEAR_A

const float CLEAR_A = 1.00F
static

◆ CLEAR_B

const float CLEAR_B = 0.10F
static

◆ CLEAR_G

const float CLEAR_G = 0.07F
static

◆ CLEAR_R

const float CLEAR_R = 0.07F
static

Couleur de fond (Clear Color) très sombre pour faire ressortir les textures HDR.

◆ FS_SRC

const char* const FS_SRC
static
Initial value:
=
"#version 330 core\n"
"in vec2 uv;\n"
"out vec4 frag_color;\n"
"uniform sampler2D u_tex;\n"
"void main() {\n"
" vec3 hdr = texture(u_tex, uv).rgb;\n"
" vec3 mapped = hdr / (hdr + vec3(1.0));\n"
" frag_color = vec4(pow(mapped, vec3(1.0/2.2)), 1.0);\n"
"}\n"

Fragment Shader : Échantillonnage HDR et Tone-Mapping.

  • MOTIVATION : Une image HDR contient des valeurs lumineuses supérieures à 1.0 (ex: un soleil à 50.0). Si on affiche ça directement sur un écran (qui plafonne à 1.0), l'image sera "brûlée" (blanche). L'opérateur de Reinhard hdr / (hdr + 1.0) compresse la plage [0, +infini] vers [0, 1].

◆ VS_SRC

const char* const VS_SRC
static
Initial value:
=
"#version 330 core\n"
"out vec2 uv;\n"
"void main() {\n"
" uv = vec2((gl_VertexID << 1) & 2, gl_VertexID & 2);\n"
" gl_Position = vec4(uv * 2.0 - 1.0, 0.0, 1.0);\n"
"}\n"

Vertex Shader : "Fullscreen Triangle".

  • ASTUCE D'OPTIMISATION : Au lieu de créer un VBO/EBO avec 4 sommets pour un quad, on utilise gl_VertexID pour générer un unique triangle gigantesque qui couvre tout l'écran. C'est la méthode standard de l'industrie pour les passes de post-processing.