1+ class Renderer {
2+
3+ static fill = true ;
4+
5+ static canvas ;
6+ static context ;
7+ static width ;
8+ static height ;
9+ static displayBuffer ;
10+ static drawBuffer ;
11+ static depthBuffer ;
12+
13+ static init ( canvas , ctx ) {
14+ this . canvas = canvas ;
15+ this . context = ctx ;
16+ this . width = canvas . width ;
17+ this . height = canvas . height ;
18+ this . initializeBuffers ( ) ;
19+ }
20+
21+ static swapBuffers ( ) {
22+ let temp = this . displayBuffer ;
23+ this . displayBuffer = this . drawBuffer ;
24+ this . drawBuffer = temp ;
25+ this . clearDrawBuffer ( ) ;
26+ this . drawDisplay ( )
27+ }
28+
29+ static clearDrawBuffer ( ) {
30+ for ( let i = 0 ; i < this . width ; i ++ ) {
31+ this . drawBuffer [ i ] = new Array ( this . height ) ;
32+ this . depthBuffer [ i ] = new Array ( this . height ) ;
33+ }
34+ }
35+
36+ static drawDisplay ( ) {
37+ this . context . clearRect ( 0 , 0 , this . width , this . height ) ;
38+ let id = this . context . getImageData ( 0 , 0 , this . width , this . height ) ;
39+ let px = id . data ;
40+ for ( let y = 0 ; y < this . height ; y ++ ) {
41+ for ( let x = 0 ; x < this . width ; x ++ ) {
42+ let offset = ( y * id . width + x ) * 4 ;
43+ let data = this . displayBuffer [ x ] [ y ] ;
44+ if ( data == null ) continue ;
45+ px [ offset ++ ] = data . r ;
46+ px [ offset ++ ] = data . g ;
47+ px [ offset ++ ] = data . b ;
48+ px [ offset ] = 255 ;
49+ }
50+ }
51+ this . context . putImageData ( id , 0 , 0 ) ;
52+ }
53+
54+ static draw ( model ) {
55+
56+ }
57+
58+ static drawTriangle ( positions , colors ) {
59+ let p1 = this . positionToPixel ( positions [ 0 ] ) ;
60+ let p2 = this . positionToPixel ( positions [ 1 ] ) ;
61+ let p3 = this . positionToPixel ( positions [ 2 ] ) ;
62+ this . drawPixel ( p1 , colors [ 0 ] ) ;
63+ this . drawPixel ( p2 , colors [ 1 ] ) ;
64+ this . drawPixel ( p3 , colors [ 2 ] ) ;
65+ let lines = plotLine ( p1 , p2 ) ;
66+ lines = lines . concat ( plotLine ( p1 , p3 ) ) ;
67+ lines = lines . concat ( plotLine ( p2 , p3 ) ) ;
68+ let scanLines = { } ;
69+ for ( let i = 0 ; i < lines . length ; i ++ ) {
70+ this . drawPixel ( lines [ i ] , colors [ 0 ] ) ;
71+ let y = lines [ i ] . y ;
72+ if ( scanLines [ y ] == undefined ) {
73+ scanLines [ y ] = { x : [ ] , z : [ ] } ;
74+ }
75+ ( scanLines [ y ] . x ) . push ( lines [ i ] . x ) ;
76+ ( scanLines [ y ] . z ) . push ( lines [ i ] . z ) ;
77+ }
78+ if ( ! this . fill ) return ;
79+ for ( const [ y , obj ] of Object . entries ( scanLines ) ) {
80+ let listX = obj . x ;
81+ // Still have to interpolate Z some time
82+ let listZ = obj . z ;
83+ if ( listX . length == 0 ) continue ;
84+ listX . sort ( ) ;
85+ let pixels = plotLine ( new Vector2 ( listX [ 0 ] , y ) , new Vector2 ( listX [ listX . length - 1 ] , y ) ) ;
86+ for ( let i = 0 ; i < pixels . length ; i ++ ) {
87+ this . drawPixel ( pixels [ i ] , colors [ 0 ] ) ;
88+ }
89+ }
90+ }
91+
92+ static positionToPixel ( position ) {
93+ let x = Math . floor ( ( position . x + 1 ) * this . width / 2 ) ;
94+ let y = Math . floor ( ( - position . y + 1 ) * this . height / 2 ) ;
95+ return new Vector2 ( x , y ) ;
96+ }
97+
98+ static drawPixel ( position , color ) {
99+ if ( this . depthBuffer [ position . x ] [ position . y ] == null || this . depthBuffer [ position . x ] [ position . y ] < position . z ) {
100+ this . drawBuffer [ position . x ] [ position . y ] = new Color ( color . r , color . g , color . b ) ;
101+ this . depthBuffer [ position . x ] [ position . y ] = position . z ;
102+ }
103+ }
104+
105+ static initializeBuffers ( ) {
106+ this . displayBuffer = new Array ( this . width ) ;
107+ this . drawBuffer = new Array ( this . width ) ;
108+ this . depthBuffer = new Array ( this . width ) ;
109+ for ( let i = 0 ; i < this . width ; i ++ ) {
110+ this . displayBuffer [ i ] = new Array ( this . height ) ;
111+ this . drawBuffer [ i ] = new Array ( this . height ) ;
112+ this . depthBuffer [ i ] = new Array ( this . height ) ;
113+ }
114+ }
115+
116+ }
0 commit comments