~nch/gamelog

ref: 2860fd647c20bdd08c60e5362e2ecffd9a4c1961 gamelog/debug_draw.nim -rw-r--r-- 3.0 KiB View raw
2860fd64 — nc minor reorg 2 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
90
91
92
93
94
95
96
97
import opengl
import glm
import sequtils
import draw_util

type DebugCtx = tuple
    mesh: seq[Vec3f]
    buffer: GLuint
    buffer_vao: GLuint
    prog: GLuint

proc init_debug*(): DebugCtx =
    var c: DebugCtx
    c.mesh = @[]
    c.prog = make_program((GL_VERTEX_SHADER, """
#version 450 core
    layout(location = 0) in vec3 vpos;
    uniform mat4 MVP;
    void main() {
       gl_Position = MVP * vec4(vpos, 1.0);
    }
    """),
    (GL_FRAGMENT_SHADER, """
#version 450 core

    out vec3 color;
    uniform sampler2D diffuse;

    void main() {
        color = vec3(1, 1, 0);
    }
    """))

    # setup debug draw buffer
    gl_create_vertex_arrays(1, c.buffer_vao.addr)
    gl_create_buffers(1, c.buffer.addr)
    gl_enable_vertex_array_attrib(c.buffer_vao, 0)
    gl_vertex_array_vertex_buffer(c.buffer_vao, 0, c.buffer, 0, Vec3f.sizeof.GLsizei)
    gl_vertex_array_attrib_format(c.buffer_vao, 0, 3, cGL_FLOAT, false, 0) # pos
    gl_named_buffer_data(c.buffer, Vec3f.sizeof * 1024, nil, GL_DYNAMIC_DRAW)

    return c

proc clear*(c: var DebugCtx) =
    c.mesh.set_len(0)

proc draw*(c: DebugCtx, mvp: var Mat4f) =
    if len(c.mesh) > 0:
        gl_use_program(c.prog)

        let p = gl_map_named_buffer(c.buffer, GL_WRITE_ONLY)
        copy_mem(p, c.mesh[0].unsafeAddr, Vec3f.sizeof * len(c.mesh))
        discard gl_unmap_named_buffer(c.buffer)

        gl_bind_vertex_array(c.buffer_vao)
        gl_bind_buffer(GL_ARRAY_BUFFER, c.buffer)
        gl_uniform_matrix4fv(gl_get_uniform_location(c.prog, "MVP"), 1, false, mvp.caddr)
        gl_point_size(5)
        gl_draw_arrays(GL_LINES, 0, (len(c.mesh)).GLsizei)
        gl_draw_arrays(GL_POINTS, 0, (len(c.mesh)).GLsizei)

proc edge*(c: var DebugCtx, vs: varargs[Vec3f]) =
    for (a, b) in zip(vs, vs[1..^1]):
        c.mesh.add(a)
        c.mesh.add(b)

proc sphere*(c: var DebugCtx, pos: Vec3f, radius: float32, np: uint = 8, nm: uint = 16) =
    for j in 0 ..< np:
        let pp = PI * (j).float / np.float
        let p = PI * (j + 1).float / np.float
        let
            spp = sin(pp)
            cpp = cos(pp)
        let
            sp = sin(p)
            cp = cos(p)
        for i in 1.. nm:
            let pm = 2.0 * PI * (i - 1).float / nm.float
            let m = 2.0 * PI * i.float / nm.float
            # ring
            c.edge(
                pos + radius * vec3f(sp * cos(pm), cp, sp * sin(pm)),
                pos + radius * vec3f(sp * cos(m), cp, sp * sin(m)))
            # connecting edge
            c.edge(
                pos + radius * vec3f(spp * cos(m), cpp, spp * sin(m)),
                pos + radius * vec3f(sp * cos(m), cp, sp * sin(m)))

proc AABB*(c: var DebugCtx, a, b: Vec3f) =
    c.edge(a, vec3f(a.x, b.y, a.z), vec3f(b.x, b.y, a.z), vec3f(b.x, a.y, a.z), a)
    c.edge(vec3f(a.x, a.y, b.z), vec3f(a.x, b.y, b.z), vec3f(b.x, b.y, b.z), vec3f(b.x, a.y, b.z), vec3f(a.x, a.y, b.z))

    c.edge(vec3f(a.x, a.y, a.z), vec3f(a.x, a.y, b.z))
    c.edge(vec3f(b.x, a.y, a.z), vec3f(b.x, a.y, b.z))
    c.edge(vec3f(b.x, b.y, a.z), vec3f(b.x, b.y, b.z))
    c.edge(vec3f(a.x, b.y, a.z), vec3f(a.x, b.y, b.z))