~nch/gamelog

ref: 75432213d3972f26c03ef636da68ed482f0ac908 gamelog/draw_util.nim -rw-r--r-- 2.8 KiB View raw
75432213 — nc refactoring debug code out a bit 3 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
import opengl
import stb_image/read as stbi
import math

proc make_program*(shaders: varargs[(GLenum, string)]): uint32 =
    let program = gl_create_program()
    var shader_ids: seq[uint32] = @[]
    for (ty, source) in shaders:
        let shader = gl_create_shader(ty)
        let a = alloc_c_string_array([source])
        defer: dealloc_c_string_array(a)
        gl_shader_source(shader, 1, a, nil)
        gl_compile_shader(shader)
        gl_attach_shader(program, shader) # now attach to the main program
        shader_ids.add(shader)
    gl_link_program(program)
    for s in shader_ids:
        gl_delete_shader(s)
    return program

proc make_mesh*(vertex_data: seq[float32], face_indices: seq[uint16]): uint =
    var vao_id: GLuint
    gl_gen_vertex_arrays(1, vao_id.addr)
    assert vao_id != 0
    gl_bind_vertex_array(vao_id)
    var vbo_id: GLuint
    gl_gen_buffers(1, vbo_id.addr)

    gl_bind_buffer(GL_ARRAY_BUFFER, vbo_id)
    gl_buffer_data(GL_ARRAY_BUFFER, vertex_data.len * float32.sizeof, vertex_data[0].unsafeAddr, GL_STATIC_DRAW)

    gl_vertex_attrib_pointer(0, 3, cGL_FLOAT, false, 8 * float32.sizeof, cast[ptr int](0)) # pos
    gl_enable_vertex_attrib_array(0)
    gl_vertex_attrib_pointer(1, 3, cGL_FLOAT, false, 8 * float32.sizeof, cast[ptr int](3 * float32.sizeof)) # normal
    gl_enable_vertex_attrib_array(1)
    gl_vertex_attrib_pointer(2, 2, cGL_FLOAT, false, 8 * float32.sizeof, cast[ptr int](6 * float32.sizeof)) # uv
    gl_enable_vertex_attrib_array(2)

    var ebo_id: GLuint
    gl_gen_buffers(1, ebo_id.addr)

    gl_bind_buffer(GL_ELEMENT_ARRAY_BUFFER, ebo_id)
    gl_buffer_data(GL_ELEMENT_ARRAY_BUFFER, face_indices.len * uint16.sizeof, face_indices[0].unsafeAddr, GL_STATIC_DRAW)

    gl_bind_vertex_array(0)
    return vao_id

proc load_texture*(file: string): tuple[filepath: string, handle: GLuint64, width: uint16, height: uint16] =
    # TODO: check if the file existed first
    #let q = textures.where((file: file, id: _,
    var tex_id: GLuint
    var w, h, nchannels: int
    let data = stbi.load(file, w, h, nchannels, stbi.Default)

    gl_create_textures(GL_TEXTURE_2D, 1, tex_id.addr)
    gl_texture_parameteri(tex_id, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
    gl_texture_parameteri(tex_id, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
    gl_texture_parameteri(tex_id, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
    gl_texture_parameteri(tex_id, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    let num_mipmaps = (log2(float(max(w, h) + 1))).GLsizei;
    gl_texture_storage_2d(tex_id, num_mipmaps, GL_RGB8, w.GLsizei, h.GLsizei);
    gl_texture_subimage_2d(tex_id, 0, 0, 0, w.GLsizei, h.GLsizei, GL_RGBA, GL_UNSIGNED_BYTE, data[0].unsafeAddr)
    gl_generate_texture_mipmap(tex_id)

    let handle = gl_get_texture_handle_arb(tex_id)
    gl_make_texture_handle_resident_arb(handle)
    return (filepath: file, handle: handle, width: w.uint16, height: h.uint16)