A 3D game engine from scratch.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

refactor last files! :)

+921 -895
-6
TODO.txt
··· 1 - peony_parser 2 - peony_parser_utils 3 - queue 4 - spatial 5 - stackarray 6 - util
+2 -2
src/behavior_functions.cpp
··· 37 37 logs::error("Could not get physics::Component for behavior::Component"); 38 38 return; 39 39 } 40 - Obb *obb = &physics_component->transformed_obb; 40 + spatial::Obb *obb = &physics_component->transformed_obb; 41 41 42 42 // Update position 43 43 spatial_component->position.x = ··· 96 96 // Check ray collision 97 97 #if 0 98 98 { 99 - Ray ray = { 99 + spatial::Ray ray = { 100 100 .origin = obb->center + obb->y_axis * obb->extents[1], 101 101 .direction = obb->y_axis, 102 102 };
+3 -3
src/debugdraw.cpp
··· 22 22 23 23 24 24 void 25 - debugdraw::draw_ray(Ray *ray, real32 length, v4 color) 25 + debugdraw::draw_ray(spatial::Ray *ray, real32 length, v4 color) 26 26 { 27 27 v3 end_pos = ray->origin + ray->direction * length; 28 28 v3 x_axis = util::get_orthogonal_vector(&ray->direction); ··· 77 77 78 78 79 79 void 80 - debugdraw::draw_obb(Obb *obb, v4 color) 80 + debugdraw::draw_obb(spatial::Obb *obb, v4 color) 81 81 { 82 82 v3 z_axis = cross(obb->x_axis, obb->y_axis); 83 83 v3 dir1 = obb->x_axis * obb->extents[0]; ··· 103 103 void 104 104 debugdraw::draw_point(v3 position, real32 size, v4 color) 105 105 { 106 - Obb obb = { 106 + spatial::Obb obb = { 107 107 .center=position, 108 108 .x_axis=v3(1.0f, 0.0f, 0.0f), 109 109 .y_axis=v3(0.0f, 1.0f, 0.0f),
+2 -2
src/debugdraw.hpp
··· 26 26 }; 27 27 28 28 static void draw_line(v3 start_pos, v3 end_pos, v4 color); 29 - static void draw_ray(Ray *ray, real32 length, v4 color); 29 + static void draw_ray(spatial::Ray *ray, real32 length, v4 color); 30 30 static void draw_quad( 31 31 v3 p1, // clockwise: top left 32 32 v3 p2, // top right ··· 45 45 v3 p8, // top left 46 46 v4 color 47 47 ); 48 - static void draw_obb(Obb *obb, v4 color); 48 + static void draw_obb(spatial::Obb *obb, v4 color); 49 49 static void draw_point(v3 position, real32 size, v4 color); 50 50 static void clear(); 51 51 static void render();
+7 -5
src/engine.cpp
··· 352 352 pstr_vcat(scene_path, MAX_PATH, SCENE_DIR, scene_name, SCENE_EXTENSION, NULL); 353 353 gui::log("Loading scene: %s", scene_path); 354 354 355 - PeonyFile *scene_file = MEMORY_PUSH(&temp_memory_pool, PeonyFile, "scene_file"); 355 + peony_parser::PeonyFile *scene_file = MEMORY_PUSH(&temp_memory_pool, 356 + peony_parser::PeonyFile, "scene_file"); 356 357 if (!peony_parser::parse_file(scene_file, scene_path)) { 357 358 gui::log("Could not load scene: %s", scene_path); 358 359 return false; ··· 369 370 scene_file, &used_materials, "materials"); 370 371 371 372 // Create Materials 372 - PeonyFile *material_file = MEMORY_PUSH(&temp_memory_pool, PeonyFile, "material_file"); 373 + peony_parser::PeonyFile *material_file = MEMORY_PUSH(&temp_memory_pool, 374 + peony_parser::PeonyFile, "material_file"); 373 375 each (used_material, used_materials) { 374 - memset(material_file, 0, sizeof(PeonyFile)); 376 + memset(material_file, 0, sizeof(peony_parser::PeonyFile)); 375 377 char material_file_path[MAX_PATH] = {}; 376 378 pstr_vcat(material_file_path, MAX_PATH, 377 379 MATERIAL_FILE_DIRECTORY, *used_material, MATERIAL_FILE_EXTENSION, nullptr); ··· 388 390 } 389 391 390 392 range (0, scene_file->n_entries) { 391 - PeonyFileEntry *entry = &scene_file->entries[idx]; 393 + peony_parser::Entry *entry = &scene_file->entries[idx]; 392 394 393 395 // Create entities::Entity 394 396 entities::Entity *entity = entities::add_entity_to_set(entry->name); ··· 397 399 char const *model_path = peony_parser_utils::get_string( 398 400 peony_parser_utils::find_prop(entry, "model_path") 399 401 ); 400 - // NOTE: We only want to make a models::ModelLoader from this PeonyFileEntry if we haven't 402 + // NOTE: We only want to make a models::ModelLoader from this peony_parser::Entry if we haven't 401 403 // already encountered this model in a previous entry. If two entities 402 404 // have the same `model_path`, we just make one model and use it in both. 403 405 models::ModelLoader *found_model_loader = engine::state->model_loaders.find(
+183 -169
src/peony_parser.cpp
··· 6 6 #include "intrinsics.hpp" 7 7 8 8 9 - namespace peony_parser { 10 - pny_internal void print_value(PeonyFilePropValue *value) { 11 - if (value->type == PeonyFilePropValueType::unknown) { 12 - logs::info("<unknown>"); 13 - } else if (value->type == PeonyFilePropValueType::string) { 14 - logs::info("%s", value->string_value); 15 - } else if (value->type == PeonyFilePropValueType::boolean) { 16 - logs::info("%d", value->boolean_value); 17 - } else if (value->type == PeonyFilePropValueType::number) { 18 - logs::info("%f", value->number_value); 19 - } else if (value->type == PeonyFilePropValueType::vec2) { 20 - logs::print_v2(&value->vec2_value); 21 - } else if (value->type == PeonyFilePropValueType::vec3) { 22 - logs::print_v3(&value->vec3_value); 23 - } else if (value->type == PeonyFilePropValueType::vec4) { 24 - logs::print_v4(&value->vec4_value); 9 + bool32 10 + peony_parser::parse_file(PeonyFile *pf, char const *path) 11 + { 12 + int32 idx_entry = -1; 13 + Entry *entry = nullptr; 14 + 15 + FILE *f = fopen(path, "r"); 16 + if (!f) { 17 + logs::error("Could not open file %s.", path); 18 + return false; 19 + } 20 + defer { fclose(f); }; 21 + 22 + char token[MAX_TOKEN_LENGTH]; 23 + 24 + while (get_non_trivial_token(token, f)) { 25 + if (token[0] == TOKEN_HEADER_START) { 26 + idx_entry++; 27 + entry = &pf->entries[idx_entry]; 28 + parse_header(token, f); 29 + pstr_copy(entry->name, MAX_TOKEN_LENGTH, token); 30 + } else if (is_token_name(token)) { 31 + if (!entry) { 32 + logs::fatal("Tried to parse file, but encountered data before header."); 33 + } 34 + Prop *prop = &entry->props[entry->n_props]; 35 + parse_property(prop, token, f); 36 + entry->n_props++; 37 + if (entry->n_props > MAX_N_ENTRY_PROPS) { 38 + logs::fatal("Too many props in peony file"); 39 + assert(false); 40 + } 41 + } else { 42 + logs::info("Unhandled token: %s", token); 43 + } 44 + } 45 + 46 + pf->n_entries = idx_entry + 1; 47 + return true; 48 + } 49 + 50 + 51 + void 52 + peony_parser::print_value(PropValue *value) 53 + { 54 + if (value->type == PropValueType::unknown) { 55 + logs::info("<unknown>"); 56 + } else if (value->type == PropValueType::string) { 57 + logs::info("%s", value->string_value); 58 + } else if (value->type == PropValueType::boolean) { 59 + logs::info("%d", value->boolean_value); 60 + } else if (value->type == PropValueType::number) { 61 + logs::info("%f", value->number_value); 62 + } else if (value->type == PropValueType::vec2) { 63 + logs::print_v2(&value->vec2_value); 64 + } else if (value->type == PropValueType::vec3) { 65 + logs::print_v3(&value->vec3_value); 66 + } else if (value->type == PropValueType::vec4) { 67 + logs::print_v4(&value->vec4_value); 25 68 } else { 26 - logs::info("<invalid>"); 69 + logs::info("<invalid>"); 27 70 } 28 - } 71 + } 29 72 30 73 31 - pny_internal bool32 is_char_whitespace(const char target) { 32 - return target == TOKEN_NEWLINE || 33 - target == TOKEN_SPACE; 34 - } 74 + bool32 75 + peony_parser::is_char_whitespace(const char target) 76 + { 77 + return target == TOKEN_NEWLINE || target == TOKEN_SPACE; 78 + } 35 79 36 80 37 - pny_internal bool32 is_token_whitespace(const char *token) { 81 + bool32 82 + peony_parser::is_token_whitespace(const char *token) 83 + { 38 84 return is_char_whitespace(token[0]); 39 - } 85 + } 40 86 41 87 42 - pny_internal bool32 is_char_allowed_in_name(const char target) { 43 - return isalpha(target) || 44 - isdigit(target) || 45 - target == '_' || 46 - target == '-' || 47 - target == '/' || 48 - target == ':' || 49 - target == '.'; 50 - } 88 + bool32 89 + peony_parser::is_char_allowed_in_name(const char target) 90 + { 91 + return isalpha(target) || isdigit(target) || target == '_' || target == '-' || 92 + target == '/' || target == ':' || target == '.'; 93 + } 51 94 52 95 53 - pny_internal bool32 is_token_name(const char *token) { 96 + bool32 97 + peony_parser::is_token_name(const char *token) 98 + { 54 99 range (0, pstr_len(token)) { 55 - if (!is_char_allowed_in_name(token[idx])) { 56 - return false; 57 - } 100 + if (!is_char_allowed_in_name(token[idx])) { 101 + return false; 102 + } 58 103 } 59 104 return true; 60 - } 105 + } 61 106 62 107 63 - pny_internal bool32 is_char_token_boundary(char target) { 108 + bool32 109 + peony_parser::is_char_token_boundary(char target) 110 + { 64 111 return is_char_whitespace(target) || 65 - target == TOKEN_HEADER_START || 66 - target == TOKEN_ELEMENT_SEPARATOR || 67 - target == TOKEN_TUPLE_START || 68 - target == TOKEN_TUPLE_END || 69 - target == TOKEN_ARRAY_START || 70 - target == TOKEN_ARRAY_END || 71 - target == TOKEN_OBJECT_START || 72 - target == TOKEN_OBJECT_END; 73 - } 112 + target == TOKEN_HEADER_START || 113 + target == TOKEN_ELEMENT_SEPARATOR || 114 + target == TOKEN_TUPLE_START || 115 + target == TOKEN_TUPLE_END || 116 + target == TOKEN_ARRAY_START || 117 + target == TOKEN_ARRAY_END || 118 + target == TOKEN_OBJECT_START || 119 + target == TOKEN_OBJECT_END; 120 + } 74 121 75 122 76 - pny_internal bool32 get_token(char *token, FILE *f) { 123 + bool32 124 + peony_parser::get_token(char *token, FILE *f) 125 + { 77 126 uint32 idx_token = 0; 78 127 bool32 could_get_token = true; 79 128 80 129 while (true) { 81 - char new_char = (char)fgetc(f); 130 + char new_char = (char)fgetc(f); 82 131 83 - *(token + idx_token) = new_char; 84 - idx_token++; 132 + *(token + idx_token) = new_char; 133 + idx_token++; 85 134 86 - if (is_char_token_boundary(new_char)) { 87 - if (idx_token - 1 == 0) { 88 - // Our first character is already a boundary. Radical! 89 - } else { 90 - // Return the boundary to the buffer so we can put it in its own token. 91 - ungetc(new_char, f); 92 - *(token + idx_token - 1) = '\0'; 135 + if (is_char_token_boundary(new_char)) { 136 + if (idx_token - 1 == 0) { 137 + // Our first character is already a boundary. Radical! 138 + } else { 139 + // Return the boundary to the buffer so we can put it in its own token. 140 + ungetc(new_char, f); 141 + *(token + idx_token - 1) = '\0'; 142 + } 143 + break; 93 144 } 94 - break; 95 - } 96 145 97 - if (new_char == EOF) { 98 - could_get_token = false; 99 - break; 100 - } 146 + if (new_char == EOF) { 147 + could_get_token = false; 148 + break; 149 + } 101 150 102 - if (idx_token >= MAX_TOKEN_LENGTH) { 103 - logs::error("Reached max token length for token %s.", token); 104 - break; 105 - } 151 + if (idx_token >= MAX_TOKEN_LENGTH) { 152 + logs::error("Reached max token length for token %s.", token); 153 + break; 154 + } 106 155 } 107 156 108 157 *(token + idx_token) = '\0'; 109 158 110 159 return could_get_token; 111 - } 160 + } 112 161 113 162 114 - pny_internal bool32 get_non_trivial_token(char *token, FILE *f) { 163 + bool32 164 + peony_parser::get_non_trivial_token(char *token, FILE *f) 165 + { 115 166 bool32 could_get_token; 116 167 do { 117 - could_get_token = get_token(token, f); 118 - if (token[0] == TOKEN_COMMENT_START) { 119 - while ((could_get_token = get_token(token, f)) != false) { 120 - if (token[0] == TOKEN_NEWLINE) { 121 - break; 122 - } 168 + could_get_token = get_token(token, f); 169 + if (token[0] == TOKEN_COMMENT_START) { 170 + while ((could_get_token = get_token(token, f)) != false) { 171 + if (token[0] == TOKEN_NEWLINE) { 172 + break; 173 + } 174 + } 123 175 } 124 - } 125 176 } while (is_token_whitespace(token) || token[0] == TOKEN_ELEMENT_SEPARATOR); 126 177 return could_get_token; 127 - } 178 + } 128 179 129 180 130 - pny_internal void parse_vec2(char *token, FILE *f, v2 *parsed_vector) { 181 + void 182 + peony_parser::parse_vec2(char *token, FILE *f, v2 *parsed_vector) 183 + { 131 184 get_non_trivial_token(token, f); 132 185 assert(token[0] == TOKEN_TUPLE_START); 133 186 get_non_trivial_token(token, f); ··· 136 189 (*parsed_vector).y = (real32)strtod(token, nullptr); 137 190 get_non_trivial_token(token, f); 138 191 assert(token[0] == TOKEN_TUPLE_END); 139 - } 192 + } 140 193 141 194 142 - pny_internal void parse_vec3(char *token, FILE *f, v3 *parsed_vector) { 195 + void 196 + peony_parser::parse_vec3(char *token, FILE *f, v3 *parsed_vector) 197 + { 143 198 get_non_trivial_token(token, f); 144 199 assert(token[0] == TOKEN_TUPLE_START); 145 200 get_non_trivial_token(token, f); ··· 150 205 (*parsed_vector).z = (real32)strtod(token, nullptr); 151 206 get_non_trivial_token(token, f); 152 207 assert(token[0] == TOKEN_TUPLE_END); 153 - } 208 + } 154 209 155 210 156 - pny_internal void parse_vec4(char *token, FILE *f, v4 *parsed_vector) { 211 + void 212 + peony_parser::parse_vec4(char *token, FILE *f, v4 *parsed_vector) 213 + { 157 214 get_non_trivial_token(token, f); 158 215 assert(token[0] == TOKEN_TUPLE_START); 159 216 get_non_trivial_token(token, f); ··· 166 223 (*parsed_vector).w = (real32)strtod(token, nullptr); 167 224 get_non_trivial_token(token, f); 168 225 assert(token[0] == TOKEN_TUPLE_END); 169 - } 226 + } 170 227 171 228 172 - pny_internal void get_value_from_token( 173 - char *token, FILE *f, PeonyFilePropValue *prop_value 174 - ) { 229 + void 230 + peony_parser::get_value_from_token(char *token, FILE *f, PropValue *prop_value) 231 + { 175 232 // NOTE: Type names the can start a value: vec2, vec3, vec4 176 233 if (pstr_eq(token, "vec2")) { 177 - prop_value->type = PeonyFilePropValueType::vec2; 178 - parse_vec2(token, f, &prop_value->vec2_value); 234 + prop_value->type = PropValueType::vec2; 235 + parse_vec2(token, f, &prop_value->vec2_value); 179 236 } else if (pstr_eq(token, "vec3")) { 180 - prop_value->type = PeonyFilePropValueType::vec3; 181 - parse_vec3(token, f, &prop_value->vec3_value); 237 + prop_value->type = PropValueType::vec3; 238 + parse_vec3(token, f, &prop_value->vec3_value); 182 239 } else if (pstr_eq(token, "vec4")) { 183 - prop_value->type = PeonyFilePropValueType::vec4; 184 - parse_vec4(token, f, &prop_value->vec4_value); 240 + prop_value->type = PropValueType::vec4; 241 + parse_vec4(token, f, &prop_value->vec4_value); 185 242 } else if (pstr_eq(token, "true")) { 186 - prop_value->type = PeonyFilePropValueType::boolean; 187 - prop_value->boolean_value = true; 243 + prop_value->type = PropValueType::boolean; 244 + prop_value->boolean_value = true; 188 245 } else if (pstr_eq(token, "false")) { 189 - prop_value->type = PeonyFilePropValueType::boolean; 190 - prop_value->boolean_value = false; 246 + prop_value->type = PropValueType::boolean; 247 + prop_value->boolean_value = false; 191 248 } else if (pstr_eq(token, "0.0") || strtod(token, nullptr) != 0.0f) { 192 - // NOTE: `strtod()` returns 0.0 if parsing fails, so we need to check 193 - // if our value actually was 0.0; 194 - prop_value->type = PeonyFilePropValueType::number; 195 - prop_value->number_value = (real32)strtod(token, nullptr); 249 + // NOTE: `strtod()` returns 0.0 if parsing fails, so we need to check 250 + // if our value actually was 0.0; 251 + prop_value->type = PropValueType::number; 252 + prop_value->number_value = (real32)strtod(token, nullptr); 196 253 } else { 197 - prop_value->type = PeonyFilePropValueType::string; 198 - pstr_copy(prop_value->string_value, MAX_TOKEN_LENGTH, token); 254 + prop_value->type = PropValueType::string; 255 + pstr_copy(prop_value->string_value, MAX_TOKEN_LENGTH, token); 199 256 } 200 - } 257 + } 201 258 202 259 203 - pny_internal void parse_header(char *token, FILE *f) { 260 + void 261 + peony_parser::parse_header(char *token, FILE *f) 262 + { 204 263 get_non_trivial_token(token, f); 205 264 assert(is_token_name(token)); 206 - } 265 + } 207 266 208 267 209 - pny_internal void parse_property( 210 - PeonyFileProp *prop, 211 - char *token, 212 - FILE *f 213 - ) { 268 + void 269 + peony_parser::parse_property(Prop *prop, char *token, FILE *f) 270 + { 214 271 pstr_copy(prop->name, MAX_TOKEN_LENGTH, token); 215 272 get_non_trivial_token(token, f); 216 273 assert(token[0] == TOKEN_EQUALS); 217 274 get_non_trivial_token(token, f); 218 275 219 - assert( 220 - is_token_name(token) || token[0] == TOKEN_ARRAY_START 221 - ); 276 + assert(is_token_name(token) || token[0] == TOKEN_ARRAY_START); 222 277 223 278 if (is_token_name(token)) { 224 - get_value_from_token(token, f, &prop->values[prop->n_values]); 225 - prop->n_values++; 226 - if (prop->n_values > MAX_N_ARRAY_VALUES) { 227 - logs::fatal("Too many array values in peony file"); 228 - assert(false); 229 - } 230 - } else if (token[0] == TOKEN_ARRAY_START) { 231 - while (true) { 232 - get_non_trivial_token(token, f); 233 - if (token[0] == TOKEN_ARRAY_END) { 234 - break; 235 - } 236 279 get_value_from_token(token, f, &prop->values[prop->n_values]); 237 280 prop->n_values++; 238 - } 239 - } 240 - } 241 - } 242 - 243 - 244 - bool32 peony_parser::parse_file(PeonyFile *pf, char const *path) { 245 - int32 idx_entry = -1; 246 - PeonyFileEntry *entry = nullptr; 247 - 248 - FILE *f = fopen(path, "r"); 249 - if (!f) { 250 - logs::error("Could not open file %s.", path); 251 - return false; 252 - } 253 - defer { fclose(f); }; 254 - 255 - char token[MAX_TOKEN_LENGTH]; 256 - 257 - while (get_non_trivial_token(token, f)) { 258 - if (token[0] == TOKEN_HEADER_START) { 259 - idx_entry++; 260 - entry = &pf->entries[idx_entry]; 261 - parse_header(token, f); 262 - pstr_copy(entry->name, MAX_TOKEN_LENGTH, token); 263 - } else if (is_token_name(token)) { 264 - if (!entry) { 265 - logs::fatal("Tried to parse file, but encountered data before header."); 266 - } 267 - PeonyFileProp *prop = &entry->props[entry->n_props]; 268 - parse_property(prop, token, f); 269 - entry->n_props++; 270 - if (entry->n_props > MAX_N_ENTRY_PROPS) { 271 - logs::fatal("Too many props in peony file"); 272 - assert(false); 273 - } 274 - } else { 275 - logs::info("Unhandled token: %s", token); 281 + if (prop->n_values > MAX_N_ARRAY_VALUES) { 282 + logs::fatal("Too many array values in peony file"); 283 + assert(false); 284 + } 285 + } else if (token[0] == TOKEN_ARRAY_START) { 286 + while (true) { 287 + get_non_trivial_token(token, f); 288 + if (token[0] == TOKEN_ARRAY_END) { 289 + break; 290 + } 291 + get_value_from_token(token, f, &prop->values[prop->n_values]); 292 + prop->n_values++; 293 + } 276 294 } 277 - } 278 - 279 - pf->n_entries = idx_entry + 1; 280 - return true; 281 295 }
+62 -50
src/peony_parser.hpp
··· 4 4 5 5 #include "types.hpp" 6 6 7 - namespace peony_parser { 8 - constexpr uint32 MAX_N_FILE_ENTRIES = 128; 9 - constexpr uint32 MAX_N_ENTRY_PROPS = 32; 10 - constexpr uint32 MAX_N_ARRAY_VALUES = 8; 11 - constexpr uint32 MAX_TOKEN_LENGTH = 128; 7 + class peony_parser { 8 + public: 9 + static constexpr uint32 MAX_N_FILE_ENTRIES = 128; 10 + static constexpr uint32 MAX_N_ENTRY_PROPS = 32; 11 + static constexpr uint32 MAX_N_ARRAY_VALUES = 8; 12 + static constexpr uint32 MAX_TOKEN_LENGTH = 128; 12 13 13 - constexpr const char TOKEN_SPACE = ' '; 14 - constexpr const char TOKEN_NEWLINE = '\n'; 15 - constexpr const char TOKEN_EQUALS = '='; 16 - constexpr const char TOKEN_HEADER_START = '>'; 17 - constexpr const char TOKEN_ARRAY_START = '['; 18 - constexpr const char TOKEN_ARRAY_END = ']'; 19 - constexpr const char TOKEN_OBJECT_START = '{'; 20 - constexpr const char TOKEN_OBJECT_END = '}'; 21 - constexpr const char TOKEN_TUPLE_START = '('; 22 - constexpr const char TOKEN_TUPLE_END = ')'; 23 - constexpr const char TOKEN_ELEMENT_SEPARATOR = ','; 24 - constexpr const char TOKEN_COMMENT_START = ';'; 14 + static constexpr const char TOKEN_SPACE = ' '; 15 + static constexpr const char TOKEN_NEWLINE = '\n'; 16 + static constexpr const char TOKEN_EQUALS = '='; 17 + static constexpr const char TOKEN_HEADER_START = '>'; 18 + static constexpr const char TOKEN_ARRAY_START = '['; 19 + static constexpr const char TOKEN_ARRAY_END = ']'; 20 + static constexpr const char TOKEN_OBJECT_START = '{'; 21 + static constexpr const char TOKEN_OBJECT_END = '}'; 22 + static constexpr const char TOKEN_TUPLE_START = '('; 23 + static constexpr const char TOKEN_TUPLE_END = ')'; 24 + static constexpr const char TOKEN_ELEMENT_SEPARATOR = ','; 25 + static constexpr const char TOKEN_COMMENT_START = ';'; 25 26 26 - enum class PeonyFilePropValueType { 27 - unknown, string, boolean, number, vec2, vec3, vec4 28 - }; 27 + enum class PropValueType { 28 + unknown, string, boolean, number, vec2, vec3, vec4 29 + }; 29 30 30 - struct PeonyFilePropValue { 31 - PeonyFilePropValueType type; 32 - union { 33 - char string_value[MAX_TOKEN_LENGTH]; 34 - bool32 boolean_value; 35 - real32 number_value; 36 - v2 vec2_value; 37 - v3 vec3_value; 38 - v4 vec4_value; 31 + struct PropValue { 32 + PropValueType type; 33 + union { 34 + char string_value[MAX_TOKEN_LENGTH]; 35 + bool32 boolean_value; 36 + real32 number_value; 37 + v2 vec2_value; 38 + v3 vec3_value; 39 + v4 vec4_value; 40 + }; 39 41 }; 40 - }; 41 42 42 - struct PeonyFileProp { 43 - char name[MAX_TOKEN_LENGTH]; 44 - PeonyFilePropValue values[MAX_N_ARRAY_VALUES]; 45 - uint32 n_values; 46 - }; 43 + struct Prop { 44 + char name[MAX_TOKEN_LENGTH]; 45 + PropValue values[MAX_N_ARRAY_VALUES]; 46 + uint32 n_values; 47 + }; 47 48 48 - struct PeonyFileEntry { 49 - char name[MAX_TOKEN_LENGTH]; 50 - PeonyFileProp props[MAX_N_ENTRY_PROPS]; 51 - uint32 n_props; 52 - }; 49 + struct Entry { 50 + char name[MAX_TOKEN_LENGTH]; 51 + Prop props[MAX_N_ENTRY_PROPS]; 52 + uint32 n_props; 53 + }; 53 54 54 - struct PeonyFile { 55 - PeonyFileEntry entries[MAX_N_FILE_ENTRIES]; 56 - uint32 n_entries; 57 - }; 55 + struct PeonyFile { 56 + Entry entries[MAX_N_FILE_ENTRIES]; 57 + uint32 n_entries; 58 + }; 58 59 59 - bool32 parse_file(PeonyFile *pf, char const *path); 60 - } 60 + static bool32 parse_file(PeonyFile *pf, char const *path); 61 61 62 - using peony_parser::PeonyFileEntry, 63 - peony_parser::PeonyFileProp, 64 - peony_parser::PeonyFilePropValue, 65 - peony_parser::PeonyFile; 62 + private: 63 + static void print_value(PropValue *value); 64 + static bool32 is_char_whitespace(const char target); 65 + static bool32 is_token_whitespace(const char *token); 66 + static bool32 is_char_allowed_in_name(const char target); 67 + static bool32 is_token_name(const char *token); 68 + static bool32 is_char_token_boundary(char target); 69 + static bool32 get_token(char *token, FILE *f); 70 + static bool32 get_non_trivial_token(char *token, FILE *f); 71 + static void parse_vec2(char *token, FILE *f, v2 *parsed_vector); 72 + static void parse_vec3(char *token, FILE *f, v3 *parsed_vector); 73 + static void parse_vec4(char *token, FILE *f, v4 *parsed_vector); 74 + static void get_value_from_token(char *token, FILE *f, PropValue *prop_value); 75 + static void parse_header(char *token, FILE *f); 76 + static void parse_property(Prop *prop, char *token, FILE *f); 77 + };
+214 -229
src/peony_parser_utils.cpp
··· 8 8 #include "intrinsics.hpp" 9 9 10 10 11 - char* peony_parser_utils::get_string(PeonyFileProp *prop) { 12 - if (!prop) { return nullptr; } 13 - return prop->values[0].string_value; 11 + char * 12 + peony_parser_utils::get_string(peony_parser::Prop *prop) 13 + { 14 + if (!prop) { return nullptr; } 15 + return prop->values[0].string_value; 14 16 } 15 17 16 18 17 - bool32* peony_parser_utils::get_boolean(PeonyFileProp *prop) { 18 - if (!prop) { return nullptr; } 19 - return &prop->values[0].boolean_value; 19 + bool32 * 20 + peony_parser_utils::get_boolean(peony_parser::Prop *prop) 21 + { 22 + if (!prop) { return nullptr; } 23 + return &prop->values[0].boolean_value; 20 24 } 21 25 22 26 23 - real32* peony_parser_utils::get_number(PeonyFileProp *prop) { 24 - if (!prop) { return nullptr; } 25 - return &prop->values[0].number_value; 27 + real32 * 28 + peony_parser_utils::get_number(peony_parser::Prop *prop) 29 + { 30 + if (!prop) { return nullptr; } 31 + return &prop->values[0].number_value; 26 32 } 27 33 28 34 29 - v2* peony_parser_utils::get_vec2(PeonyFileProp *prop) { 30 - if (!prop) { return nullptr; } 31 - return &prop->values[0].vec2_value; 35 + v2 * 36 + peony_parser_utils::get_vec2(peony_parser::Prop *prop) 37 + { 38 + if (!prop) { return nullptr; } 39 + return &prop->values[0].vec2_value; 32 40 } 33 41 34 42 35 - v3* peony_parser_utils::get_vec3(PeonyFileProp *prop) { 36 - if (!prop) { return nullptr; } 37 - return &prop->values[0].vec3_value; 43 + v3 * 44 + peony_parser_utils::get_vec3(peony_parser::Prop *prop) 45 + { 46 + if (!prop) { return nullptr; } 47 + return &prop->values[0].vec3_value; 38 48 } 39 49 40 50 41 - v4* peony_parser_utils::get_vec4(PeonyFileProp *prop) { 42 - if (!prop) { return nullptr; } 43 - return &prop->values[0].vec4_value; 51 + v4 * 52 + peony_parser_utils::get_vec4(peony_parser::Prop *prop) 53 + { 54 + if (!prop) { return nullptr; } 55 + return &prop->values[0].vec4_value; 44 56 } 45 57 46 58 47 - PeonyFileProp* peony_parser_utils::find_prop(PeonyFileEntry *entry, char const *name) { 48 - range (0, entry->n_props) { 49 - if (pstr_eq(name, entry->props[idx].name)) { 50 - return &entry->props[idx]; 59 + peony_parser::Prop * 60 + peony_parser_utils::find_prop(peony_parser::Entry *entry, char const *name) 61 + { 62 + range (0, entry->n_props) { 63 + if (pstr_eq(name, entry->props[idx].name)) { 64 + return &entry->props[idx]; 65 + } 51 66 } 52 - } 53 - logs::warning("Could not find prop %s", name); 54 - return nullptr; 67 + logs::warning("Could not find prop %s", name); 68 + return nullptr; 55 69 } 56 70 57 71 58 - void peony_parser_utils::get_unique_string_values_for_prop_name( 59 - PeonyFile *pf, 60 - Array<char[MAX_COMMON_NAME_LENGTH]> *unique_values, 61 - char const *prop_name 72 + void 73 + peony_parser_utils::get_unique_string_values_for_prop_name( 74 + peony_parser::PeonyFile *pf, 75 + Array<char[MAX_COMMON_NAME_LENGTH]> *unique_values, 76 + char const *prop_name 62 77 ) { 63 - range_named (idx_entry, 0, pf->n_entries) { 64 - PeonyFileEntry *entry = &pf->entries[idx_entry]; 65 - PeonyFileProp *prop = find_prop(entry, prop_name); 66 - if (!prop) { 67 - continue; 68 - } 69 - range_named (idx_value, 0, prop->n_values) { 70 - PeonyFilePropValue *value = &prop->values[idx_value]; 71 - bool32 does_material_already_exist = false; 72 - each (unique_value, *unique_values) { 73 - if (pstr_eq(value->string_value, *unique_value)) { 74 - does_material_already_exist = true; 75 - break; 78 + range_named (idx_entry, 0, pf->n_entries) { 79 + peony_parser::Entry *entry = &pf->entries[idx_entry]; 80 + peony_parser::Prop *prop = find_prop(entry, prop_name); 81 + if (!prop) { 82 + continue; 76 83 } 77 - } 78 - if (!does_material_already_exist) { 79 - pstr_copy( 80 - *(unique_values->push()), 81 - MAX_COMMON_NAME_LENGTH, 82 - value->string_value 83 - ); 84 - } 84 + range_named (idx_value, 0, prop->n_values) { 85 + peony_parser::PropValue *value = &prop->values[idx_value]; 86 + bool32 does_material_already_exist = false; 87 + each (unique_value, *unique_values) { 88 + if (pstr_eq(value->string_value, *unique_value)) { 89 + does_material_already_exist = true; 90 + break; 91 + } 92 + } 93 + if (!does_material_already_exist) { 94 + pstr_copy(*(unique_values->push()), 95 + MAX_COMMON_NAME_LENGTH, value->string_value); 96 + } 97 + } 85 98 } 86 - } 87 99 } 88 100 89 101 90 - void peony_parser_utils::create_material_from_peony_file_entry( 91 - mats::Material *material, 92 - PeonyFileEntry *entry, 93 - memory::Pool *memory_pool 102 + void 103 + peony_parser_utils::create_material_from_peony_file_entry( 104 + mats::Material *material, 105 + peony_parser::Entry *entry, 106 + memory::Pool *memory_pool 94 107 ) { 95 - mats::init_material(material, entry->name); 108 + mats::init_material(material, entry->name); 96 109 97 - // We're calling `find_prop()` a lot here, which goes through the full 98 - // list of props every time, and so this is kind of #slow. Not a huge deal, but 99 - // good to keep in mind. 100 - PeonyFileProp *prop; 110 + // We're calling `find_prop()` a lot here, which goes through the full 111 + // list of props every time, and so this is kind of #slow. Not a huge deal, but 112 + // good to keep in mind. 113 + peony_parser::Prop *prop; 101 114 102 - if ((prop = find_prop(entry, "albedo_static"))) { 103 - material->albedo_static = *get_vec4(prop); 104 - } 105 - if ((prop = find_prop(entry, "metallic_static"))) { 106 - material->metallic_static = *get_number(prop); 107 - } 108 - if ((prop = find_prop(entry, "roughness_static"))) { 109 - material->roughness_static = *get_number(prop); 110 - } 111 - if ((prop = find_prop(entry, "ao_static"))) { 112 - material->ao_static = *get_number(prop); 113 - } 115 + if ((prop = find_prop(entry, "albedo_static"))) { 116 + material->albedo_static = *get_vec4(prop); 117 + } 118 + if ((prop = find_prop(entry, "metallic_static"))) { 119 + material->metallic_static = *get_number(prop); 120 + } 121 + if ((prop = find_prop(entry, "roughness_static"))) { 122 + material->roughness_static = *get_number(prop); 123 + } 124 + if ((prop = find_prop(entry, "ao_static"))) { 125 + material->ao_static = *get_number(prop); 126 + } 114 127 115 - if ((prop = find_prop(entry, "shader_asset.vert_path"))) { 116 - if (!pstr_is_empty(get_string(prop))) { 117 - shaders::init_shader_asset( 118 - &material->shader_asset, 119 - memory_pool, 120 - entry->name, 121 - shaders::Type::standard, 122 - get_string(find_prop(entry, "shader_asset.vert_path")), 123 - get_string(find_prop(entry, "shader_asset.frag_path")), 124 - get_string(find_prop(entry, "shader_asset.geom_path")) 125 - ); 128 + if ((prop = find_prop(entry, "shader_asset.vert_path"))) { 129 + if (!pstr_is_empty(get_string(prop))) { 130 + shaders::init_shader_asset(&material->shader_asset, 131 + memory_pool, 132 + entry->name, 133 + shaders::Type::standard, 134 + get_string(find_prop(entry, "shader_asset.vert_path")), 135 + get_string(find_prop(entry, "shader_asset.frag_path")), 136 + get_string(find_prop(entry, "shader_asset.geom_path"))); 137 + } 126 138 } 127 - } 128 139 129 - if ((prop = find_prop(entry, "depth_shader_asset.vert_path"))) { 130 - if (!pstr_is_empty(get_string(prop))) { 131 - shaders::init_shader_asset( 132 - &material->depth_shader_asset, 133 - memory_pool, 134 - entry->name, 135 - shaders::Type::depth, 136 - get_string(find_prop(entry, "depth_shader_asset.vert_path")), 137 - get_string(find_prop(entry, "depth_shader_asset.frag_path")), 138 - get_string(find_prop(entry, "depth_shader_asset.geom_path")) 139 - ); 140 + if ((prop = find_prop(entry, "depth_shader_asset.vert_path"))) { 141 + if (!pstr_is_empty(get_string(prop))) { 142 + shaders::init_shader_asset(&material->depth_shader_asset, 143 + memory_pool, 144 + entry->name, 145 + shaders::Type::depth, 146 + get_string(find_prop(entry, "depth_shader_asset.vert_path")), 147 + get_string(find_prop(entry, "depth_shader_asset.frag_path")), 148 + get_string(find_prop(entry, "depth_shader_asset.geom_path"))); 149 + } 140 150 } 141 - } 142 151 143 - auto *builtin_textures = renderer::get_builtin_textures(); 152 + auto *builtin_textures = renderer::get_builtin_textures(); 144 153 145 - // Iterate through all props to get textures, since those could have any name 146 - range (0, entry->n_props) { 147 - prop = &entry->props[idx]; 154 + // Iterate through all props to get textures, since those could have any name 155 + range (0, entry->n_props) { 156 + prop = &entry->props[idx]; 148 157 149 - if (pstr_starts_with(prop->name, TEXTURE_PREFIX)) { 150 - // Handle a texture 151 - mats::Texture texture = {}; 152 - // The uniform name is the prop name without the prefix 153 - // The first value is the type, and the second the path 154 - // e.g. textures.foam_texture = [other, water_foam.png] 155 - char const *uniform_name = &prop->name[TEXTURE_PREFIX_LENGTH]; 156 - mats::init_texture( 157 - &texture, 158 - mats::texture_type_from_string(prop->values[0].string_value), 159 - prop->values[1].string_value 160 - ); 161 - mats::add_texture_to_material( 162 - material, 163 - texture, 164 - uniform_name 165 - ); 166 - } else if (pstr_starts_with(prop->name, BUILTIN_TEXTURE_PREFIX)) { 167 - // Handle a builtin texture 168 - char const *builtin_uniform_name = &prop->name[BUILTIN_TEXTURE_PREFIX_LENGTH]; 169 - if (pstr_eq(builtin_uniform_name, "g_position_texture")) { 170 - mats::add_texture_to_material( 171 - material, *builtin_textures->g_position_texture, builtin_uniform_name 172 - ); 173 - } else if (pstr_eq(builtin_uniform_name, "g_albedo_texture")) { 174 - mats::add_texture_to_material( 175 - material, *builtin_textures->g_albedo_texture, builtin_uniform_name 176 - ); 177 - } else if (pstr_eq(builtin_uniform_name, "shadowmaps_3d")) { 178 - mats::add_texture_to_material( 179 - material, *builtin_textures->shadowmaps_3d_texture, builtin_uniform_name 180 - ); 181 - } else if (pstr_eq(builtin_uniform_name, "shadowmaps_2d")) { 182 - mats::add_texture_to_material( 183 - material, *builtin_textures->shadowmaps_2d_texture, builtin_uniform_name 184 - ); 185 - } else { 186 - logs::fatal( 187 - "Attempted to use unsupported built-in texture %s", 188 - builtin_uniform_name 189 - ); 190 - } 158 + if (pstr_starts_with(prop->name, TEXTURE_PREFIX)) { 159 + // Handle a texture 160 + mats::Texture texture = {}; 161 + // The uniform name is the prop name without the prefix 162 + // The first value is the type, and the second the path 163 + // e.g. textures.foam_texture = [other, water_foam.png] 164 + char const *uniform_name = &prop->name[TEXTURE_PREFIX_LENGTH]; 165 + mats::init_texture(&texture, 166 + mats::texture_type_from_string(prop->values[0].string_value), 167 + prop->values[1].string_value); 168 + mats::add_texture_to_material(material, texture, uniform_name); 169 + } else if (pstr_starts_with(prop->name, BUILTIN_TEXTURE_PREFIX)) { 170 + // Handle a builtin texture 171 + char const *builtin_uniform_name = &prop->name[BUILTIN_TEXTURE_PREFIX_LENGTH]; 172 + if (pstr_eq(builtin_uniform_name, "g_position_texture")) { 173 + mats::add_texture_to_material( 174 + material, *builtin_textures->g_position_texture, builtin_uniform_name); 175 + } else if (pstr_eq(builtin_uniform_name, "g_albedo_texture")) { 176 + mats::add_texture_to_material( 177 + material, *builtin_textures->g_albedo_texture, builtin_uniform_name); 178 + } else if (pstr_eq(builtin_uniform_name, "shadowmaps_3d")) { 179 + mats::add_texture_to_material( 180 + material, *builtin_textures->shadowmaps_3d_texture, builtin_uniform_name); 181 + } else if (pstr_eq(builtin_uniform_name, "shadowmaps_2d")) { 182 + mats::add_texture_to_material( 183 + material, *builtin_textures->shadowmaps_2d_texture, builtin_uniform_name); 184 + } else { 185 + logs::fatal("Attempted to use unsupported built-in texture %s", 186 + builtin_uniform_name); 187 + } 188 + } 191 189 } 192 - } 193 190 } 194 191 195 192 196 - void peony_parser_utils::create_model_loader_from_peony_file_entry( 197 - PeonyFileEntry *entry, 198 - entities::Handle entity_handle, 199 - models::ModelLoader *model_loader 193 + void 194 + peony_parser_utils::create_model_loader_from_peony_file_entry( 195 + peony_parser::Entry *entry, 196 + entities::Handle entity_handle, 197 + models::ModelLoader *model_loader 200 198 ) { 201 - PeonyFileProp *model_path_prop = find_prop(entry, "model_path"); 202 - assert(model_path_prop); 203 - char const *model_path = get_string(model_path_prop); 199 + peony_parser::Prop *model_path_prop = find_prop(entry, "model_path"); 200 + assert(model_path_prop); 201 + char const *model_path = get_string(model_path_prop); 204 202 205 - models::init_model_loader(model_loader, model_path); 203 + models::init_model_loader(model_loader, model_path); 206 204 207 - PeonyFileProp *materials_prop = find_prop(entry, "materials"); 208 - model_loader->n_material_names = materials_prop->n_values; 209 - range (0, materials_prop->n_values) { 210 - pstr_copy( 211 - model_loader->material_names[idx], 212 - MAX_COMMON_NAME_LENGTH, 213 - materials_prop->values[idx].string_value 214 - ); 215 - } 205 + peony_parser::Prop *materials_prop = find_prop(entry, "materials"); 206 + model_loader->n_material_names = materials_prop->n_values; 207 + range (0, materials_prop->n_values) { 208 + pstr_copy(model_loader->material_names[idx], 209 + MAX_COMMON_NAME_LENGTH, 210 + materials_prop->values[idx].string_value); 211 + } 216 212 } 217 213 218 214 219 - void peony_parser_utils::create_entity_loader_from_peony_file_entry( 220 - PeonyFileEntry *entry, 221 - entities::Handle entity_handle, 222 - models::EntityLoader *entity_loader 215 + void 216 + peony_parser_utils::create_entity_loader_from_peony_file_entry( 217 + peony_parser::Entry *entry, 218 + entities::Handle entity_handle, 219 + models::EntityLoader *entity_loader 223 220 ) { 224 - PeonyFileProp *model_path_prop = find_prop(entry, "model_path"); 225 - assert(model_path_prop); 226 - char const *model_path = get_string(model_path_prop); 221 + peony_parser::Prop *model_path_prop = find_prop(entry, "model_path"); 222 + assert(model_path_prop); 223 + char const *model_path = get_string(model_path_prop); 227 224 228 - // Get render pass 229 - auto render_pass = drawable::Pass::none; 230 - PeonyFileProp *render_passes_prop = find_prop(entry, "render_passes"); 231 - if (render_passes_prop) { 232 - range (0, render_passes_prop->n_values) { 233 - render_pass = (drawable::Pass)( 234 - (uint32)render_pass | 235 - (uint32)drawable::render_pass_from_string( 236 - render_passes_prop->values[idx].string_value 237 - ) 238 - ); 225 + // Get render pass 226 + auto render_pass = drawable::Pass::none; 227 + peony_parser::Prop *render_passes_prop = find_prop(entry, "render_passes"); 228 + if (render_passes_prop) { 229 + range (0, render_passes_prop->n_values) { 230 + render_pass = (drawable::Pass)( 231 + (uint32)render_pass | 232 + (uint32)drawable::render_pass_from_string( 233 + render_passes_prop->values[idx].string_value)); 234 + } 235 + } else { 236 + logs::warning( 237 + "Loading EntityLoader with no RenderPasses, you probably don't want this?"); 239 238 } 240 - } else { 241 - logs::warning( 242 - "Loading EntityLoader with no RenderPasses, you probably don't want this?" 243 - ); 244 - } 245 239 246 - // Initialise everything except the components 247 - models::init_entity_loader( 248 - entity_loader, 249 - entry->name, 250 - model_path, 251 - render_pass, 252 - entity_handle 253 - ); 240 + // Initialise everything except the components 241 + models::init_entity_loader(entity_loader, entry->name, model_path, 242 + render_pass, entity_handle); 254 243 255 - // Build physics::Component, spatial::Component, lights::Component, behavior::Component 256 - range (0, entry->n_props) { 257 - PeonyFileProp *prop = &entry->props[idx]; 258 - if (pstr_eq(prop->name, "physics_component.obb.center")) { 259 - entity_loader->physics_component.obb.center = *get_vec3(prop); 260 - } else if (pstr_eq(prop->name, "physics_component.obb.x_axis")) { 261 - entity_loader->physics_component.obb.x_axis = *get_vec3(prop); 262 - } else if (pstr_eq(prop->name, "physics_component.obb.y_axis")) { 263 - entity_loader->physics_component.obb.y_axis = *get_vec3(prop); 264 - } else if (pstr_eq(prop->name, "physics_component.obb.extents")) { 265 - entity_loader->physics_component.obb.extents = *get_vec3(prop); 266 - } else if (pstr_eq(prop->name, "spatial_component.position")) { 267 - entity_loader->spatial_component.position = *get_vec3(prop); 268 - } else if (pstr_eq(prop->name, "spatial_component.rotation")) { 269 - entity_loader->spatial_component.rotation = 270 - glm::angleAxis( 271 - radians((*get_vec4(prop))[0]), 272 - v3( 273 - (*get_vec4(prop))[1], 274 - (*get_vec4(prop))[2], 275 - (*get_vec4(prop))[3] 276 - ) 277 - ); 278 - } else if (pstr_eq(prop->name, "spatial_component.scale")) { 279 - entity_loader->spatial_component.scale = *get_vec3(prop); 280 - } else if (pstr_eq(prop->name, "light_component.type")) { 281 - entity_loader->light_component.type = 282 - lights::light_type_from_string(get_string(prop)); 283 - } else if (pstr_eq(prop->name, "light_component.direction")) { 284 - entity_loader->light_component.direction = *get_vec3(prop); 285 - } else if (pstr_eq(prop->name, "light_component.color")) { 286 - entity_loader->light_component.color = *get_vec4(prop); 287 - } else if (pstr_eq(prop->name, "light_component.attenuation")) { 288 - entity_loader->light_component.attenuation = *get_vec4(prop); 289 - } else if (pstr_eq(prop->name, "behavior_component.behavior")) { 290 - entity_loader->behavior_component.behavior = 291 - behavior::behavior_from_string(get_string(prop)); 244 + // Build physics::Component, spatial::Component, lights::Component, behavior::Component 245 + range (0, entry->n_props) { 246 + peony_parser::Prop *prop = &entry->props[idx]; 247 + if (pstr_eq(prop->name, "physics_component.obb.center")) { 248 + entity_loader->physics_component.obb.center = *get_vec3(prop); 249 + } else if (pstr_eq(prop->name, "physics_component.obb.x_axis")) { 250 + entity_loader->physics_component.obb.x_axis = *get_vec3(prop); 251 + } else if (pstr_eq(prop->name, "physics_component.obb.y_axis")) { 252 + entity_loader->physics_component.obb.y_axis = *get_vec3(prop); 253 + } else if (pstr_eq(prop->name, "physics_component.obb.extents")) { 254 + entity_loader->physics_component.obb.extents = *get_vec3(prop); 255 + } else if (pstr_eq(prop->name, "spatial_component.position")) { 256 + entity_loader->spatial_component.position = *get_vec3(prop); 257 + } else if (pstr_eq(prop->name, "spatial_component.rotation")) { 258 + entity_loader->spatial_component.rotation = glm::angleAxis( 259 + radians((*get_vec4(prop))[0]), 260 + v3((*get_vec4(prop))[1], 261 + (*get_vec4(prop))[2], 262 + (*get_vec4(prop))[3])); 263 + } else if (pstr_eq(prop->name, "spatial_component.scale")) { 264 + entity_loader->spatial_component.scale = *get_vec3(prop); 265 + } else if (pstr_eq(prop->name, "light_component.type")) { 266 + entity_loader->light_component.type = 267 + lights::light_type_from_string(get_string(prop)); 268 + } else if (pstr_eq(prop->name, "light_component.direction")) { 269 + entity_loader->light_component.direction = *get_vec3(prop); 270 + } else if (pstr_eq(prop->name, "light_component.color")) { 271 + entity_loader->light_component.color = *get_vec4(prop); 272 + } else if (pstr_eq(prop->name, "light_component.attenuation")) { 273 + entity_loader->light_component.attenuation = *get_vec4(prop); 274 + } else if (pstr_eq(prop->name, "behavior_component.behavior")) { 275 + entity_loader->behavior_component.behavior = 276 + behavior::behavior_from_string(get_string(prop)); 277 + } 292 278 } 293 - } 294 279 }
+34 -33
src/peony_parser_utils.hpp
··· 7 7 #include "models.hpp" 8 8 #include "renderer.hpp" 9 9 10 - namespace peony_parser_utils { 11 - constexpr const char *TEXTURE_PREFIX = "textures."; 12 - constexpr size_t TEXTURE_PREFIX_LENGTH = 9; 13 - constexpr const char *BUILTIN_TEXTURE_PREFIX = "builtin_textures."; 14 - constexpr size_t BUILTIN_TEXTURE_PREFIX_LENGTH = 17; 10 + class peony_parser_utils { 11 + public: 12 + static constexpr const char *TEXTURE_PREFIX = "textures."; 13 + static constexpr size_t TEXTURE_PREFIX_LENGTH = 9; 14 + static constexpr const char *BUILTIN_TEXTURE_PREFIX = "builtin_textures."; 15 + static constexpr size_t BUILTIN_TEXTURE_PREFIX_LENGTH = 17; 15 16 16 - char* get_string(PeonyFileProp *prop); 17 - bool32* get_boolean(PeonyFileProp *prop); 18 - real32* get_number(PeonyFileProp *prop); 19 - v2* get_vec2(PeonyFileProp *prop); 20 - v3* get_vec3(PeonyFileProp *prop); 21 - v4* get_vec4(PeonyFileProp *prop); 22 - PeonyFileProp* find_prop(PeonyFileEntry *entry, char const *name); 23 - void get_unique_string_values_for_prop_name( 24 - PeonyFile *pf, 25 - Array<char[MAX_COMMON_NAME_LENGTH]> *unique_values, 26 - char const *prop_name 27 - ); 28 - void create_material_from_peony_file_entry( 29 - mats::Material *material, 30 - PeonyFileEntry *entry, 31 - memory::Pool *memory_pool 32 - ); 33 - void create_model_loader_from_peony_file_entry( 34 - PeonyFileEntry *entry, 35 - entities::Handle entity_handle, 36 - models::ModelLoader *model_loader 37 - ); 38 - void create_entity_loader_from_peony_file_entry( 39 - PeonyFileEntry *entry, 40 - entities::Handle entity_handle, 41 - models::EntityLoader *entity_loader 42 - ); 43 - } 17 + static char * get_string(peony_parser::Prop *prop); 18 + static bool32 * get_boolean(peony_parser::Prop *prop); 19 + static real32 * get_number(peony_parser::Prop *prop); 20 + static v2 * get_vec2(peony_parser::Prop *prop); 21 + static v3 * get_vec3(peony_parser::Prop *prop); 22 + static v4 * get_vec4(peony_parser::Prop *prop); 23 + static peony_parser::Prop * find_prop(peony_parser::Entry *entry, char const *name); 24 + static void get_unique_string_values_for_prop_name( 25 + peony_parser::PeonyFile *pf, 26 + Array<char[MAX_COMMON_NAME_LENGTH]> *unique_values, 27 + char const *prop_name 28 + ); 29 + static void create_material_from_peony_file_entry( 30 + mats::Material *material, 31 + peony_parser::Entry *entry, 32 + memory::Pool *memory_pool 33 + ); 34 + static void create_model_loader_from_peony_file_entry( 35 + peony_parser::Entry *entry, 36 + entities::Handle entity_handle, 37 + models::ModelLoader *model_loader 38 + ); 39 + static void create_entity_loader_from_peony_file_entry( 40 + peony_parser::Entry *entry, 41 + entities::Handle entity_handle, 42 + models::EntityLoader *entity_loader 43 + ); 44 + };
+11 -11
src/physics.cpp
··· 9 9 10 10 physics::RayCollisionResult 11 11 physics::find_ray_collision( 12 - Ray *ray, 12 + spatial::Ray *ray, 13 13 // TODO: Replace this with some kind of collision layers. 14 14 physics::Component *physics_component_to_ignore_or_nullptr 15 15 ) { ··· 89 89 } 90 90 91 91 92 - Obb 93 - physics::transform_obb(Obb obb, spatial::Component *spatial) 92 + spatial::Obb 93 + physics::transform_obb(spatial::Obb obb, spatial::Component *spatial) 94 94 { 95 95 m3 rotation = glm::toMat3(normalize(spatial->rotation)); 96 96 obb.center = spatial->position + (rotation * (spatial->scale * obb.center)); ··· 102 102 103 103 104 104 physics::RaycastResult 105 - physics::intersect_obb_ray(Obb *obb, Ray *ray) 105 + physics::intersect_obb_ray(spatial::Obb *obb, spatial::Ray *ray) 106 106 { 107 107 // Gabor Szauer, Game Physics Cookbook, “Raycast Oriented Bounding Box” 108 108 v3 obb_z_axis = cross(obb->x_axis, obb->y_axis); ··· 241 241 } 242 242 243 243 244 - Face 244 + spatial::Face 245 245 physics::get_incident_face( 246 246 m3 *cob, // incident change of base 247 247 v3 e, // incident extents 248 248 v3 c, // incident center 249 249 v3 n // incident normal 250 250 ) { 251 - Face face; 251 + spatial::Face face; 252 252 n = transpose(*cob) * n; 253 253 v3 abs_n = abs(n); 254 254 ··· 407 407 physics::clip_faces( 408 408 v3 reference_center, v3 reference_face_extents, 409 409 uint32 clip_edges[4], m3 reference_face_cob, 410 - Face incident_face, 410 + spatial::Face incident_face, 411 411 v3 clip_vertices[8], real32 clip_depths[8] 412 412 ) { 413 413 return 0; ··· 472 472 */ 473 473 physics::CollisionManifold 474 474 physics::intersect_obb_obb( 475 - Obb *a, 476 - Obb *b, 475 + spatial::Obb *a, 476 + spatial::Obb *b, 477 477 spatial::Component *spatial_a, 478 478 spatial::Component *spatial_b 479 479 ) { ··· 666 666 } 667 667 668 668 if (manifold.axis < 6) { 669 - // Face-something collision 669 + // spatial::Face-something collision 670 670 v3 reference_extents, incident_extents, reference_center, incident_center; 671 671 m3 reference_cob, incident_cob; 672 672 ··· 687 687 incident_center = a->center; 688 688 } 689 689 690 - Face incident_face = get_incident_face(&incident_cob, incident_extents, incident_center, manifold.normal); 690 + spatial::Face incident_face = get_incident_face(&incident_cob, incident_extents, incident_center, manifold.normal); 691 691 692 692 uint32 clip_edges[4]; 693 693 m3 reference_face_cob;
+9 -9
src/physics.hpp
··· 14 14 15 15 struct Component { 16 16 entities::Handle entity_handle; 17 - Obb obb; 18 - Obb transformed_obb; 17 + spatial::Obb obb; 18 + spatial::Obb transformed_obb; 19 19 }; 20 20 21 21 struct ComponentSet { ··· 42 42 }; 43 43 44 44 static RayCollisionResult find_ray_collision( 45 - Ray *ray, 45 + spatial::Ray *ray, 46 46 Component *physics_component_to_ignore_or_nullptr 47 47 ); 48 48 static CollisionManifold find_collision( ··· 52 52 static void update_components(); 53 53 54 54 private: 55 - static Obb transform_obb(Obb obb, spatial::Component *spatial); 56 - static RaycastResult intersect_obb_ray(Obb *obb, Ray *ray); 55 + static spatial::Obb transform_obb(spatial::Obb obb, spatial::Component *spatial); 56 + static RaycastResult intersect_obb_ray(spatial::Obb *obb, spatial::Ray *ray); 57 57 static bool is_component_valid(Component *physics_component); 58 58 static v3 get_edge_contact_point( 59 59 v3 a_edge_point, ··· 64 64 real32 b_axis_length, 65 65 bool32 should_use_a_midpoint 66 66 ); 67 - static Face get_incident_face(m3 *cob, v3 e, v3 c, v3 n); 67 + static spatial::Face get_incident_face(m3 *cob, v3 e, v3 c, v3 n); 68 68 static void get_reference_face_edges_and_basis( 69 69 m3 *cob, 70 70 v3 e, ··· 78 78 static uint32 clip_faces( 79 79 v3 reference_center, v3 reference_face_extents, 80 80 uint32 clip_edges[4], m3 reference_face_cob, 81 - Face incident_face, 81 + spatial::Face incident_face, 82 82 v3 clip_vertices[8], real32 clip_depths[8] 83 83 ); 84 84 static void update_best_for_face_axis( ··· 90 90 real32 sep, uint32 axis, v3 normal 91 91 ); 92 92 static CollisionManifold intersect_obb_obb( 93 - Obb *a, 94 - Obb *b, 93 + spatial::Obb *a, 94 + spatial::Obb *b, 95 95 spatial::Component *spatial_a, 96 96 spatial::Component *spatial_b 97 97 );
+41 -41
src/queue.hpp
··· 7 7 template <typename T> 8 8 class Queue { 9 9 public: 10 - uint32 size = 0; 11 - uint32 max_size = 0; 12 - T *items = nullptr; 13 - uint32 head = 0; 14 - uint32 tail = 0; 10 + uint32 size = 0; 11 + uint32 max_size = 0; 12 + T *items = nullptr; 13 + uint32 head = 0; 14 + uint32 tail = 0; 15 15 16 - T* push() { 17 - assert(this->size < this->max_size); 18 - T* new_slot = this->items + this->tail; 19 - if (this->tail + 1 >= this->max_size) { 20 - this->tail = 0; 21 - } else { 22 - this->tail++; 16 + T* push() { 17 + assert(this->size < this->max_size); 18 + T* new_slot = this->items + this->tail; 19 + if (this->tail + 1 >= this->max_size) { 20 + this->tail = 0; 21 + } else { 22 + this->tail++; 23 + } 24 + this->size++; 25 + return new_slot; 23 26 } 24 - this->size++; 25 - return new_slot; 26 - } 27 27 28 - T push(T new_item) { 29 - T* new_slot = push(); 30 - *new_slot = new_item; 31 - return new_item; 32 - } 28 + T push(T new_item) { 29 + T* new_slot = push(); 30 + *new_slot = new_item; 31 + return new_item; 32 + } 33 33 34 - T* pop() { 35 - assert(this->size > 0); 36 - T* item = this->items + this->head; 37 - if (this->head + 1 >= this->max_size) { 38 - this->head = 0; 39 - } else { 40 - this->head++; 34 + T* pop() { 35 + assert(this->size > 0); 36 + T* item = this->items + this->head; 37 + if (this->head + 1 >= this->max_size) { 38 + this->head = 0; 39 + } else { 40 + this->head++; 41 + } 42 + this->size--; 43 + return item; 41 44 } 42 - this->size--; 43 - return item; 44 - } 45 45 46 - Queue(memory::Pool *memory_pool, uint32 new_max_size, const char *debug_name) { 47 - this->max_size = new_max_size; 48 - this->items = (T*)memory::push(memory_pool, sizeof(T) * this->max_size, debug_name); 49 - } 46 + Queue(memory::Pool *memory_pool, uint32 new_max_size, const char *debug_name) { 47 + this->max_size = new_max_size; 48 + this->items = (T*)memory::push(memory_pool, sizeof(T) * this->max_size, debug_name); 49 + } 50 50 51 - Queue(memory::Pool *memory_pool, uint32 new_size, uint32 new_max_size, T *new_items) { 52 - this->size = new_size; 53 - this->head = 0; 54 - this->tail = new_size; 55 - this->max_size = new_max_size; 56 - this->items = new_items; 57 - } 51 + Queue(memory::Pool *memory_pool, uint32 new_size, uint32 new_max_size, T *new_items) { 52 + this->size = new_size; 53 + this->head = 0; 54 + this->tail = new_size; 55 + this->max_size = new_max_size; 56 + this->items = new_items; 57 + } 58 58 };
+1 -1
src/renderer.cpp
··· 1288 1288 drawable::Mode render_mode, 1289 1289 shaders::Asset *standard_depth_shader_asset 1290 1290 ) { 1291 - ModelMatrixCache cache = { m4(1.0f), nullptr }; 1291 + spatial::ModelMatrixCache cache = { m4(1.0f), nullptr }; 1292 1292 1293 1293 each (drawable_component, *engine::get_drawable_components()) { 1294 1294 if (!drawable::is_component_valid(drawable_component)) {
+52 -47
src/spatial.cpp
··· 5 5 #include "engine.hpp" 6 6 7 7 8 - void spatial::print_spatial_component(spatial::Component *spatial_component) { 9 - logs::info("spatial::Component:"); 10 - logs::info(" entity_handle: %d", spatial_component->entity_handle); 11 - logs::info(" position:"); 12 - logs::print_v3(&spatial_component->position); 13 - logs::info(" rotation:"); 14 - logs::info("(don't know how to print rotation, sorry)"); 15 - /* logs::print_v4(&spatial_component->rotation); */ 16 - logs::info(" scale:"); 17 - logs::print_v3(&spatial_component->scale); 18 - logs::info(" parent_entity_handle: %d", spatial_component->parent_entity_handle); 8 + void 9 + spatial::print_spatial_component(spatial::Component *spatial_component) 10 + { 11 + logs::info("spatial::Component:"); 12 + logs::info(" entity_handle: %d", spatial_component->entity_handle); 13 + logs::info(" position:"); 14 + logs::print_v3(&spatial_component->position); 15 + logs::info(" rotation:"); 16 + logs::info("(don't know how to print rotation, sorry)"); 17 + /* logs::print_v4(&spatial_component->rotation); */ 18 + logs::info(" scale:"); 19 + logs::print_v3(&spatial_component->scale); 20 + logs::info(" parent_entity_handle: %d", spatial_component->parent_entity_handle); 19 21 } 20 22 21 23 22 - bool32 spatial::does_spatial_component_have_dimensions( 23 - spatial::Component *spatial_component 24 - ) { 25 - return ( 26 - spatial_component->scale.x > 0.0f && 27 - spatial_component->scale.y > 0.0f && 28 - spatial_component->scale.z > 0.0f 29 - ); 24 + bool32 25 + spatial::does_spatial_component_have_dimensions(spatial::Component *spatial_component) 26 + { 27 + return ( 28 + spatial_component->scale.x > 0.0f && 29 + spatial_component->scale.y > 0.0f && 30 + spatial_component->scale.z > 0.0f 31 + ); 30 32 } 31 33 32 34 33 - bool32 spatial::is_spatial_component_valid(spatial::Component *spatial_component) { 34 - return does_spatial_component_have_dimensions(spatial_component) || 35 - spatial_component->parent_entity_handle != entities::NO_ENTITY_HANDLE; 35 + bool32 36 + spatial::is_spatial_component_valid(spatial::Component *spatial_component) 37 + { 38 + return does_spatial_component_have_dimensions(spatial_component) || 39 + spatial_component->parent_entity_handle != entities::NO_ENTITY_HANDLE; 36 40 } 37 41 38 42 39 - m4 spatial::make_model_matrix( 40 - spatial::Component *spatial_component, 41 - ModelMatrixCache *cache 43 + m4 44 + spatial::make_model_matrix( 45 + spatial::Component *spatial_component, 46 + ModelMatrixCache *cache 42 47 ) { 43 - m4 model_matrix = m4(1.0f); 48 + m4 model_matrix = m4(1.0f); 44 49 45 - if (spatial_component->parent_entity_handle != entities::NO_ENTITY_HANDLE) { 46 - spatial::Component *parent = engine::get_spatial_component( 47 - spatial_component->parent_entity_handle); 48 - model_matrix = make_model_matrix(parent, cache); 49 - } 50 + if (spatial_component->parent_entity_handle != entities::NO_ENTITY_HANDLE) { 51 + spatial::Component *parent = engine::get_spatial_component( 52 + spatial_component->parent_entity_handle); 53 + model_matrix = make_model_matrix(parent, cache); 54 + } 50 55 51 - if (does_spatial_component_have_dimensions(spatial_component)) { 52 - // TODO: This is somehow really #slow, the multiplication in particular. 53 - // Is there a better way? 54 - if ( 55 - spatial_component == cache->last_model_matrix_spatial_component 56 - ) { 57 - model_matrix = cache->last_model_matrix; 58 - } else { 59 - model_matrix = glm::translate(model_matrix, spatial_component->position); 60 - model_matrix = glm::scale(model_matrix, spatial_component->scale); 61 - model_matrix = model_matrix * 62 - glm::toMat4(normalize(spatial_component->rotation)); 63 - cache->last_model_matrix = model_matrix; 64 - cache->last_model_matrix_spatial_component = spatial_component; 56 + if (does_spatial_component_have_dimensions(spatial_component)) { 57 + // TODO: This is somehow really #slow, the multiplication in particular. 58 + // Is there a better way? 59 + if ( 60 + spatial_component == cache->last_model_matrix_spatial_component 61 + ) { 62 + model_matrix = cache->last_model_matrix; 63 + } else { 64 + model_matrix = glm::translate(model_matrix, spatial_component->position); 65 + model_matrix = glm::scale(model_matrix, spatial_component->scale); 66 + model_matrix = model_matrix * 67 + glm::toMat4(normalize(spatial_component->rotation)); 68 + cache->last_model_matrix = model_matrix; 69 + cache->last_model_matrix_spatial_component = spatial_component; 70 + } 65 71 } 66 - } 67 72 68 - return model_matrix; 73 + return model_matrix; 69 74 }
+37 -39
src/spatial.hpp
··· 5 5 #include "types.hpp" 6 6 #include "entities.hpp" 7 7 8 - namespace spatial { 9 - struct Obb { 10 - v3 center; 11 - v3 x_axis; 12 - v3 y_axis; // We can get the z axis with a cross product 13 - v3 extents; 14 - }; 15 - 16 - struct Face { 17 - v3 vertices[4]; 18 - }; 8 + class spatial { 9 + public: 10 + struct Obb { 11 + v3 center; 12 + v3 x_axis; 13 + v3 y_axis; // We can get the z axis with a cross product 14 + v3 extents; 15 + }; 19 16 20 - struct Ray { 21 - v3 origin; 22 - v3 direction; 23 - }; 17 + struct Face { 18 + v3 vertices[4]; 19 + }; 24 20 21 + struct Ray { 22 + v3 origin; 23 + v3 direction; 24 + }; 25 25 26 - struct Component { 27 - entities::Handle entity_handle; 28 - v3 position; 29 - quat rotation; 30 - v3 scale; 31 - entities::Handle parent_entity_handle; 32 - }; 33 26 27 + struct Component { 28 + entities::Handle entity_handle; 29 + v3 position; 30 + quat rotation; 31 + v3 scale; 32 + entities::Handle parent_entity_handle; 33 + }; 34 34 35 - struct ModelMatrixCache { 36 - m4 last_model_matrix; 37 - Component *last_model_matrix_spatial_component; 38 - }; 39 35 40 - struct ComponentSet { 41 - Array<Component> components; 42 - }; 36 + struct ModelMatrixCache { 37 + m4 last_model_matrix; 38 + Component *last_model_matrix_spatial_component; 39 + }; 43 40 41 + struct ComponentSet { 42 + Array<Component> components; 43 + }; 44 44 45 - void print_spatial_component(Component *spatial_component); 46 - bool32 does_spatial_component_have_dimensions(Component *spatial_component); 47 - bool32 is_spatial_component_valid(Component *spatial_component); 48 - m4 make_model_matrix( 49 - Component *spatial_component, 50 - ModelMatrixCache *cache 51 - ); 52 - } 53 45 54 - using spatial::Obb, spatial::Face, spatial::Ray, spatial::Component, 55 - spatial::ModelMatrixCache, spatial::ComponentSet; 46 + static void print_spatial_component(Component *spatial_component); 47 + static bool32 does_spatial_component_have_dimensions(Component *spatial_component); 48 + static bool32 is_spatial_component_valid(Component *spatial_component); 49 + static m4 make_model_matrix( 50 + Component *spatial_component, 51 + ModelMatrixCache *cache 52 + ); 53 + };
+49 -49
src/stackarray.hpp
··· 7 7 template <typename T, uint32 capacity> 8 8 class StackArray { 9 9 public: 10 - T items[capacity] = {{}}; 11 - uint32 length = 0; 12 - bool32 is_sparse = false; 13 - uint32 starting_idx = 0; 10 + T items[capacity] = {{}}; 11 + uint32 length = 0; 12 + bool32 is_sparse = false; 13 + uint32 starting_idx = 0; 14 14 15 - T* push() { 16 - assert(this->length < capacity); 17 - uint32 new_idx = this->length; 18 - this->length++; 19 - T* new_slot = &this->items[new_idx]; 20 - return new_slot; 21 - } 15 + T* push() { 16 + assert(this->length < capacity); 17 + uint32 new_idx = this->length; 18 + this->length++; 19 + T* new_slot = &this->items[new_idx]; 20 + return new_slot; 21 + } 22 22 23 - T* push(T new_item) { 24 - T* new_slot = push(); 25 - *new_slot = new_item; 26 - return new_slot; 27 - } 28 - 29 - T* get(uint32 idx) { 30 - assert(idx >= this->starting_idx && idx < capacity); 31 - if (idx >= this->length) { 32 - assert(this->is_sparse); 33 - this->length = idx + 1; 23 + T* push(T new_item) { 24 + T* new_slot = push(); 25 + *new_slot = new_item; 26 + return new_slot; 34 27 } 35 - return &this->items[idx]; 36 - } 37 28 38 - T* operator[](uint32 idx) { 39 - return get(idx); 40 - } 29 + T* get(uint32 idx) { 30 + assert(idx >= this->starting_idx && idx < capacity); 31 + if (idx >= this->length) { 32 + assert(this->is_sparse); 33 + this->length = idx + 1; 34 + } 35 + return &this->items[idx]; 36 + } 41 37 42 - template <typename F> 43 - T* find(F match) { 44 - for (auto item = begin(); item < end(); item++) { 45 - if (match(item)) { 46 - return item; 47 - } 38 + T* operator[](uint32 idx) { 39 + return get(idx); 48 40 } 49 - return nullptr; 50 - } 41 + 42 + template <typename F> 43 + T* find(F match) { 44 + for (auto item = begin(); item < end(); item++) { 45 + if (match(item)) { 46 + return item; 47 + } 48 + } 49 + return nullptr; 50 + } 51 51 52 - T* begin() { 53 - return &this->items[this->starting_idx]; 54 - } 52 + T* begin() { 53 + return &this->items[this->starting_idx]; 54 + } 55 55 56 - T* end() { 57 - return &this->items[this->length]; 58 - } 56 + T* end() { 57 + return &this->items[this->length]; 58 + } 59 59 60 - void clear() { 61 - memset(this->items, 0, sizeof(this->items)); 62 - this->length = 0; 63 - } 60 + void clear() { 61 + memset(this->items, 0, sizeof(this->items)); 62 + this->length = 0; 63 + } 64 64 65 - void delete_elements_after_index(uint32 idx) { 66 - memset(&this->items[idx], 0, sizeof(T) * (this->length - idx)); 67 - this->length = idx; 68 - } 65 + void delete_elements_after_index(uint32 idx) { 66 + memset(&this->items[idx], 0, sizeof(T) * (this->length - idx)); 67 + this->length = idx; 68 + } 69 69 };
+189 -175
src/util.cpp
··· 4 4 #include "util.hpp" 5 5 6 6 7 - const char* util::stringify_glenum(GLenum thing) { 8 - switch (thing) { 7 + char const * 8 + util::stringify_glenum(GLenum thing) 9 + { 10 + switch (thing) { 9 11 case 0: 10 - return "(none)"; 12 + return "(none)"; 11 13 case GL_BYTE: 12 - return "GLbyte"; 14 + return "GLbyte"; 13 15 case GL_UNSIGNED_BYTE: 14 - return "GLubyte"; 16 + return "GLubyte"; 15 17 case GL_SHORT: 16 - return "GLshort"; 18 + return "GLshort"; 17 19 case GL_UNSIGNED_SHORT: 18 - return "GLushort"; 20 + return "GLushort"; 19 21 case GL_INT: 20 - return "GLint"; 22 + return "GLint"; 21 23 case GL_UNSIGNED_INT: 22 - return "GLuint"; 24 + return "GLuint"; 23 25 case GL_HALF_FLOAT: 24 - return "GLhalf"; 26 + return "GLhalf"; 25 27 case GL_FLOAT: 26 - return "GLfloat"; 28 + return "GLfloat"; 27 29 case GL_DOUBLE: 28 - return "GLdouble"; 30 + return "GLdouble"; 29 31 case GL_RGB8: 30 - return "GL_RGB8"; 32 + return "GL_RGB8"; 31 33 case GL_RGBA8: 32 - return "GL_RGBA8"; 34 + return "GL_RGBA8"; 33 35 case GL_SRGB8: 34 - return "GL_SRGB8"; 36 + return "GL_SRGB8"; 35 37 case GL_UNSIGNED_INT_8_8_8_8: 36 - return "GL_UNSIGNED_INT_8_8_8_8"; 38 + return "GL_UNSIGNED_INT_8_8_8_8"; 37 39 case GL_UNSIGNED_INT_8_8_8_8_REV: 38 - return "GL_UNSIGNED_INT_8_8_8_8_REV"; 40 + return "GL_UNSIGNED_INT_8_8_8_8_REV"; 39 41 case GL_DEPTH_COMPONENT: 40 - return "GL_DEPTH_COMPONENT"; 42 + return "GL_DEPTH_COMPONENT"; 41 43 case GL_DEPTH_STENCIL: 42 - return "GL_DEPTH_STENCIL"; 44 + return "GL_DEPTH_STENCIL"; 43 45 case GL_RED: 44 - return "GL_RED"; 46 + return "GL_RED"; 45 47 case GL_RGB: 46 - return "GL_RGB"; 48 + return "GL_RGB"; 47 49 case GL_RGBA: 48 - return "GL_RGBA"; 50 + return "GL_RGBA"; 49 51 default: 50 - logs::warning("Unknown GLenum %d", thing); 51 - return "Unknown GLenum"; 52 - } 52 + logs::warning("Unknown GLenum %d", thing); 53 + return "Unknown GLenum"; 54 + } 53 55 } 54 56 55 57 56 - GLenum util::get_texture_format_from_n_components(int32 n_components) { 57 - if (n_components == 1) { 58 - return GL_RED; 59 - } else if (n_components == 3) { 60 - return GL_BGR; 61 - } else if (n_components == 4) { 62 - return GL_BGRA; 63 - } else { 64 - logs::fatal("Don't know what to do with n_components = %d", n_components); 65 - return 0; 66 - } 58 + GLenum 59 + util::get_texture_format_from_n_components(int32 n_components) 60 + { 61 + if (n_components == 1) { 62 + return GL_RED; 63 + } else if (n_components == 3) { 64 + return GL_BGR; 65 + } else if (n_components == 4) { 66 + return GL_BGRA; 67 + } else { 68 + logs::fatal("Don't know what to do with n_components = %d", n_components); 69 + return 0; 70 + } 67 71 } 68 72 69 73 70 - real64 util::random(real64 min, real64 max) { 71 - uint32 r = rand(); 72 - real64 r_normalized = (real64)r / (real64)RAND_MAX; 73 - return min + ((r_normalized) * (max - min)); 74 + real64 75 + util::random(real64 min, real64 max) 76 + { 77 + uint32 r = rand(); 78 + real64 r_normalized = (real64)r / (real64)RAND_MAX; 79 + return min + ((r_normalized) * (max - min)); 74 80 } 75 81 76 82 77 - v3 util::aiVector3D_to_glm(aiVector3D *vec) { 78 - return v3(vec->x, vec->y, vec->z); 83 + v3 84 + util::aiVector3D_to_glm(aiVector3D *vec) 85 + { 86 + return v3(vec->x, vec->y, vec->z); 79 87 } 80 88 81 89 82 - quat util::aiQuaternion_to_glm(aiQuaternion *rotation) { 83 - return quat(rotation->w, rotation->x, rotation->y, rotation->z); 90 + quat 91 + util::aiQuaternion_to_glm(aiQuaternion *rotation) 92 + { 93 + return quat(rotation->w, rotation->x, rotation->y, rotation->z); 84 94 } 85 95 86 96 87 - m4 util::aimatrix4x4_to_glm(aiMatrix4x4 *from) { 88 - m4 to; 97 + m4 98 + util::aimatrix4x4_to_glm(aiMatrix4x4 *from) 99 + { 100 + m4 to; 89 101 90 - to[0][0] = (GLfloat)from->a1; 91 - to[0][1] = (GLfloat)from->b1; 92 - to[0][2] = (GLfloat)from->c1; 93 - to[0][3] = (GLfloat)from->d1; 102 + to[0][0] = (GLfloat)from->a1; 103 + to[0][1] = (GLfloat)from->b1; 104 + to[0][2] = (GLfloat)from->c1; 105 + to[0][3] = (GLfloat)from->d1; 94 106 95 - to[1][0] = (GLfloat)from->a2; 96 - to[1][1] = (GLfloat)from->b2; 97 - to[1][2] = (GLfloat)from->c2; 98 - to[1][3] = (GLfloat)from->d2; 107 + to[1][0] = (GLfloat)from->a2; 108 + to[1][1] = (GLfloat)from->b2; 109 + to[1][2] = (GLfloat)from->c2; 110 + to[1][3] = (GLfloat)from->d2; 99 111 100 - to[2][0] = (GLfloat)from->a3; 101 - to[2][1] = (GLfloat)from->b3; 102 - to[2][2] = (GLfloat)from->c3; 103 - to[2][3] = (GLfloat)from->d3; 112 + to[2][0] = (GLfloat)from->a3; 113 + to[2][1] = (GLfloat)from->b3; 114 + to[2][2] = (GLfloat)from->c3; 115 + to[2][3] = (GLfloat)from->d3; 104 116 105 - to[3][0] = (GLfloat)from->a4; 106 - to[3][1] = (GLfloat)from->b4; 107 - to[3][2] = (GLfloat)from->c4; 108 - to[3][3] = (GLfloat)from->d4; 117 + to[3][0] = (GLfloat)from->a4; 118 + to[3][1] = (GLfloat)from->b4; 119 + to[3][2] = (GLfloat)from->c4; 120 + to[3][3] = (GLfloat)from->d4; 109 121 110 - return to; 122 + return to; 111 123 } 112 124 113 125 114 - void util::print_texture_internalformat_info(GLenum internal_format) { 115 - if (!GLAD_GL_ARB_internalformat_query) { 116 - logs::warning( 117 - "Not printing texture_internalformat as this feature is not supported " 118 - "on this system." 119 - ); 120 - return; 121 - } 126 + void 127 + util::print_texture_internalformat_info(GLenum internal_format) 128 + { 129 + if (!GLAD_GL_ARB_internalformat_query) { 130 + logs::warning("Not printing texture_internalformat as this feature is not supported on this system."); 131 + return; 132 + } 122 133 123 - if (!GLAD_GL_ARB_internalformat_query2) { 124 - logs::warning( 125 - "Printing texture_internalformat, but some information may be missing, " 126 - "as internalformat_query2 is not supported on this system." 127 - ); 128 - } 134 + if (!GLAD_GL_ARB_internalformat_query2) { 135 + logs::warning("Printing texture_internalformat, but some information may be missing, as internalformat_query2 is not supported on this system."); 136 + } 129 137 130 - GLint preferred_format; 131 - GLint optimal_image_format; 132 - GLint optimal_image_type; 138 + GLint preferred_format; 139 + GLint optimal_image_format; 140 + GLint optimal_image_type; 133 141 134 - glGetInternalformativ( 135 - GL_TEXTURE_2D, internal_format, GL_INTERNALFORMAT_PREFERRED, 1, &preferred_format 136 - ); 137 - glGetInternalformativ( 138 - GL_TEXTURE_2D, internal_format, GL_TEXTURE_IMAGE_FORMAT, 1, &optimal_image_format 139 - ); 140 - glGetInternalformativ( 141 - GL_TEXTURE_2D, internal_format, GL_TEXTURE_IMAGE_TYPE, 1, &optimal_image_type 142 - ); 142 + glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_INTERNALFORMAT_PREFERRED, 1, &preferred_format); 143 + glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_TEXTURE_IMAGE_FORMAT, 1, &optimal_image_format); 144 + glGetInternalformativ(GL_TEXTURE_2D, internal_format, GL_TEXTURE_IMAGE_TYPE, 1, &optimal_image_type); 143 145 144 - logs::info("internal format: %s", stringify_glenum(internal_format)); 145 - logs::info("preferred format: %s", stringify_glenum(preferred_format)); 146 - logs::info("optimal image format: %s", stringify_glenum(optimal_image_format)); 147 - logs::info("optimal image type: %s", stringify_glenum(optimal_image_type)); 148 - logs::print_newline(); 146 + logs::info("internal format: %s", stringify_glenum(internal_format)); 147 + logs::info("preferred format: %s", stringify_glenum(preferred_format)); 148 + logs::info("optimal image format: %s", stringify_glenum(optimal_image_format)); 149 + logs::info("optimal image type: %s", stringify_glenum(optimal_image_type)); 150 + logs::print_newline(); 149 151 } 150 152 151 153 152 - void APIENTRY util::debug_message_callback( 153 - GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, 154 - const char *message, const void *userParam 154 + void 155 + APIENTRY util::debug_message_callback( 156 + GLenum source, 157 + GLenum type, 158 + unsigned int id, 159 + GLenum severity, 160 + GLsizei length, 161 + char const *message, 162 + const void *userParam 155 163 ) { 156 - // Ignore insignificant error/warning codes 157 - if ( 158 - // Framebuffer detailed info: The driver allocated storage for 159 - // renderbuffer 1. 160 - id == 131169 || 161 - // Program/shader state performance warning: Vertex shader in program 19 162 - // is being recompiled based on GL state. 163 - id == 131218 || 164 - // Buffer detailed info: Buffer object 1522 (bound to 165 - // GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), and GL_ARRAY_BUFFER_ARB, 166 - // usage hint is GL_DYNAMIC_DRAW) will use VIDEO memory as the source for 167 - // buffer object operations. 168 - id == 131185 || 169 - // Texture state usage warning: The texture object (0) bound to texture 170 - // image unit 4 does not have a defined base level and cannot be used for 171 - // texture mapping. 172 - id == 131204 || 173 - // Pixel-path performance warning: Pixel transfer is synchronized with 3D rendering. 174 - id == 131154 175 - ) { 176 - return; 177 - } 164 + // Ignore insignificant error/warning codes 165 + if ( 166 + // Framebuffer detailed info: The driver allocated storage for 167 + // renderbuffer 1. 168 + id == 131169 || 169 + // Program/shader state performance warning: Vertex shader in program 19 170 + // is being recompiled based on GL state. 171 + id == 131218 || 172 + // Buffer detailed info: Buffer object 1522 (bound to 173 + // GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB (0), and GL_ARRAY_BUFFER_ARB, 174 + // usage hint is GL_DYNAMIC_DRAW) will use VIDEO memory as the source for 175 + // buffer object operations. 176 + id == 131185 || 177 + // Texture state usage warning: The texture object (0) bound to texture 178 + // image unit 4 does not have a defined base level and cannot be used for 179 + // texture mapping. 180 + id == 131204 || 181 + // Pixel-path performance warning: Pixel transfer is synchronized with 3D rendering. 182 + id == 131154 183 + ) { 184 + return; 185 + } 178 186 179 - logs::warning("Debug message (%d): %s", id, message); 187 + logs::warning("Debug message (%d): %s", id, message); 180 188 181 - switch (source) { 189 + switch (source) { 182 190 case GL_DEBUG_SOURCE_API: 183 - logs::warning("Source: API"); 184 - break; 191 + logs::warning("Source: API"); 192 + break; 185 193 case GL_DEBUG_SOURCE_WINDOW_SYSTEM: 186 - logs::warning("Source: Window System"); 187 - break; 194 + logs::warning("Source: Window System"); 195 + break; 188 196 case GL_DEBUG_SOURCE_SHADER_COMPILER: 189 - logs::warning("Source: Shader Compiler"); 190 - break; 197 + logs::warning("Source: Shader Compiler"); 198 + break; 191 199 case GL_DEBUG_SOURCE_THIRD_PARTY: 192 - logs::warning("Source: Third Party"); 193 - break; 200 + logs::warning("Source: Third Party"); 201 + break; 194 202 case GL_DEBUG_SOURCE_APPLICATION: 195 - logs::warning("Source: Application"); 196 - break; 203 + logs::warning("Source: Application"); 204 + break; 197 205 case GL_DEBUG_SOURCE_OTHER: 198 - logs::warning("Source: Other"); 199 - break; 200 - } 206 + logs::warning("Source: Other"); 207 + break; 208 + } 201 209 202 - switch (type) { 210 + switch (type) { 203 211 case GL_DEBUG_TYPE_ERROR: 204 - logs::warning("Type: Error"); 205 - break; 212 + logs::warning("Type: Error"); 213 + break; 206 214 case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: 207 - logs::warning("Type: Deprecated Behaviour"); 208 - break; 215 + logs::warning("Type: Deprecated Behaviour"); 216 + break; 209 217 case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: 210 - logs::warning("Type: Undefined Behaviour"); 211 - break; 218 + logs::warning("Type: Undefined Behaviour"); 219 + break; 212 220 case GL_DEBUG_TYPE_PORTABILITY: 213 - logs::warning("Type: Portability"); 214 - break; 221 + logs::warning("Type: Portability"); 222 + break; 215 223 case GL_DEBUG_TYPE_PERFORMANCE: 216 - logs::warning("Type: Performance"); 217 - break; 224 + logs::warning("Type: Performance"); 225 + break; 218 226 case GL_DEBUG_TYPE_MARKER: 219 - logs::warning("Type: Marker"); 220 - break; 227 + logs::warning("Type: Marker"); 228 + break; 221 229 case GL_DEBUG_TYPE_PUSH_GROUP: 222 - logs::warning("Type: Push Group"); 223 - break; 230 + logs::warning("Type: Push Group"); 231 + break; 224 232 case GL_DEBUG_TYPE_POP_GROUP: 225 - logs::warning("Type: Pop Group"); 226 - break; 233 + logs::warning("Type: Pop Group"); 234 + break; 227 235 case GL_DEBUG_TYPE_OTHER: 228 - logs::warning("Type: Other"); 229 - break; 230 - } 236 + logs::warning("Type: Other"); 237 + break; 238 + } 231 239 232 - switch (severity) { 240 + switch (severity) { 233 241 case GL_DEBUG_SEVERITY_HIGH: 234 - logs::warning("Severity: high"); 235 - break; 242 + logs::warning("Severity: high"); 243 + break; 236 244 case GL_DEBUG_SEVERITY_MEDIUM: 237 - logs::warning("Severity: medium"); 238 - break; 245 + logs::warning("Severity: medium"); 246 + break; 239 247 case GL_DEBUG_SEVERITY_LOW: 240 - logs::warning("Severity: low"); 241 - break; 248 + logs::warning("Severity: low"); 249 + break; 242 250 case GL_DEBUG_SEVERITY_NOTIFICATION: 243 - logs::warning("Severity: notification"); 244 - break; 245 - } 251 + logs::warning("Severity: notification"); 252 + break; 253 + } 246 254 247 - logs::print_newline(); 255 + logs::print_newline(); 248 256 } 249 257 250 258 251 - real32 util::round_to_nearest_multiple(real32 n, real32 multiple_of) { 252 - return (floor((n) / multiple_of) * multiple_of) + multiple_of; 259 + real32 260 + util::round_to_nearest_multiple(real32 n, real32 multiple_of) 261 + { 262 + return (floor((n) / multiple_of) * multiple_of) + multiple_of; 253 263 } 254 264 255 265 256 - real64 util::get_us_from_duration(chrono::duration<real64> duration) { 257 - return chrono::duration_cast<chrono::duration<real64>>(duration).count(); 266 + real64 267 + util::get_us_from_duration(chrono::duration<real64> duration) 268 + { 269 + return chrono::duration_cast<chrono::duration<real64>>(duration).count(); 258 270 } 259 271 260 272 261 - v3 util::get_orthogonal_vector(v3 *v) { 262 - if (v->z < v->x) { 263 - return v3(v->y, -v->x, 0.0f); 264 - } else { 265 - return v3(0.0f, -v->z, v->y); 266 - } 273 + v3 274 + util::get_orthogonal_vector(v3 *v) 275 + { 276 + if (v->z < v->x) { 277 + return v3(v->y, -v->x, 0.0f); 278 + } else { 279 + return v3(0.0f, -v->z, v->y); 280 + } 267 281 } 268 282 269 283
+25 -24
src/util.hpp
··· 8 8 #include "../src_external/glad/glad.h" 9 9 #include "types.hpp" 10 10 11 - namespace util { 12 - const char* stringify_glenum(GLenum thing); 13 - GLenum get_texture_format_from_n_components(int32 n_components); 14 - real64 random(real64 min, real64 max); 15 - v3 aiVector3D_to_glm(aiVector3D *vec); 16 - quat aiQuaternion_to_glm(aiQuaternion *rotation); 17 - m4 aimatrix4x4_to_glm(aiMatrix4x4 *from); 18 - void print_texture_internalformat_info(GLenum internal_format); 19 - void APIENTRY debug_message_callback( 20 - GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, 21 - const char *message, const void *userParam 22 - ); 23 - real32 round_to_nearest_multiple(real32 n, real32 multiple_of); 24 - real64 get_us_from_duration(chrono::duration<real64> duration); 25 - v3 get_orthogonal_vector(v3 *v); 26 - uint32 kb_to_b(uint32 value); 27 - uint32 mb_to_b(uint32 value); 28 - uint32 gb_to_b(uint32 value); 29 - uint32 tb_to_b(uint32 value); 30 - real32 b_to_kb(uint32 value); 31 - real32 b_to_mb(uint32 value); 32 - real32 b_to_gb(uint32 value); 33 - real32 b_to_tb(uint32 value); 34 - } 11 + class util { 12 + public: 13 + static char const * stringify_glenum(GLenum thing); 14 + static GLenum get_texture_format_from_n_components(int32 n_components); 15 + static real64 random(real64 min, real64 max); 16 + static v3 aiVector3D_to_glm(aiVector3D *vec); 17 + static quat aiQuaternion_to_glm(aiQuaternion *rotation); 18 + static m4 aimatrix4x4_to_glm(aiMatrix4x4 *from); 19 + static void print_texture_internalformat_info(GLenum internal_format); 20 + static void APIENTRY debug_message_callback( 21 + GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, 22 + char const *message, const void *userParam 23 + ); 24 + static real32 round_to_nearest_multiple(real32 n, real32 multiple_of); 25 + static real64 get_us_from_duration(chrono::duration<real64> duration); 26 + static v3 get_orthogonal_vector(v3 *v); 27 + static uint32 kb_to_b(uint32 value); 28 + static uint32 mb_to_b(uint32 value); 29 + static uint32 gb_to_b(uint32 value); 30 + static uint32 tb_to_b(uint32 value); 31 + static real32 b_to_kb(uint32 value); 32 + static real32 b_to_mb(uint32 value); 33 + static real32 b_to_gb(uint32 value); 34 + static real32 b_to_tb(uint32 value); 35 + };