Skip to content

Commit 32ddefd

Browse files
committed
Local progress
0 parents  commit 32ddefd

File tree

9 files changed

+282
-0
lines changed

9 files changed

+282
-0
lines changed

bresenham.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
function plotLineLow(p0, p1) {
2+
let x0 = p0.x; let y0 = p0.y;
3+
let x1 = p1.x; let y1 = p1.y;
4+
let depth = p0.z;
5+
let len = p1.x - p0.x;
6+
if (len == 0) len = 1;
7+
let depthStep = (p1.z - p0.z) / len;
8+
let result = [];
9+
let dx = x1 - x0;
10+
let dy = y1 - y0;
11+
let yi = 1;
12+
if (dy < 0) {
13+
yi = -1;
14+
dy = -dy;
15+
}
16+
let D = (2 * dy) - dx;
17+
let y = y0;
18+
for (let x = x0; x <= x1; x++) {
19+
result.push(new Vector3(x, y, depth));
20+
depth += depthStep;
21+
if (D > 0) {
22+
y = y + yi;
23+
D = D + (2 * (dy - dx));
24+
} else {
25+
D = D + 2 * dy;
26+
}
27+
}
28+
return result;
29+
}
30+
31+
function plotLineHigh(p0, p1) {
32+
let x0 = p0.x; let y0 = p0.y;
33+
let x1 = p1.x; let y1 = p1.y;
34+
let depth = p0.z;
35+
let len = p1.y - p0.y;
36+
if (len == 0) len = 1;
37+
let depthStep = (p1.z - p0.z) / len;
38+
let result = [];
39+
let dx = x1 - x0;
40+
let dy = y1 - y0;
41+
let xi = 1;
42+
if (dx < 0) {
43+
xi = -1;
44+
dx = -dx;
45+
}
46+
let D = (2 * dx) - dy;
47+
let x = x0;
48+
for (let y = y0; y <= y1; y++) {
49+
result.push(new Vector3(x, y, depth));
50+
depth += depthStep;
51+
if (D > 0) {
52+
x = x + xi;
53+
D = D + (2 * (dx - dy));
54+
} else {
55+
D = D + 2 * dx;
56+
}
57+
}
58+
return result;
59+
}
60+
61+
function plotLine(p0, p1) {
62+
if (Math.abs(p1.y - p0.y) < Math.abs(p1.x - p0.x)) {
63+
if (p0.x > p1.x) {
64+
return plotLineLow(p1, p0);
65+
} else {
66+
return plotLineLow(p0, p1);
67+
}
68+
} else {
69+
if (p0.y > p1.y) {
70+
return plotLineHigh(p1, p0);
71+
} else {
72+
return plotLineHigh(p0, p1);
73+
}
74+
}
75+
}

color.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Color {
2+
constructor(r, g, b) {
3+
this.r = r;
4+
this.g = g;
5+
this.b = b;
6+
}
7+
}

index.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>
5+
JS 3D Graphics Pipeline
6+
</title>
7+
</head>
8+
<body>
9+
<canvas id="canvas" width="100%" height="100%"></canvas>
10+
<script src="bresenham.js"></script>
11+
<script src="vector3.js"></script>
12+
<script src="vector2.js"></script>
13+
<script src="shader.js"></script>
14+
<script src="model.js"></script>
15+
<script src="color.js"></script>
16+
<script src="renderer.js"></script>
17+
<script src="index.js"></script>
18+
</body>
19+
</html>

index.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
let canvas;
2+
let context;
3+
4+
function init() {
5+
canvas = document.getElementById('canvas');
6+
ctx = canvas.getContext('2d');
7+
canvas.width = 50;//window.innerWidth;
8+
canvas.height = 50;//window.innerHeight;
9+
Renderer.init(canvas, ctx);
10+
}
11+
12+
async function loop() {
13+
//while (true) {
14+
await new Promise(resolve => setTimeout(resolve, 30))
15+
Renderer.drawTriangle([new Vector3(-0.5, -0.5, 0), new Vector3(0, 0.5, 0), new Vector3(0.5, -0.5, 0)],
16+
[new Color(0, 0, 0), new Color(0, 0, 0), new Color(0, 0, 0)])
17+
Renderer.swapBuffers();
18+
//}
19+
}
20+
21+
function terminate() {
22+
23+
}
24+
25+
init()
26+
loop()
27+
terminate()

model.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class Model {
2+
3+
constructor(positions, normals) {
4+
this.positions = positions;
5+
this.normals = normals;
6+
this.pd = 3;
7+
this.nd = 3;
8+
}
9+
10+
}

renderer.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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+
}

shader.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Shader {
2+
3+
static vertex(position, normal) {
4+
5+
}
6+
7+
static pixel() {
8+
9+
}
10+
11+
}

vector2.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class Vector2 {
2+
3+
constructor(x, y) {
4+
this.x = x;
5+
this.y = y;
6+
}
7+
8+
}

vector3.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class Vector3 {
2+
3+
constructor(x, y, z) {
4+
this.x = x;
5+
this.y = y;
6+
this.z = z;
7+
}
8+
9+
}

0 commit comments

Comments
 (0)