~zjm/Moon3D

ref: 0e81b821a0782674dbed435a58ad682e7aef0282 Moon3D/src/3d/render.c -rw-r--r-- 2.4 KiB
0e81b821Zack Michener wrap rendering objects in a RenderingContext struct 5 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include "render.h"
#include "../arraylist.h"
#include "image.h"
#include "device.h"
#include "abstract.h"

RenderingContext MakeRenderingContext(Viewport *viewport, Camera *camera, RasterSettings settings)
{
	RenderingContext context;
	context.viewport = viewport;
	context.camera = camera;
	context.settings = settings;
	return context;
}

void DrawObject(Object *object, LightSource **lights, RenderingContext context)
{
	Transform t = ComposeTransform(Translation(object->position), object->transform);
	for (int i = 0; i < NumFacets(object->geometry); i++) {
		Polygon *modeled = FromPolygon(object->geometry->facets[i], t);
		Color shade = LightPolygon(modeled, object->color, object->glow, lights);
		DrawPolygon(modeled, shade, context);
		FreePolygon(modeled);
	}
}

void DrawPolygon(Polygon *polygon, Color color, RenderingContext context)
{
	Polygon *image = ProjectPolygon(polygon);
	if (ClipPolygon(&image)) {
		if (!BackfaceCulled(image)) {
			HomogenizePolygon(image);
			ViewmapPolygon(image);
			RasterPolygon(image, color, context.viewport, context.settings);
			if (context.settings.showWireframes) {
				WireframePolygon(image, BLACK, context.viewport);
			}
		}
	}
	FreePolygon(image);
}

void WireframePolygon(Polygon *polygon, Color color, Viewport *viewport)
{
	Vertex *a, *b;
	for (int i = 0; i < NumVertices(polygon); i++) {
		a = PolygonVertex(polygon, i);
		b = PolygonVertex(polygon, i+1);
		RasterLine(*a, *b, color, viewport);
	}
}

void DrawPoint(Point *p, RenderingContext context)
{
	Vector projected = ProjectPoint(p->position);
	if (ClipPoint(projected)) {
		Vector mapped = ViewmapPoint(Homogenize(projected));
		if (UpdateDepthBuffer(mapped.x, mapped.y, mapped.z, context.viewport)) {
			WritePixel(mapped.x, mapped.y, p->color, context.viewport);
		}
	}
}

void DrawLine(Vertex a, Vertex b, Color color, Viewport *viewport)
{
	Vector ap = ProjectPoint(a);
	Vector bp = ProjectPoint(b);
	Vector ac = ap;
	Vector bc = bp;
	if (ClipLine(&ac, &bc)) {
		Vertex av = ViewmapPoint(Homogenize(ac));
		Vertex bv = ViewmapPoint(Homogenize(bc));
		RasterLine(av, bv, color, viewport);
	}
}

void DrawAxes(Viewport *viewport)
{
	DrawLine(V(0, 0, 0), V(10, 0, 0), LT_GRAY, viewport);
	DrawLine(V(0, 0, 0), V(0, 10, 0), LT_GRAY, viewport);
	DrawLine(V(0, 0, 0), V(0, 0, 10), LT_GRAY, viewport);
}

bool BackfaceCulled(Polygon *polygon)
{
	Vector normal = PolygonNormal(polygon);
	return normal.z <= 0;
}