Skip to content

Core Rendering

Alessandro Bria edited this page Sep 21, 2026 · 3 revisions

Rendering, camera e livelli

Il rendering attraversa quattro livelli distinti:

Window -> Scene -> View -> RenderableObject -> Sprite

Separarli evita che coordinate della scena, coordinate dello schermo e contenuto delle texture vengano confusi.

Tre spazi di coordinate

Spazio Esempio Chi lo usa
Scena RectF di un personaggio o di una piattaforma Object, GameScene, collisioni
Finestra/renderer posizione in pixel dopo camera e viewport SDL, View, input del mouse
Texture RectI che seleziona un'immagine nella spritesheet Sprite e derivate

pixelUnitSize specifica quanti pixel della grafica corrispondono a un'unità della scena. Non è la dimensione del viewport: quella dipende dalla finestra e dalla camera. Per esempio, un personaggio largo un'unità può usare una regione di texture larga 16 pixel, mentre sul monitor viene ingrandito in base alla View.

Window: il dispositivo di uscita

Window crea SDL_Window e SDL_Renderer, abilita il blending e attiva il VSync. A ogni frame:

  1. pulisce il renderer;
  2. chiede alle scene di disegnarsi nell'ordine dello stack;
  3. presenta il frame con SDL_RenderPresent().

Il ridimensionamento aggiorna le dimensioni della finestra; gli eventi corrispondenti fanno ricalcolare i viewport delle scene.

Window non decide quali oggetti sono visibili: inoltra il rendering alle scene. Game::dispatchEvent() passa gli eventi di finestra a tutte le scene; Scene::event() chiede alla propria View di aggiornare il viewport. Le modalità con shader sostituiscono la classe della finestra, non l'organizzazione di scene e oggetti.

View: camera e viewport

La View collega due rettangoli:

  • il view rect, espresso nelle coordinate della scena;
  • il viewport, espresso come porzione normalizzata della finestra.

Da questi dati calcola:

  • fattore di ingrandimento;
  • trasformazione scena -> schermo;
  • trasformazione schermo -> scena;
  • correzione dell'aspect ratio;
  • area di clipping.

mapFromScene() è usato per disegnare; mapToScene() serve per trasformare mouse e input grafici nel sistema della scena.

Il view rect è la camera nella scena: spostarlo cambia la zona osservata, non la posizione degli oggetti. Il viewport è la zona della finestra in cui la camera disegna; valori normalizzati come (0, 0, 1, 1) indicano tutta la superficie. View::updateViewport() converte il viewport in pixel, applica l'eventuale aspect ratio fisso e costruisce le due trasformazioni. Se RectF::yUp è attivo, la trasformazione inverte verticalmente l'asse Y rispetto alle coordinate dello schermo SDL.

punto nella scena --mapFromScene()--> punto nel renderer
punto del mouse --mapToScene()--> punto nella scena

Con setViewport() puoi dedicare una porzione della finestra a una vista; con setClipRect() puoi restringere ulteriormente il disegno. Se l'aspect ratio fissato non coincide con quello della finestra, la View centra un'area che conserva le proporzioni invece di deformarla.

Culling

Prima di disegnare, View::render() chiede alla scena soltanto gli oggetti che intersecano il view rect. Con il quadtree attivo questa selezione evita una scansione completa degli oggetti.

La View ordina i candidati per layer, prova a convertirli in RenderableObject e chiama draw() soltanto su quelli renderizzabili. La selezione spaziale usa il rettangolo dell'oggetto: se l'immagine disegnata sporge dal suo rettangolo logico (fit = false), considera il possibile effetto sul culling vicino ai bordi della camera.

RenderableObject: presenza visiva nella scena

RenderableObject estende Object con:

  • colore e colore di sfondo;
  • bordo e spessore;
  • visibilità e lampeggio;
  • angolo e velocità angolare;
  • flip orizzontale o verticale;
  • riferimento a uno Sprite.

Se lo sprite è nullo, l'oggetto viene disegnato come rettangolo colorato. Questo è utile per prototipi, debug e interfacce semplici.

RenderableObject::draw() può aggiungere uno sfondo colorato, un bordo, un rettangolo di debug e un breve lampeggio. RenderableObject::update() aggiorna angolo e sprite, quindi un'animazione vive nel normale ciclo degli oggetti. setVisible(false) agisce sul singolo oggetto: non lo toglie dalle query della scena, ma il suo draw() termina subito.

Ordinamento per layer

Gli oggetti visibili vengono ordinati per layer prima del disegno. Un valore più alto viene disegnato dopo e quindi appare davanti.

auto* shadow = new RenderableObject(scene, shadowRect, shadowSprite, 1);
auto* player = new RenderableObject(scene, playerRect, playerSprite, 2);
auto* effect = new RenderableObject(scene, effectRect, effectSprite, 3);

Il layer influenza il rendering, non la logica delle collisioni.

L'ordinamento viene calcolato tra gli oggetti restituiti dalla query a ogni disegno; non cambia l'ordine del vettore mantenuto dalla scena. Oggetti con lo stesso layer non hanno qui una regola esplicita di precedenza su cui fare affidamento.

fit e pixel art

Con fit = true, lo sprite viene adattato al rettangolo dell'oggetto. Con fit = false, il core conserva proporzioni e scala coerenti con pixelUnitSize, utile quando il rettangolo logico rappresenta un collider ma l'immagine deve estendersi oltre di esso.

Il filtro nearest impostato sulle texture mantiene nitida la pixel art durante l'ingrandimento.

Il filtro è una proprietà della texture, non della camera: le funzioni di caricamento grafico in utils/sdlUtils.h impostano SDL_SCALEMODE_NEAREST per le immagini. La texture generata per il testo usa invece il filtraggio lineare. La scelta va fatta quando si crea la texture se si aggiunge un caricatore nuovo.

Aspect ratio

Game conserva l'aspect ratio desiderato. Le View possono applicarlo al proprio viewport, introducendo bande laterali o superiori invece di deformare la scena.

GameScene imposta sulla propria View l'aspect ratio fornito da Game; anche OverlayScene lo imposta. UIScene crea una View autonoma e può avere esigenze diverse. Nella GameScene standard la camera segue _player centrando il view rect sul rettangolo del giocatore, oppure si può passare al movimento manuale con le frecce e allo zoom con la rotellina. La camera non sposta gli oggetti: cambia soltanto la trasformazione usata nel disegno e nelle conversioni dell'input.

Per i click nella scena, continua con Input ed eventi; per la grafica dentro ogni oggetto, continua con Sprite, animazioni e testo.

Sorgenti di riferimento

Clone this wiki locally