From e8bc8a1647aae4b9c0534910ac732fac34864dc7 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Wed, 25 Sep 2024 01:35:16 +0200 Subject: [PATCH] 1. improved AMS, 2. improved render scene structure for the future --- asset/Asset.h | 9 ++ asset/AssetManagementSystem.h | 12 +-- gpuapi/opengl/Opengl.h | 7 +- gpuapi/opengl/OpenglUtils.h | 193 ++++++++++++++++++++-------------- gpuapi/opengl/OpenglWin32.h | 14 +-- object/Texture.h | 1 + object/Vertex.h | 25 +++-- stdlib/HashMap.h | 24 ++++- 8 files changed, 181 insertions(+), 104 deletions(-) diff --git a/asset/Asset.h b/asset/Asset.h index e897d5f..b027c5d 100644 --- a/asset/Asset.h +++ b/asset/Asset.h @@ -46,6 +46,15 @@ struct Asset { bool is_ram; bool is_vram; + // Describes if the asset can be removed/garbage collected IF necessary + // This however only happens if space is needed + bool can_garbage_collect_ram; + bool can_garbage_collect_vram; + + // Describes if the asset should be removed/garbage collected during CPU/GPU down time + bool should_garbage_collect_ram; + bool should_garbage_collect_vram; + Asset* next; Asset* prev; diff --git a/asset/AssetManagementSystem.h b/asset/AssetManagementSystem.h index 03ae04c..dbf2f96 100644 --- a/asset/AssetManagementSystem.h +++ b/asset/AssetManagementSystem.h @@ -96,6 +96,7 @@ void ams_create(AssetManagementSystem* ams, byte* buf, int chunk_size, int count ams->last = NULL; } +inline uint64 ams_get_vram_usage(AssetManagementSystem* ams) { uint64 size = 0; @@ -119,19 +120,18 @@ void ams_free_asset(AssetManagementSystem* ams, Asset* asset) } } +inline Asset* ams_get_asset(AssetManagementSystem* ams, uint64 element) { return (Asset *) chunk_get_element(&ams->asset_memory, element, false); } +inline Asset* ams_get_asset(AssetManagementSystem* ams, const char* key) { - HashEntryInt64* entry = (HashEntryInt64 *) hashmap_get_entry(&ams->hash_map, key); - if (entry == NULL) { - return NULL; - } + HashEntry* entry = hashmap_get_entry(&ams->hash_map, key); - return (Asset *) chunk_get_element(&ams->asset_memory, entry->value, false); + return entry ? (Asset *) entry->value : NULL; } // @todo implement defragment command to optimize memory layout since the memory layout will become fragmented over time @@ -153,7 +153,7 @@ Asset* ams_reserve_asset(AssetManagementSystem* ams, const char* name, uint64 el strncpy(asset->name, name, name_length); asset->name[name_length] = '\0'; - hashmap_insert(&ams->hash_map, name, free_asset); + hashmap_insert(&ams->hash_map, name, (uintptr_t) asset); chunk_reserve_index(&ams->asset_data_memory, free_asset, elements, true); asset->self = chunk_get_element(&ams->asset_data_memory, free_asset); diff --git a/gpuapi/opengl/Opengl.h b/gpuapi/opengl/Opengl.h index d798c5c..2c0fa32 100644 --- a/gpuapi/opengl/Opengl.h +++ b/gpuapi/opengl/Opengl.h @@ -9,8 +9,6 @@ #ifndef TOS_GPUAPI_OPENGL_H #define TOS_GPUAPI_OPENGL_H -// @todo remove some of the unused consts below - // #define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 #define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 @@ -723,6 +721,11 @@ #define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC #define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD +#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 +#define GL_PROGRAM_BINARY_LENGTH 0x8741 +#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE +#define GL_PROGRAM_BINARY_FORMATS 0x87FF + typedef char GLchar; typedef ptrdiff_t GLsizeiptr; typedef ptrdiff_t GLintptr; diff --git a/gpuapi/opengl/OpenglUtils.h b/gpuapi/opengl/OpenglUtils.h index a7ad4f5..7bebe3f 100644 --- a/gpuapi/opengl/OpenglUtils.h +++ b/gpuapi/opengl/OpenglUtils.h @@ -109,12 +109,12 @@ uint32 get_texture_data_type(uint32 texture_data_type) // 4. load_texture_to_gpu inline -void prepare_texture(Texture* texture, uint32 texture_unit) +void prepare_texture(Texture* texture) { uint32 texture_data_type = get_texture_data_type(texture->texture_data_type); glGenTextures(1, (GLuint *) &texture->id); - glActiveTexture(GL_TEXTURE0 + texture_unit); + glActiveTexture(GL_TEXTURE0 + texture->sample_id); glBindTexture(texture_data_type, (GLuint) texture->id); } @@ -166,6 +166,7 @@ GLuint shader_make(GLenum type, const char *source, RingMemory* ring) return shader; } +inline GLuint shader_load(GLenum type, const char* path, RingMemory* ring) { uint64 temp = ring->pos; @@ -181,6 +182,15 @@ GLuint shader_load(GLenum type, const char* path, RingMemory* ring) { return result; } +inline +int32 program_get_size(uint32 program) +{ + int32 size; + glGetProgramiv(program, GL_PROGRAM_BINARY_LENGTH, &size); + + return size; +} + GLuint program_make( GLuint vertex_shader, GLuint fragment_shader, @@ -195,6 +205,7 @@ GLuint program_make( glAttachShader(program, vertex_shader); glAttachShader(program, fragment_shader); + glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); glLinkProgram(program); GLint status; @@ -263,27 +274,28 @@ void draw_triangles_3d(VertexRef* vertices, GLuint buffer, int count) { glBindBuffer(GL_ARRAY_BUFFER, buffer); // position attribute - glVertexAttribPointer(vertices->position, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) 0); - glEnableVertexAttribArray(vertices->position); + glVertexAttribPointer(vertices->data_id, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) 0); + glEnableVertexAttribArray(vertices->data_id); // normal attribute - glVertexAttribPointer(vertices->normal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 3)); - glEnableVertexAttribArray(vertices->normal); + glVertexAttribPointer(vertices->normal_id, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 3)); + glEnableVertexAttribArray(vertices->normal_id); // texture coord attribute - glVertexAttribIPointer(vertices->tex_coord, 2, GL_UNSIGNED_INT, sizeof(Vertex3D), (void *) (sizeof(float) * 6)); - glEnableVertexAttribArray(vertices->tex_coord); + // vs glVertexAttribPointer + glVertexAttribIPointer(vertices->tex_coord_id, 2, GL_UNSIGNED_INT, sizeof(Vertex3D), (void *) (sizeof(float) * 6)); + glEnableVertexAttribArray(vertices->tex_coord_id); // color attribute - glVertexAttribPointer(vertices->color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 8)); - glEnableVertexAttribArray(vertices->color); + glVertexAttribPointer(vertices->color_id, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 8)); + glEnableVertexAttribArray(vertices->color_id); glDrawArrays(GL_TRIANGLES, 0, count); - glDisableVertexAttribArray(vertices->position); - glDisableVertexAttribArray(vertices->normal); - glDisableVertexAttribArray(vertices->tex_coord); - glDisableVertexAttribArray(vertices->color); + glDisableVertexAttribArray(vertices->data_id); + glDisableVertexAttribArray(vertices->normal_id); + glDisableVertexAttribArray(vertices->tex_coord_id); + glDisableVertexAttribArray(vertices->color_id); glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -293,22 +305,22 @@ void draw_triangles_3d_textureless(VertexRef* vertices, GLuint buffer, int count glBindBuffer(GL_ARRAY_BUFFER, buffer); // position attribute - glVertexAttribPointer(vertices->position, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) 0); - glEnableVertexAttribArray(vertices->position); + glVertexAttribPointer(vertices->data_id, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) 0); + glEnableVertexAttribArray(vertices->data_id); // normal attribute - glVertexAttribPointer(vertices->normal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 3)); - glEnableVertexAttribArray(vertices->normal); + glVertexAttribPointer(vertices->normal_id, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 3)); + glEnableVertexAttribArray(vertices->normal_id); // color attribute - glVertexAttribPointer(vertices->color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 8)); - glEnableVertexAttribArray(vertices->color); + glVertexAttribPointer(vertices->color_id, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 8)); + glEnableVertexAttribArray(vertices->color_id); glDrawArrays(GL_TRIANGLES, 0, count); - glDisableVertexAttribArray(vertices->position); - glDisableVertexAttribArray(vertices->normal); - glDisableVertexAttribArray(vertices->color); + glDisableVertexAttribArray(vertices->data_id); + glDisableVertexAttribArray(vertices->normal_id); + glDisableVertexAttribArray(vertices->color_id); glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -318,22 +330,22 @@ void draw_triangles_3d_colorless(VertexRef* vertices, GLuint buffer, int count) glBindBuffer(GL_ARRAY_BUFFER, buffer); // position attribute - glVertexAttribPointer(vertices->position, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) 0); - glEnableVertexAttribArray(vertices->position); + glVertexAttribPointer(vertices->data_id, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) 0); + glEnableVertexAttribArray(vertices->data_id); // normal attribute - glVertexAttribPointer(vertices->normal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 3)); - glEnableVertexAttribArray(vertices->normal); + glVertexAttribPointer(vertices->normal_id, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 3)); + glEnableVertexAttribArray(vertices->normal_id); // texture coord attribute - glVertexAttribIPointer(vertices->tex_coord, 2, GL_UNSIGNED_INT, sizeof(Vertex3D), (void *) (sizeof(float) * 6)); - glEnableVertexAttribArray(vertices->tex_coord); + glVertexAttribIPointer(vertices->tex_coord_id, 2, GL_UNSIGNED_INT, sizeof(Vertex3D), (void *) (sizeof(float) * 6)); + glEnableVertexAttribArray(vertices->tex_coord_id); glDrawArrays(GL_TRIANGLES, 0, count); - glDisableVertexAttribArray(vertices->position); - glDisableVertexAttribArray(vertices->normal); - glDisableVertexAttribArray(vertices->tex_coord); + glDisableVertexAttribArray(vertices->data_id); + glDisableVertexAttribArray(vertices->normal_id); + glDisableVertexAttribArray(vertices->tex_coord_id); glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -343,22 +355,23 @@ void draw_triangles_2d(VertexRef* vertices, GLuint buffer, int count) { glBindBuffer(GL_ARRAY_BUFFER, buffer); // position attribute - glVertexAttribPointer(vertices->position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) 0); - glEnableVertexAttribArray(vertices->position); + glVertexAttribPointer(vertices->position_id, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) 0); + glEnableVertexAttribArray(vertices->position_id); // texture coord attribute - glVertexAttribIPointer(vertices->tex_coord, 2, GL_UNSIGNED_INT, sizeof(Vertex2D), (void *) (sizeof(float) * 2)); - glEnableVertexAttribArray(vertices->tex_coord); + // vs glVertexAttribPointer + glVertexAttribIPointer(vertices->tex_coord_id, 2, GL_UNSIGNED_INT, sizeof(Vertex2D), (void *) (sizeof(float) * 2)); + glEnableVertexAttribArray(vertices->tex_coord_id); // color attribute - glVertexAttribPointer(vertices->color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) (sizeof(float) * 4)); - glEnableVertexAttribArray(vertices->color); + glVertexAttribPointer(vertices->color_id, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) (sizeof(float) * 4)); + glEnableVertexAttribArray(vertices->color_id); glDrawArrays(GL_TRIANGLES, 0, count); - glDisableVertexAttribArray(vertices->position); - glDisableVertexAttribArray(vertices->tex_coord); - glDisableVertexAttribArray(vertices->color); + glDisableVertexAttribArray(vertices->position_id); + glDisableVertexAttribArray(vertices->tex_coord_id); + glDisableVertexAttribArray(vertices->color_id); glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -368,17 +381,17 @@ void draw_triangles_2d_textureless(VertexRef* vertices, GLuint buffer, int count glBindBuffer(GL_ARRAY_BUFFER, buffer); // position attribute - glVertexAttribPointer(vertices->position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) 0); - glEnableVertexAttribArray(vertices->position); + glVertexAttribPointer(vertices->data_id, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) 0); + glEnableVertexAttribArray(vertices->data_id); // color attribute - glVertexAttribPointer(vertices->color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) (sizeof(float) * 4)); - glEnableVertexAttribArray(vertices->color); + glVertexAttribPointer(vertices->color_id, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) (sizeof(float) * 4)); + glEnableVertexAttribArray(vertices->color_id); glDrawArrays(GL_TRIANGLES, 0, count); - glDisableVertexAttribArray(vertices->position); - glDisableVertexAttribArray(vertices->color); + glDisableVertexAttribArray(vertices->data_id); + glDisableVertexAttribArray(vertices->color_id); glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -388,36 +401,21 @@ void draw_triangles_2d_colorless(VertexRef* vertices, GLuint buffer, int count) glBindBuffer(GL_ARRAY_BUFFER, buffer); // position attribute - glVertexAttribPointer(vertices->position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) 0); - glEnableVertexAttribArray(vertices->position); + glVertexAttribPointer(vertices->data_id, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) 0); + glEnableVertexAttribArray(vertices->data_id); // texture coord attribute - glVertexAttribIPointer(vertices->tex_coord, 2, GL_UNSIGNED_INT, sizeof(Vertex2D), (void *) (sizeof(float) * 2)); - glEnableVertexAttribArray(vertices->tex_coord); + glVertexAttribIPointer(vertices->tex_coord_id, 2, GL_UNSIGNED_INT, sizeof(Vertex2D), (void *) (sizeof(float) * 2)); + glEnableVertexAttribArray(vertices->tex_coord_id); glDrawArrays(GL_TRIANGLES, 0, count); - glDisableVertexAttribArray(vertices->position); - glDisableVertexAttribArray(vertices->tex_coord); + glDisableVertexAttribArray(vertices->data_id); + glDisableVertexAttribArray(vertices->tex_coord_id); glBindBuffer(GL_ARRAY_BUFFER, 0); } -struct TextRender { - uint32 align; - uint32 x; - uint32 y; - float scale; // @is it really scale or is it position in texture map? - VertexRef vertices; - char* text; - - TextShader shader_data; -}; - -#define TEXT_ALIGN_LEFT 0 -#define TEXT_ALIGN_CENTER 1 -#define TEXT_ALIGN_RIGHT 2 - inline int calculate_face_size(int components, int faces) { @@ -511,42 +509,75 @@ int get_gpu_free_memory() return available; } +struct TextRender { + uint32 align; + uint32 x; + uint32 y; + float scale; + VertexRef vertices; + char* text; + + uint32 sampler_id; + + TextShader shader_data; +}; + +#define TEXT_ALIGN_LEFT 0 +#define TEXT_ALIGN_CENTER 1 +#define TEXT_ALIGN_RIGHT 2 + +// @performance This needs to handle batched randering, isolated rendering is WAY to inefficient inline -void render_text( +void render_text_batched( + RingMemory* ring, int width, int height, TextRender* text_data ) { glUseProgram(text_data->shader_data.program_id); - glUniform1i(text_data->shader_data.sampler_id, 1); + glUniform1i(text_data->shader_data.sampler_addr, text_data->vertices.sampler_id); // @performance Instead of re-creating the matrix every render call just use the id to activate it // 2d projection if (text_data->shader_data.matrix_id == 0) { float matrix[16] = {}; mat4_ortho_sparse_rh(matrix, 0.0f, (float) width, 0.0f, (float) height, -1.0f, 1.0f); - glUniformMatrix4fv(text_data->shader_data.matrix_id, 1, GL_FALSE, matrix); + glUniformMatrix4fv(text_data->shader_data.matrix_addr, 1, GL_FALSE, matrix); + text_data->shader_data.matrix_id = 1; + // @bug this is wrong, we need to make buffer instead. We don't want to upload the matrix every time + // Isn't this buffer the same for every text? + // If yes, consider to save the orth projection matrix globally and change it whenever we change the resolution/window dimensions } else { - + // @question Do we even need to bind it if we never change it? + // We also never bind our projection matrix apart from the first time and it works. This should be the same no? + //glBindVertexArray(text_data->shader_data.matrix_id); } int length = (int) strlen(text_data->text); float x = text_data->x - text_data->scale * text_data->align * (length - 1) / 2; - // @todo fix - GLfloat *data = NULL; //malloc_faces(4, length); // sizeof(GLfloat) * 6 * 4 * length + // @performance Only create when the text got removed from memory + if (text_data->vertices.data_id == 0) { + GLfloat *data = (GLfloat *) ring_get_memory(ring, sizeof(GLfloat) * 6 * 4 * length); - for (int i = 0; i < length; i++) { - make_character(data + i * 24, x, (float) text_data->y, text_data->scale / 2, text_data->scale, text_data->text[i]); - x += text_data->scale; + for (int i = 0; i < length; i++) { + make_character(data + i * 24, x, (float) text_data->y, text_data->scale / 2, text_data->scale, text_data->text[i]); + x += text_data->scale; + } + + text_data->vertices.data_id = gpuapi_buffer_generate(sizeof(GLfloat) * 6 * 4 * length, data); + } else { + glBindBuffer(GL_ARRAY_BUFFER, text_data->vertices.data_id); + //glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); Is this required? } - GLuint buffer = gpuapi_buffer_generate(sizeof(GLfloat) * 6 * 4 * length, data); - glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - draw_triangles_2d(&text_data->vertices, buffer, length * 6); + draw_triangles_2d(&text_data->vertices, text_data->vertices.data_id, length * 6); glDisable(GL_BLEND); - glDeleteBuffers(1, &buffer); + + // @performance We should only delete the buffer, when the text becomes invisible + // @todo remember to implement a remove logic for all the buffers + //glDeleteBuffers(1, &text_data->vertices.data_id); } /* diff --git a/gpuapi/opengl/OpenglWin32.h b/gpuapi/opengl/OpenglWin32.h index 0b01d55..d8d953e 100644 --- a/gpuapi/opengl/OpenglWin32.h +++ b/gpuapi/opengl/OpenglWin32.h @@ -1040,7 +1040,6 @@ extern "C" { (GLenum target, GLenum pname, GLfloat *params); } - typedef void WINAPI type_glTexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); static type_glTexImage2DMultisample* glTexImage2DMultisample; @@ -1218,6 +1217,9 @@ static type_glDrawArraysInstanced* glDrawArraysInstanced; typedef void WINAPI type_glDrawElementsInstanced(GLenum mode, GLint count, GLenum type, const void* indices, GLsizei instancecount); static type_glDrawElementsInstanced* glDrawElementsInstanced; +typedef void WINAPI type_glProgramParameteri(GLuint program, GLenum pname, GLint value); +static type_glProgramParameteri* glProgramParameteri; + #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 @@ -1298,7 +1300,6 @@ static type_glDrawElementsInstanced* glDrawElementsInstanced; #define WGL_ALPHA_BITS_ARB 0x201B #define WGL_DEPTH_BITS_ARB 0x2022 - typedef HGLRC WINAPI wgl_create_context_attribs_arb(HDC hDC, HGLRC hShareContext, const int *attribList); static wgl_create_context_attribs_arb* wglCreateContextAttribsARB; @@ -1496,10 +1497,7 @@ void opengl_init_gl() glGetShaderiv = (type_glGetShaderiv *) wglGetProcAddress("glGetShaderiv"); glDrawArraysInstanced = (type_glDrawArraysInstanced *) wglGetProcAddress("glDrawArraysInstanced"); glDrawElementsInstanced = (type_glDrawElementsInstanced *) wglGetProcAddress("glDrawElementsInstanced"); - - if (wglSwapIntervalEXT) { - wglSwapIntervalEXT(0); - } + glProgramParameteri = (type_glProgramParameteri *) wglGetProcAddress("glProgramParameteri"); } void opengl_init(Window* window) @@ -1524,6 +1522,10 @@ void opengl_init(Window* window) } opengl_init_gl(); + + if (wglSwapIntervalEXT) { + wglSwapIntervalEXT(0); + } } #endif \ No newline at end of file diff --git a/object/Texture.h b/object/Texture.h index 11a2c4a..12d43df 100644 --- a/object/Texture.h +++ b/object/Texture.h @@ -38,6 +38,7 @@ struct Texture { uint64 id; + byte sample_id; // @question Should the texture hold the texture unit? // If yes remember to update prepare_texture() diff --git a/object/Vertex.h b/object/Vertex.h index 70b6a71..f40b555 100644 --- a/object/Vertex.h +++ b/object/Vertex.h @@ -25,20 +25,29 @@ struct Vertex2D { }; struct VertexRef { - uint32 position; - uint32 normal; - uint32 tex_coord; - uint32 color; - uint32 index; + uint32 data_id; + + uint32 position_id; + uint32 normal_id; + + uint32 tex_coord_id; + uint32 sampler_id; // e.g. GL_TEXTURE0 + + uint32 color_id; + + uint32 index_id; }; // Data for the text shader struct TextShader { uint32 program_id; + uint32 matrix_id; - uint32 uv_id; - uint32 color_id; - uint32 sampler_id; + uint32 matrix_addr; + + uint32 uv_addr; + uint32 color_addr; + uint32 sampler_addr; }; enum VertexType { diff --git a/stdlib/HashMap.h b/stdlib/HashMap.h index 946090a..b096078 100644 --- a/stdlib/HashMap.h +++ b/stdlib/HashMap.h @@ -31,6 +31,13 @@ struct HashEntryInt64 { int64 value; }; +struct HashEntryUIntPtr { + int64 element_id; + char key[MAX_KEY_LENGTH]; + HashEntryUIntPtr* next; + uintptr_t value; +}; + struct HashEntryVoidP { int64 element_id; char key[MAX_KEY_LENGTH]; @@ -141,6 +148,21 @@ void hashmap_insert(HashMap* hm, const char* key, int64 value) { hm->table[index] = entry; } +void hashmap_insert(HashMap* hm, const char* key, uintptr_t value) { + uint64 index = hash_djb2(key) % hm->buf.count; + + int64 element = chunk_reserve(&hm->buf, 1); + HashEntryUIntPtr* entry = (HashEntryUIntPtr *) chunk_get_element(&hm->buf, element, true); + entry->element_id = element; + + strncpy(entry->key, key, MAX_KEY_LENGTH); + entry->key[MAX_KEY_LENGTH - 1] = '\0'; + + entry->value = value; + entry->next = (HashEntryUIntPtr *) hm->table[index]; + hm->table[index] = entry; +} + void hashmap_insert(HashMap* hm, const char* key, void* value) { uint64 index = hash_djb2(key) % hm->buf.count; @@ -206,7 +228,7 @@ void hashmap_insert(HashMap* hm, const char* key, byte* value) { hm->table[index] = entry; } -void* hashmap_get_entry(HashMap* hm, const char* key) { +HashEntry* hashmap_get_entry(HashMap* hm, const char* key) { uint64 index = hash_djb2(key) % hm->buf.count; HashEntry* entry = (HashEntry *) hm->table[index];