La matrice aggiornata

La matrice aggiornata

A volte puoi trovare cose interessanti nei tuoi progetti passati!

Un giorno stavo pensando a nuovi argomenti per i post per il blog, ma in qualche modo non avevo molta energia per farlo. Quindi, ho appena sfogliato i miei vecchissimi progetti (che in realtà sono elencati nel mio sito di portfolio). I ricordi sono tornati e ho deciso che forse è ora di aggiornare gli antichi file di codice!

Questa volta entriamo in Matrix!

Introduzione

Verso la fine del 2003, dopo che io e i miei amici abbiamo guardato tutti i film di Matrix, siamo diventati tutti pazzi per la trilogia (che si è conclusa in quel momento). Un amico ha suggerito che forse avrei potuto fare delle animazioni relative alla "pioggia della matrice" dell'introduzione del film. Ho detto "Perché no!".

La clip qui sotto mostra l'introduzione di Matrix Reloaded:

Nell'animazione si passa da una semplice "pioggia di matrice" a una scena 3D complessa e poi alla prima scena del film vero e proprio.

C'erano (e ci sono ancora) molti screen saver e demo che utilizzano l'idea dell'effetto matrice. Quindi sapevo che implementare una semplice pioggia di lettere non sarebbe stato fantastico. Avevo bisogno di qualcosa di più. Allo stesso tempo, mi sono reso conto che anche realizzare animazioni complete (come nell'introduzione) è al di là delle mie capacità:non potevo creare quella scena 3D di orologio/macchine avanzate. Ma se potessi semplificare questa idea?

Dopo alcune indagini, prove ed errori ho deciso di creare una scena 3d molto semplice e di metterla dietro le lettere che cadono!

La vetrina

Dai un'occhiata al video qui sotto:

Cosa abbiamo qui?

  • C'è un'animazione dell'orologio 3D molto semplice (mostra l'ora corrente)
  • La fotocamera si muove
  • L'intera scena viene proiettata utilizzando l'effetto matrice come post-elaborazione

Come funziona

Abbiamo le seguenti parti principali:

  • Configurazione
  • Matrice pioggia
  • Animazione orologio 3D
  • Effetto di post-elaborazione che rende i glifi

Installazione

La demo utilizza la libreria Allegro Game 4.03 per il rendering, implementata in Dev Cpp, Windows.

Abbiamo bisogno di una bitmap fuori schermo con la risoluzione di scr_w/font_width x scr_h/font_height . Ad esempio 1600/8 x 900/8 =200x112 pixel. Inizialmente, ho usato solo un font di sistema 8x8, ma ho anche sperimentato con font in stile matrice. Per me, il carattere di sistema sembrava effettivamente migliore per questo effetto rispetto al carattere matrice.

Tieni presente che abbiamo bisogno anche di un'altra bitmap fuori schermo, un buffer, che verrà utilizzato per il doppio buffering.

Matrice pioggia

Ogni colonna della piccola bitmap fuori schermo ha una particella che si sposta dall'alto verso il basso. Ogni particella ha una velocità iniziale, non c'è gravità qui. La particella è renderer con una scia di dissolvenza:

Le lettere cadono dall'alto, ma in effetti, se ho ragione, possono iniziare nel mezzo di una finestra... quindi potrebbe valere la pena controllare.

Animazione orologio 3D

La maggior parte del codice 3d (calcolo della matrice, rotazioni, fotocamera) viene scritta da zero e utilizza solo metodi Allegro di base:

  • set_projection_viewport - spef da allegro 4.4.2 - memorizza il corretto viewport di proiezione della scena.
  • clip3d_f - spec da allegro 4.4.2 - questo gestisce il ritaglio, quindi posso semplicemente inviare i miei vertici trasformati (prima della proiezione) e ottenere l'output ritagliato.
  • persp_project_f - spec da allegro 4.4.2 - esegue la proiezione prospettica finale utilizzando la mia fotocamera e le impostazioni dello schermo.

Quindi, eseguiamo il rendering dei modelli in modalità wireframe solo e solo nei punti coperti da linee (non vuoti, spazi neri), quindi do_line viene richiamato lì per mettere i pixel nelle posizioni corrette - controlla semplicemente se il colore esistente non è zero (non nero) e quindi inserisce un pixel:

void PutLetter(BITMAP *bmp, int x, int y, int c)
{
 if (x >= 0 && x < bmp->w && y >= 0 && y < bmp->h)
 {
  if (bmp->line[y][x] > 0) 
   bmp->line[y][x] = c;
 }  
} 

Postelaborazione

