summaryrefslogtreecommitdiff
path: root/render.h
blob: a2bc06bab7ef89d69b44530ed23e1fa03845e676 (plain)
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
#ifndef render_h
#define render_h

void
clear_window(struct v3 color)
{
    glClearColor(color.x, color.y, color.z, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void
begin3d(struct window window, struct shader shader, struct camera cam)
{
    f32 ar = (f32)window.width / (f32)window.height;
    mat4 projection = perspective(camera, ar);
    mat4 view = camera_get_view_mat(camera);
    glUseProgram(shader.id);
    shader_set_mat4(shader, SHADER_PROJECTION_MATRIX, projection);
    shader_set_mat4(shader, SHADER_VIEW_MATRIX, view);
}

void end3d(void)
{
    glUseProgram(0);
}

void begin3d_alpha(prge_window_t window, shader_t shader, camera_t camera)
{
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    begin3d(window, shader, camera);
}

void end3d_alpha(void)
{
    end3d();
    glDisable(GL_BLEND);
}

void draw_mesh(mesh_t mesh)
{
    if (!mesh.vao) {
        printf("warning: trying to draw mesh that doesn't have vao\n");
        return;
    }

    glBindVertexArray(mesh.vao);

    for (i32 i = 0; i < mesh.ntextures; i++) {
        glActiveTexture(GL_TEXTURE0+i);
        glBindTexture(GL_TEXTURE_2D, mesh.textures[i].id);
    }

    if (mesh.ebo)
        glDrawElements(GL_TRIANGLES, mesh.nindices, GL_UNSIGNED_INT, 0);
    else
        glDrawArrays(GL_TRIANGLES, 0, mesh.nvertices);

    glBindTexture(GL_TEXTURE_2D, 0);

    glBindVertexArray(0);
} 

void draw_model(shader_t shader, model_t model)
{
    mat4 modelmat = apply_transform(model.transform);
    for (i32 i = 0; i < model.nmeshes; ++i) {
        mat4 meshmat = apply_transform(model.meshes[i].transform);
        mat4 resultmat = mat4_mul(modelmat, meshmat);

        shader_set_mat4(shader, SHADER_MODEL_MATRIX, resultmat);
        draw_mesh(model.meshes[i]);
    }
}

void draw_entity(shader_t shader, entity_t entity)
{
    v3 position = entity.model.transform.position;
    position = v3_add(position, entity.position);
    entity.model.transform.position = position;
    draw_model(shader, entity.model);
}

void draw_entities(elist_t entities, shader_t shader)
{
    for (enode_t *node = entities.first; node; node = node->next)
        if (!(node->entity.flags & ENTITY_ALPHA))
            draw_entity(shader, node->entity);
}

void draw_entities_alpha(elist_t entities, shader_t shader)
{
    for (enode_t *node = entities.first; node; node = node->next)
        if (node->entity.flags & ENTITY_ALPHA)
            draw_entity(shader, node->entity);
}