A 3D game engine from scratch.
at main 191 lines 5.4 kB view raw
1// (c) 2020 Vlad-Stefan Harbuz <vlad@vladh.net> 2 3#include "../src_external/glad/glad.h" 4#include "shaders.hpp" 5#include "util.hpp" 6#include "logs.hpp" 7#include "debugdraw.hpp" 8#include "intrinsics.hpp" 9 10 11debugdraw::State *debugdraw::state = nullptr; 12 13 14void 15debugdraw::draw_line(v3 start_pos, v3 end_pos, v4 color) 16{ 17 DebugDrawVertex vertices[2]; 18 vertices[0] = { start_pos, color }; 19 vertices[1] = { end_pos, color }; 20 push_vertices(vertices, 2); 21} 22 23 24void 25debugdraw::draw_ray(spatial::Ray *ray, f32 length, v4 color) 26{ 27 v3 end_pos = ray->origin + ray->direction * length; 28 v3 x_axis = util::get_orthogonal_vector(&ray->direction); 29 v3 z_axis = cross(ray->direction, x_axis); 30 f32 chevron_size = 0.2f; 31 v3 chevron_1_pos = end_pos + ((-ray->direction + x_axis) * chevron_size); 32 v3 chevron_2_pos = end_pos + ((-ray->direction - x_axis) * chevron_size); 33 v3 chevron_3_pos = end_pos + ((-ray->direction + z_axis) * chevron_size); 34 v3 chevron_4_pos = end_pos + ((-ray->direction - z_axis) * chevron_size); 35 draw_line(ray->origin, end_pos, color); 36 draw_line(chevron_1_pos, end_pos, color); 37 draw_line(chevron_2_pos, end_pos, color); 38 draw_line(chevron_3_pos, end_pos, color); 39 draw_line(chevron_4_pos, end_pos, color); 40} 41 42 43void 44debugdraw::draw_quad( 45 v3 p1, // clockwise: top left 46 v3 p2, // top right 47 v3 p3, // bottom right 48 v3 p4, // bottom left 49 v4 color 50) { 51 draw_line(p1, p2, color); 52 draw_line(p2, p3, color); 53 draw_line(p3, p4, color); 54 draw_line(p4, p1, color); 55} 56 57 58void 59debugdraw::draw_box( 60 v3 p1, // clockwise top face: top left 61 v3 p2, // top right 62 v3 p3, // bottom right 63 v3 p4, // top left 64 v3 p5, // clockwise bottom face: top left 65 v3 p6, // top right 66 v3 p7, // bottom right 67 v3 p8, // top left 68 v4 color 69) { 70 draw_quad(p1, p2, p3, p4, color); 71 draw_quad(p5, p6, p7, p8, color); 72 draw_quad(p1, p2, p6, p5, color); 73 draw_quad(p2, p3, p7, p6, color); 74 draw_quad(p3, p4, p8, p7, color); 75 draw_quad(p4, p1, p5, p8, color); 76} 77 78 79void 80debugdraw::draw_obb(spatial::Obb *obb, v4 color) 81{ 82 v3 z_axis = cross(obb->x_axis, obb->y_axis); 83 v3 dir1 = obb->x_axis * obb->extents[0]; 84 v3 dir2 = obb->y_axis * obb->extents[1]; 85 v3 dir3 = z_axis * obb->extents[2]; 86 v3 p1 = obb->center - dir1 + dir2 - dir3; 87 v3 p2 = obb->center + dir1 + dir2 - dir3; 88 v3 p3 = obb->center + dir1 + dir2 + dir3; 89 v3 p4 = obb->center - dir1 + dir2 + dir3; 90 v3 p5 = obb->center - dir1 - dir2 - dir3; 91 v3 p6 = obb->center + dir1 - dir2 - dir3; 92 v3 p7 = obb->center + dir1 - dir2 + dir3; 93 v3 p8 = obb->center - dir1 - dir2 + dir3; 94 draw_quad(p1, p2, p3, p4, color); 95 draw_quad(p5, p6, p7, p8, color); 96 draw_quad(p1, p2, p6, p5, color); 97 draw_quad(p2, p3, p7, p6, color); 98 draw_quad(p3, p4, p8, p7, color); 99 draw_quad(p4, p1, p5, p8, color); 100} 101 102 103void 104debugdraw::draw_point(v3 position, f32 size, v4 color) 105{ 106 spatial::Obb obb = { 107 .center=position, 108 .x_axis=v3(1.0f, 0.0f, 0.0f), 109 .y_axis=v3(0.0f, 1.0f, 0.0f), 110 .extents=v3(size), 111 }; 112 draw_obb(&obb, color); 113} 114 115 116void 117debugdraw::clear() 118{ 119 debugdraw::state->n_vertices_pushed = 0; 120} 121 122 123void 124debugdraw::render() 125{ 126 glBindVertexArray(debugdraw::state->vao); 127 glBindBuffer(GL_ARRAY_BUFFER, debugdraw::state->vbo); 128 glBufferData(GL_ARRAY_BUFFER, 129 VERTEX_SIZE * debugdraw::state->n_vertices_pushed, 130 debugdraw::state->vertices, GL_STATIC_DRAW); 131 132 glUseProgram(debugdraw::state->shader_asset.program); 133 134 glDrawArrays(GL_LINES, 0, debugdraw::state->n_vertices_pushed); 135} 136 137 138void 139debugdraw::init(debugdraw::State *debug_draw_state, memory::Pool *memory_pool) 140{ 141 debugdraw::state = debug_draw_state; 142 143 memory::Pool temp_memory_pool = {}; 144 145 // Shaders 146 { 147 shaders::init_shader_asset(&debugdraw::state->shader_asset, 148 &temp_memory_pool, "debugdraw", shaders::Type::standard, 149 "debugdraw.vert", "debugdraw.frag", ""); 150 debugdraw::state->shader_asset.did_set_texture_uniforms = true; 151 } 152 153 // VAO 154 { 155 glGenVertexArrays(1, &debugdraw::state->vao); 156 glGenBuffers(1, &debugdraw::state->vbo); 157 glBindVertexArray(debugdraw::state->vao); 158 glBindBuffer(GL_ARRAY_BUFFER, debugdraw::state->vbo); 159 glBufferData(GL_ARRAY_BUFFER, VERTEX_SIZE * MAX_N_VERTICES, NULL, GL_DYNAMIC_DRAW); 160 161 u32 location; 162 163 // position (vec3) 164 location = 0; 165 glEnableVertexAttribArray(location); 166 glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE, VERTEX_SIZE, 167 (void*)(0)); 168 169 // color (vec4) 170 location = 1; 171 glEnableVertexAttribArray(location); 172 glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE, VERTEX_SIZE, 173 (void*)(3 * sizeof(f32))); 174 } 175 176 memory::destroy_memory_pool(&temp_memory_pool); 177} 178 179 180void 181debugdraw::push_vertices(DebugDrawVertex vertices[], u32 n_vertices) 182{ 183 if (debugdraw::state->n_vertices_pushed + n_vertices > MAX_N_VERTICES) { 184 logs::error("Pushed too many DebugDraw vertices, did you forget to call debugdraw::clear()?"); 185 return; 186 } 187 range (0, n_vertices) { 188 debugdraw::state->vertices[debugdraw::state->n_vertices_pushed + idx] = vertices[idx]; 189 } 190 debugdraw::state->n_vertices_pushed += n_vertices; 191}