1 /*
2 * This software is licensed under the terms of the MIT License.
3 * See COPYING for further information.
4 * ---
5 * Copyright (c) 2011-2019, Lukas Weber <laochailan@web.de>.
6 * Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
7 */
8
9 #include "taisei.h"
10
11 #include "models.h"
12 #include "../api.h"
13 #include "resource/model.h"
14
15 static struct {
16 VertexBuffer *vbuf;
17 IndexBuffer *ibuf;
18 VertexArray *varr;
19 Model quad;
20 } _r_models;
21
_r_models_init(void)22 void _r_models_init(void) {
23 VertexAttribFormat fmt[3];
24
25 r_vertex_attrib_format_interleaved(3, (VertexAttribSpec[]) {
26 { 3, VA_FLOAT, VA_CONVERT_FLOAT }, // position
27 { 3, VA_FLOAT, VA_CONVERT_FLOAT }, // normal
28 { 2, VA_FLOAT, VA_CONVERT_FLOAT }, // texcoord
29 }, fmt, 0);
30
31 GenericModelVertex quad[4] = {
32 { { 0.5, -0.5, 0.0 }, { 0, 0, 1 }, { 1, 1 } },
33 { { -0.5, -0.5, 0.0 }, { 0, 0, 1 }, { 0, 1 } },
34 { { 0.5, 0.5, 0.0 }, { 0, 0, 1 }, { 1, 0 } },
35 { { -0.5, 0.5, 0.0 }, { 0, 0, 1 }, { 0, 0 } },
36 };
37
38 const size_t max_vertices = 8192;
39
40 _r_models.vbuf = r_vertex_buffer_create(max_vertices * sizeof(GenericModelVertex), NULL);
41 r_vertex_buffer_set_debug_label(_r_models.vbuf, "Static models vertex buffer");
42
43 _r_models.ibuf = r_index_buffer_create(max_vertices);
44 r_index_buffer_set_debug_label(_r_models.ibuf, "Static models index buffer");
45
46 _r_models.varr = r_vertex_array_create();
47 r_vertex_array_set_debug_label(_r_models.varr, "Static models vertex array");
48 r_vertex_array_layout(_r_models.varr, 3, fmt);
49 r_vertex_array_attach_vertex_buffer(_r_models.varr, _r_models.vbuf, 0);
50 r_vertex_array_attach_index_buffer(_r_models.varr, _r_models.ibuf);
51
52 r_model_add_static(&_r_models.quad, PRIM_TRIANGLE_STRIP, 4, quad, NULL);
53 }
54
_r_models_shutdown(void)55 void _r_models_shutdown(void) {
56 r_vertex_array_destroy(_r_models.varr);
57 r_vertex_buffer_destroy(_r_models.vbuf);
58 }
59
r_model_add_static(Model * out_mdl,Primitive prim,size_t num_vertices,GenericModelVertex vertices[num_vertices],uint indices[num_vertices])60 void r_model_add_static(Model *out_mdl, Primitive prim, size_t num_vertices, GenericModelVertex vertices[num_vertices], uint indices[num_vertices]) {
61 out_mdl->vertex_array = _r_models.varr;
62 out_mdl->num_vertices = num_vertices;
63 out_mdl->primitive = prim;
64
65 SDL_RWops *vert_stream = r_vertex_buffer_get_stream(_r_models.vbuf);
66 size_t vert_ofs = SDL_RWtell(vert_stream) / sizeof(GenericModelVertex);
67
68 if(indices != NULL) {
69 out_mdl->offset = r_index_buffer_get_offset(_r_models.ibuf);
70 r_index_buffer_add_indices(_r_models.ibuf, vert_ofs, num_vertices, indices);
71 out_mdl->indexed = true;
72 } else {
73 out_mdl->offset = vert_ofs;
74 out_mdl->indexed = false;
75 }
76
77 SDL_RWwrite(vert_stream, vertices, sizeof(GenericModelVertex), num_vertices);
78 }
79
r_vertex_buffer_static_models(void)80 VertexBuffer* r_vertex_buffer_static_models(void) {
81 return _r_models.vbuf;
82 }
83
r_vertex_array_static_models(void)84 VertexArray* r_vertex_array_static_models(void) {
85 return _r_models.varr;
86 }
87
r_draw_quad(void)88 void r_draw_quad(void) {
89 r_draw_model_ptr(&_r_models.quad, 0, 0);
90 }
91
r_draw_quad_instanced(uint instances)92 void r_draw_quad_instanced(uint instances) {
93 r_draw_model_ptr(&_r_models.quad, instances, 0);
94 }
95
r_draw_model_ptr(Model * model,uint instances,uint base_instance)96 void r_draw_model_ptr(Model *model, uint instances, uint base_instance) {
97 (model->indexed ? r_draw_indexed : r_draw)(
98 model->vertex_array,
99 model->primitive,
100 model->offset, model->num_vertices,
101 instances,
102 base_instance
103 );
104 }
105