Lo stato attuale dell'effetto sembra abbastanza orribile di per sé, la risoluzione non è accettabile, il modello wireframe è troppo semplice. Ma con la postelaborazione diventa un po' migliore.

Il mini buffer corrente viene copiato nel buffer posteriore, ma ogni pixel viene sostituito da un glifo:

for (i = 0; i < map->w; i++)
{
 for (j = 0; j < map->h; j++)
 {
  txt[0] = letter;
  textout_ex(back_buffer, matrix_font, txt, 
			 i*font_width, j*font_height, // x, y
			 map->line[j][i], 0);
 }
}

il letter è un codice char che verrà mostrato sullo schermo. In realtà abbiamo diverse opzioni qui:

  • casuale (originariamente implementato) - i glifi cambiano ogni fotogramma
  • basato su pos + colore (i glifi non cambiano):questo è ciò che puoi vedere nella clip di YouTube compilata.
  • predefinito:come quando premi F2 vedrai '+Modalità Fen' :)

Ricompilazione del vecchio codice

Sono rimasto piuttosto sorpreso dal fatto che il file exe originale funzionasse bene sulla mia macchina Win10!. Potrei semplicemente fare doppio clic sul file e giocare con l'effetto. Tuttavia, si sono verificati alcuni problemi con la selezione di una buona risoluzione.

L'immagine sopra mostra un'interfaccia utente predefinita per il selettore della modalità Allegro GFX. Come puoi vedere, la maggior parte di questo è per Windows/monitor con proporzioni 4:3! Nessuna opzione HD purtroppo. E, cosa più problematica:non ho potuto abilitare la modalità a schermo intero.

Ho deciso che sarebbe stato bello se potessi farlo funzionare in risoluzione HD o almeno dare più opzioni di dimensioni. Ma come ricompilare questa cosa? Ho quei vecchi strumenti...?

Ecco cosa ho raccolto:

  • Allegro 5 conteneva alcune modifiche sostanziali relative alla versione 4, quindi ricompilare il mio vecchio codice (che utilizzava la versione 4.03 ) non sarebbe stato così facile nella versione più recente.
  • Ho scaricato la versione 4.2.1 e sono stati necessari solo pochi aggiornamenti minori
  • DevCpp 4.9.2 è piuttosto vecchio e non è più aggiornato, ma puoi prendere Orwell DevCpp - http://orwelldevcpp.blogspot.com/

In qualche modo, dopo aver impostato di nuovo il progetto, assicurandomi di utilizzare il compilatore appropriato (MinGW, non TDM...) sorprendentemente potrei giocare con il codice!

Aggiornamenti

Volevo mantenere il vecchio effetto, ma sono stati comunque apportati alcuni aggiornamenti:

  • il codice è stato leggermente migliorato, ma per favore non usarlo per imparare C++! È piuttosto vecchio, codifica in stile C, molte variabili globali, cattiva denominazione delle variabili... ma funziona :D
  • Ho aggiunto l'opzione per passare la larghezza e l'altezza della finestra come parametri della riga di comando.
  • C'è una nuova opzione per interrompere l'animazione della telecamera:F4
  • Mostra mini buffer - F5
  • Inizialmente tutti i glifi erano casuali (quindi c'era molto sfarfallio), l'ho modificato un po' in modo che utilizzi un glifo basato sul valore x/y/col.

Idee future:

  • Riscrivilo su OpenGL... o forse anche su WebGL. Non ci sono molti contenuti da scaricare, quindi dovrebbe essere una piccola app web. Potremmo utilizzare un approccio simile, eseguire il rendering fuori schermo e quindi utilizzare l'effetto di post-elaborazione. La maggior parte delle cose potrebbe essere scritta in shader. Ci sono molti effetti simili su shadertoy.
  • Trova meglio, font a matrice
  • Ottimizza:questo è in realtà discutibile. L'effetto funziona abbastanza bene, anche in modalità id Debug! Potrei ottimizzarlo come esercizio, ma non sarebbe un grande vantaggio.

Riepilogo

GitHub Repo:https://github.com/fenbf/matrix - Fai attenzione alla qualità del codice... è davvero obsoleto! :)

Scarica il file exe originale:link qui

È stato davvero fantastico giocare con questo antico progetto. Erano passati più di 10 anni (13 per l'esattezza) quando ho implementato il codice. Fortunatamente, le mie capacità di programmazione sono migliorate e ora scrivo codice migliore. Ma in termini di creatività, a quel tempo probabilmente ero più bravo in questo. Mi piacerebbe tornare a scrivere tali demo e piccole animazioni.