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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
#include "asset.hpp"
#include "camera.hpp"
#include "debugdraw.hpp"
#include "video.hpp"
extern "C" {
#include "plat.h"
}
void Line_Renderer::init(Device* dev, Asset_Arena* assets) {
vb.init(
dev,
"Line Renderer mesh",
max_lines * sizeof(Vertex) * 2,
Buffer_Flags::vertex_buffer
);
cb.init(
dev,
"Line Renderer cbuffer",
sizeof(CBuffer),
Buffer_Flags::constant_buffer
);
shader = (Shader*)assets->load("debug.csh");
vert_binding = shader->binding_index("verts");
cbuffer_binding = shader->descriptor_binding("cbuf");
assert(vert_binding >= 0);
assert(cbuffer_binding >= 0);
verts = (Vertex*)vb.map(dev);
cur = 0;
}
void Line_Renderer::destroy(Device* dev) {
vb.unmap(dev);
vb.destroy(dev);
cb.destroy(dev);
}
void Line_Renderer::begin(int wi, int he) {
cur = 0;
w = wi;
h = he;
cur_col = v3f(1.0f, 1.0f, 1.0f);
}
void Line_Renderer::colour(const v3f& c) {
cur_col = c;
}
void Line_Renderer::add_line(const v3f& s, const v3f& e) {
if (cur >= max_lines) {
assert(0);
return;
}
Vertex& a = verts[cur * 2];
Vertex& b = verts[cur * 2 + 1];
a.x = s.x;
a.y = s.y;
a.z = s.z;
b.x = e.x;
b.y = e.y;
b.z = e.z;
a.r = cur_col.x;
a.g = cur_col.y;
a.b = cur_col.z;
b.r = cur_col.x;
b.g = cur_col.y;
b.b = cur_col.z;
cur++;
}
void Line_Renderer::add_box(const AABB& b) {
add_line(v3f(b.max.x, b.max.y, b.max.z), v3f(b.max.x, b.max.y, b.min.z));
add_line(v3f(b.max.x, b.max.y, b.max.z), v3f(b.max.x, b.min.y, b.max.z));
add_line(v3f(b.max.x, b.max.y, b.max.z), v3f(b.min.x, b.max.y, b.max.z));
add_line(v3f(b.max.x, b.min.y, b.min.z), v3f(b.max.x, b.max.y, b.min.z));
add_line(v3f(b.max.x, b.min.y, b.min.z), v3f(b.max.x, b.min.y, b.max.z));
add_line(v3f(b.min.x, b.max.y, b.max.z), v3f(b.min.x, b.min.y, b.max.z));
add_line(v3f(b.min.x, b.max.y, b.min.z), v3f(b.max.x, b.max.y, b.min.z));
add_line(v3f(b.min.x, b.max.y, b.min.z), v3f(b.min.x, b.max.y, b.max.z));
add_line(v3f(b.min.x, b.min.y, b.max.z), v3f(b.max.x, b.min.y, b.max.z));
add_line(v3f(b.min.x, b.min.y, b.min.z), v3f(b.max.x, b.min.y, b.min.z));
add_line(v3f(b.min.x, b.min.y, b.min.z), v3f(b.min.x, b.max.y, b.min.z));
add_line(v3f(b.min.x, b.min.y, b.min.z), v3f(b.min.x, b.min.y, b.max.z));
}
void Line_Renderer::flush(
const Camera& cam,
Device* dev,
Arena* a,
Render_Pass& rp
) {
if (!cur) return;
CBuffer* c = (CBuffer*)cb.map(dev);
c->vp = cam.get_proj() * cam.get_view();
cb.unmap(dev);
Pipeline_Builder pb(a, dev);
Context& ctx = dev->get_ctx();
cb.update(ctx);
vb.update(ctx);
pb.begin();
pb.shader(shader->id);
pb.cbuffer(cbuffer_binding, cb.gpuonly);
pb.vertex_format(shader->vf);
pb.geo(Geo_Type::lines);
if (rp.depth.id)
pb.depth(true, false, Depth_Mode::less);
Pipeline& pip = pb.build();
Vertex_Buffer_Binding binding[] = {{
.id = vb.gpuonly,
.offset = 0,
.target = vert_binding
}, {}};
Draw d{};
d.verts = binding;
d.vertex_count = cur * 2;
d.instance_count = 1;
ctx.submit(d, pip, rp);
cur = 0;
}
|