rotating cubes

This commit is contained in:
Dennis Eichhorn 2024-09-11 05:56:09 +02:00
parent 7f1a35d61a
commit 8335444c03
68 changed files with 5211 additions and 937 deletions

View File

@ -10,17 +10,20 @@
#ifndef TOS_ANIMATION_H
#define TOS_ANIMATION_H
#include <math.h>
#include "../utils/MathUtils.h"
#include "AnimationEaseType.h"
inline
float lerp_approx(float a, float b, float t)
float lerp(float a, float b, float t)
{
return a + t * (b - a);
}
float smoothstep(float t) {
return t * t * (3 - 2 * t);
}
float anim_ease(float t, AnimationEaseType type) {
switch(type) {
case ANIMATION_EASE_IN_SINE: {
@ -182,6 +185,11 @@ float anim_ease_out_quart(float t) {
return 1 - pow(1 - t, 4);
}
inline
float anim_ease_in_perlin(float t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
inline
float anim_ease_in_out_quart(float t) {
return t < 0.5

View File

@ -10,20 +10,22 @@
#define TOS_ASSET_H
#include "../stdlib/Types.h"
#include "../object/Vertex.h"
#include "../stdlib/HashMap.h"
#define MAX_ASSET_NAME_LENGTH 32
struct Asset {
// A id of 0 means the entity is no longer alive
// The id is the same as its location in memory/in the ecs array
// This is is only an internal id and NOT the same as a db id (e.g. player id)
uint32 internal_id;
uint32 type;
uint64 internal_id;
// Could be 0 if there is no official id
uint32 official_id;
uint64 official_id;
uint32 vao; // vertex buffer
uint32 vbo; // index buffer
uint32 ebo; // input layout
char name[MAX_ASSET_NAME_LENGTH];
uint32 type;
// Counts the references to this entity
// e.g. textures
@ -31,8 +33,8 @@ struct Asset {
// Describes how much ram/vram the asset uses
// E.g. vram_size = 0 but ram_size > 0 means that it never uses any gpu memory
uint32 ram_size;
uint32 vram_size;
uint64 ram_size;
uint64 vram_size;
// Usually 1 but in some cases an ECS may hold entities of variable chunk length
// For textures for example a 128x128 is of size 1 but 256x256 is of size 4

View File

@ -15,6 +15,7 @@
#include "AssetType.h"
#include "../memory/ChunkMemory.h"
#include "../utils/TestUtils.h"
#include "../stdlib/HashMap.h"
// The major asset types should have their own asset component system
// All other entities are grouped together in one asset component system
@ -22,6 +23,8 @@
// @bug This means players might not be able to transition from one area to another?!
struct AssetManagementSystem {
HashMap hash_map;
// The indices of asset_memory and asset_data_memory are always linked
// General asset memory
@ -34,7 +37,66 @@ struct AssetManagementSystem {
Asset* last;
};
int ams_get_vram_usage(AssetManagementSystem* ams)
void ams_create(AssetManagementSystem* ams, BufferMemory* buf, int chunk_size, int count)
{
// setup hash_map
hashmap_create(&ams->hash_map, count, sizeof(HashEntryInt64), buf);
// setup asset_memory
ams->asset_memory.count = count;
ams->asset_memory.chunk_size = sizeof(Asset);
ams->asset_memory.last_pos = -1;
ams->asset_memory.alignment = 1;
ams->asset_memory.memory = buffer_get_memory(buf, sizeof(Asset) * count);
ams->asset_memory.free = (uint64 *) buffer_get_memory(buf, CEIL_DIV(count, 64) * sizeof(uint64));
// setup asset_data_memory
ams->asset_data_memory.count = count;
ams->asset_data_memory.chunk_size = chunk_size;
ams->asset_data_memory.last_pos = -1;
ams->asset_data_memory.alignment = 1;
ams->asset_data_memory.memory = buffer_get_memory(buf, chunk_size * count);
ams->asset_data_memory.free = (uint64 *) buffer_get_memory(buf, CEIL_DIV(count, 64) * sizeof(uint64));
ams->first = NULL;
ams->last = NULL;
}
inline
int64 ams_get_buffer_size(int count, int chunk_size)
{
return hashmap_get_buffer_size(count, sizeof(HashEntryInt64)) // hash map
+ sizeof(Asset) * count + CEIL_DIV(count, 64) * sizeof(uint64) // asset_memory
+ chunk_size * count + CEIL_DIV(count, 64) * sizeof(uint64); // asset_data_memory
}
// WARNING: buf size see ams_get_buffer_size
void ams_create(AssetManagementSystem* ams, byte* buf, int chunk_size, int count)
{
// setup hash_map
hashmap_create(&ams->hash_map, count, sizeof(HashEntryInt64), buf);
// setup asset_memory
ams->asset_memory.count = count;
ams->asset_memory.chunk_size = sizeof(Asset);
ams->asset_memory.last_pos = -1;
ams->asset_memory.alignment = 1;
ams->asset_memory.memory = buf;
ams->asset_memory.free = (uint64 *) (ams->asset_memory.memory + sizeof(Asset) * count);
// setup asset_data_memory
ams->asset_data_memory.count = count;
ams->asset_data_memory.chunk_size = chunk_size;
ams->asset_data_memory.last_pos = -1;
ams->asset_data_memory.alignment = 1;
ams->asset_data_memory.memory = (byte *) (ams->asset_data_memory.free + CEIL_DIV(count, 64));
ams->asset_data_memory.free = (uint64 *) (ams->asset_data_memory.memory + chunk_size * count);
ams->first = NULL;
ams->last = NULL;
}
uint64 ams_get_vram_usage(AssetManagementSystem* ams)
{
uint64 size = 0;
for (int i = 0; i < ams->asset_memory.count; ++i) {
@ -44,29 +106,57 @@ int ams_get_vram_usage(AssetManagementSystem* ams)
return size;
}
void asset_delete(AssetManagementSystem* ams, Asset* asset)
void ams_free_asset(AssetManagementSystem* ams, Asset* asset)
{
asset->prev->next = asset->next;
asset->next->prev = asset->prev;
for (int i = 0; i < asset->size; ++i) {
chunk_element_free(&ams->asset_memory, asset->internal_id + i);
chunk_element_free(&ams->asset_data_memory, asset->internal_id + i);
hashmap_delete_entry(&ams->hash_map, asset->name);
for (uint32 i = 0; i < asset->size; ++i) {
chunk_free_element(&ams->asset_memory, asset->internal_id + i);
chunk_free_element(&ams->asset_data_memory, asset->internal_id + i);
}
}
Asset* ams_get_asset(AssetManagementSystem* ams, uint64 element)
{
return (Asset *) chunk_get_element(&ams->asset_memory, element, false);
}
Asset* ams_get_asset(AssetManagementSystem* ams, const char* key)
{
HashEntryInt64* entry = (HashEntryInt64 *) hashmap_get_entry(&ams->hash_map, key);
if (entry == NULL) {
return NULL;
}
return (Asset *) chunk_get_element(&ams->asset_memory, entry->value, false);
}
// @todo implement defragment command to optimize memory layout since the memory layout will become fragmented over time
Asset* asset_reserve(AssetManagementSystem* ams, uint64 elements = 1)
Asset* ams_reserve_asset(AssetManagementSystem* ams, const char* name, uint64 elements = 1)
{
int64 free_asset = chunk_reserve(&ams->asset_memory, elements, true);
if (free_asset < 0) {
ASSERT_SIMPLE(free_asset >= 0);
return NULL;
}
size_t name_length = strlen(name);
ASSERT_SIMPLE(name_length < MAX_ASSET_NAME_LENGTH - 1);
Asset* asset = (Asset *) chunk_get_element(&ams->asset_memory, free_asset);
asset->internal_id = free_asset;
strncpy(asset->name, name, name_length);
asset->name[name_length] = '\0';
hashmap_insert(&ams->hash_map, name, free_asset);
chunk_reserve_index(&ams->asset_data_memory, free_asset, elements, true);
Asset* asset = (Asset *) chunk_get_memory(&ams->asset_memory, free_asset);
asset->internal_id = free_asset;
asset->self = chunk_get_memory(&ams->asset_data_memory, free_asset);
asset->self = chunk_get_element(&ams->asset_data_memory, free_asset);
asset->ram_size = ams->asset_memory.chunk_size * elements;
// @performance Do we really want a double linked list. Are we really using this feature or is the free_index enough?

View File

@ -10,6 +10,7 @@
#define TOS_COMPRESSION_LZP_H
#include <stdio.h>
#include <string.h>
#include "../stdlib/Types.h"
@ -101,4 +102,94 @@ uint32 decode_lzp(const byte* in, size_t length, byte* out)
return out_pos;
}
int find_longest_match(char *window, int window_start, char *buffer, int buffer_size, int *match_position) {
int best_length = 0;
int best_offset = 0;
for (int i = window_start; i < 4096 && i < buffer_size; ++i) {
int length = 0;
while (length < 18 &&
i + length < 4096 &&
buffer[length] == window[i + length]) {
length++;
}
if (length > best_length) {
best_length = length;
best_offset = i;
}
}
*match_position = best_offset;
return best_length;
}
uint32 encode_lzp3(const byte* in, size_t length, byte* out) {
char window[4096] = {0};
int window_start = 0;
int out_size = 0;
int i = 0;
while (i < length) {
int match_position = 0;
int match_length = find_longest_match(window, window_start, (char *)&in[i], (int) (length - i), &match_position);
if (match_length > 2) {
out[out_size++] = 0xFF;
out[out_size++] = match_position & 0xFF;
out[out_size++] = match_length & 0xFF;
i += match_length;
} else {
out[out_size++] = in[i];
++i;
}
int shift_length = match_length > 0 ? match_length : 1;
memmove(window, window + shift_length, 4096 - shift_length);
memcpy(window + (4096 - shift_length), &in[i - shift_length], shift_length);
window_start = (window_start + shift_length) >= 4096 ? 0 : window_start + shift_length;
}
return out_size;
}
uint32 decode_lzp3(const byte* in, size_t length, byte* out) {
char window[4096] = {0};
int window_start = 0;
int out_size = 0;
int i = 0;
while (i < length) {
if (in[i] == 0xFF) {
int match_position = in[i + 1];
int match_length = in[i + 2];
for (int j = 0; j < match_length; j++) {
out[out_size++] = window[(match_position + j) % 4096];
}
memmove(window, window + match_length, 4096 - match_length);
memcpy(window + (4096 - match_length), &out[out_size - match_length], match_length);
window_start = (window_start + match_length) >= 4096 ? 0 : window_start + match_length;
i += 3;
} else {
out[out_size++] = in[i];
memmove(window, window + 1, 4096 - 1);
window[4096 - 1] = in[i];
window_start = (window_start + 1) >= 4096 ? 0 : window_start + 1;
++i;
}
}
return out_size;
}
#endif

View File

@ -6,8 +6,8 @@
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_GPUAPI_DIRECT3D_UTILS
#define TOS_GPUAPI_DIRECT3D_UTILS
#ifndef TOS_GPUAPI_DIRECTX_UTILS_H
#define TOS_GPUAPI_DIRECTX_UTILS_H
#include <windows.h>
#include <wrl.h>
@ -60,7 +60,7 @@ void window_create(Window* window, void* proc)
wc.style = CS_OWNDC;
wc.lpfnWndProc = wndproc;
wc.hInstance = hinstance;
wc.lpszClassName = (LPCWSTR) window->name;
wc.lpszClassName = (LPCSTR) window->name;
RegisterClassEx(&wc);

738
gpuapi/opengl/Opengl.h Normal file
View File

@ -0,0 +1,738 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_GPUAPI_OPENGL_H
#define TOS_GPUAPI_OPENGL_H
#include <gl/GL.h>
// @todo remove some of the unused consts below
//
#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12
#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13
#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22
#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23
#define GL_UNSIGNED_BYTE_3_3_2 0x8032
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
#define GL_UNSIGNED_INT_8_8_8_8 0x8035
#define GL_UNSIGNED_INT_10_10_10_2 0x8036
#define GL_RESCALE_NORMAL 0x803A
#define GL_TEXTURE_BINDING_3D 0x806A
#define GL_PACK_SKIP_IMAGES 0x806B
#define GL_PACK_IMAGE_HEIGHT 0x806C
#define GL_UNPACK_SKIP_IMAGES 0x806D
#define GL_UNPACK_IMAGE_HEIGHT 0x806E
#define GL_TEXTURE_3D 0x806F
#define GL_PROXY_TEXTURE_3D 0x8070
#define GL_TEXTURE_DEPTH 0x8071
#define GL_TEXTURE_WRAP_R 0x8072
#define GL_MAX_3D_TEXTURE_SIZE 0x8073
#define GL_BGR 0x80E0
#define GL_BGRA 0x80E1
#define GL_MAX_ELEMENTS_VERTICES 0x80E8
#define GL_MAX_ELEMENTS_INDICES 0x80E9
#define GL_CLAMP_TO_EDGE 0x812F
#define GL_TEXTURE_MIN_LOD 0x813A
#define GL_TEXTURE_MAX_LOD 0x813B
#define GL_TEXTURE_BASE_LEVEL 0x813C
#define GL_TEXTURE_MAX_LEVEL 0x813D
#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8
#define GL_SINGLE_COLOR 0x81F9
#define GL_SEPARATE_SPECULAR_COLOR 0x81FA
#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362
#define GL_UNSIGNED_SHORT_5_6_5 0x8363
#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364
#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365
#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366
#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
#define GL_ALIASED_POINT_SIZE_RANGE 0x846D
#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E
//
#define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE
#define GL_FOG_COORD GL_FOG_COORDINATE
#define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY
#define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING
#define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER
#define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE
#define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE
#define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE
#define GL_SRC0_ALPHA GL_SOURCE0_ALPHA
#define GL_SRC0_RGB GL_SOURCE0_RGB
#define GL_SRC1_ALPHA GL_SOURCE1_ALPHA
#define GL_SRC1_RGB GL_SOURCE1_RGB
#define GL_SRC2_ALPHA GL_SOURCE2_ALPHA
#define GL_SRC2_RGB GL_SOURCE2_RGB
#define GL_BUFFER_SIZE 0x8764
#define GL_BUFFER_USAGE 0x8765
#define GL_QUERY_COUNTER_BITS 0x8864
#define GL_CURRENT_QUERY 0x8865
#define GL_QUERY_RESULT 0x8866
#define GL_QUERY_RESULT_AVAILABLE 0x8867
#define GL_ARRAY_BUFFER 0x8892
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
#define GL_ARRAY_BUFFER_BINDING 0x8894
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896
#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897
#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898
#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899
#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A
#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B
#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C
#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D
#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F
#define GL_READ_ONLY 0x88B8
#define GL_WRITE_ONLY 0x88B9
#define GL_READ_WRITE 0x88BA
#define GL_BUFFER_ACCESS 0x88BB
#define GL_BUFFER_MAPPED 0x88BC
#define GL_BUFFER_MAP_POINTER 0x88BD
#define GL_STREAM_DRAW 0x88E0
#define GL_STREAM_READ 0x88E1
#define GL_STREAM_COPY 0x88E2
#define GL_STATIC_DRAW 0x88E4
#define GL_STATIC_READ 0x88E5
#define GL_STATIC_COPY 0x88E6
#define GL_DYNAMIC_DRAW 0x88E8
#define GL_DYNAMIC_READ 0x88E9
#define GL_DYNAMIC_COPY 0x88EA
#define GL_SAMPLES_PASSED 0x8914
//
#define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
#define GL_CURRENT_VERTEX_ATTRIB 0x8626
#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642
#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
#define GL_STENCIL_BACK_FUNC 0x8800
#define GL_STENCIL_BACK_FAIL 0x8801
#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802
#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803
#define GL_MAX_DRAW_BUFFERS 0x8824
#define GL_DRAW_BUFFER0 0x8825
#define GL_DRAW_BUFFER1 0x8826
#define GL_DRAW_BUFFER2 0x8827
#define GL_DRAW_BUFFER3 0x8828
#define GL_DRAW_BUFFER4 0x8829
#define GL_DRAW_BUFFER5 0x882A
#define GL_DRAW_BUFFER6 0x882B
#define GL_DRAW_BUFFER7 0x882C
#define GL_DRAW_BUFFER8 0x882D
#define GL_DRAW_BUFFER9 0x882E
#define GL_DRAW_BUFFER10 0x882F
#define GL_DRAW_BUFFER11 0x8830
#define GL_DRAW_BUFFER12 0x8831
#define GL_DRAW_BUFFER13 0x8832
#define GL_DRAW_BUFFER14 0x8833
#define GL_DRAW_BUFFER15 0x8834
#define GL_BLEND_EQUATION_ALPHA 0x883D
#define GL_POINT_SPRITE 0x8861
#define GL_COORD_REPLACE 0x8862
#define GL_MAX_VERTEX_ATTRIBS 0x8869
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
#define GL_MAX_TEXTURE_COORDS 0x8871
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
#define GL_FRAGMENT_SHADER 0x8B30
#define GL_VERTEX_SHADER 0x8B31
#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49
#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A
#define GL_MAX_VARYING_FLOATS 0x8B4B
#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C
#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D
#define GL_SHADER_TYPE 0x8B4F
#define GL_FLOAT_VEC2 0x8B50
#define GL_FLOAT_VEC3 0x8B51
#define GL_FLOAT_VEC4 0x8B52
#define GL_INT_VEC2 0x8B53
#define GL_INT_VEC3 0x8B54
#define GL_INT_VEC4 0x8B55
#define GL_BOOL 0x8B56
#define GL_BOOL_VEC2 0x8B57
#define GL_BOOL_VEC3 0x8B58
#define GL_BOOL_VEC4 0x8B59
#define GL_FLOAT_MAT2 0x8B5A
#define GL_FLOAT_MAT3 0x8B5B
#define GL_FLOAT_MAT4 0x8B5C
#define GL_SAMPLER_1D 0x8B5D
#define GL_SAMPLER_2D 0x8B5E
#define GL_SAMPLER_3D 0x8B5F
#define GL_SAMPLER_CUBE 0x8B60
#define GL_SAMPLER_1D_SHADOW 0x8B61
#define GL_SAMPLER_2D_SHADOW 0x8B62
#define GL_DELETE_STATUS 0x8B80
#define GL_COMPILE_STATUS 0x8B81
#define GL_LINK_STATUS 0x8B82
#define GL_VALIDATE_STATUS 0x8B83
#define GL_INFO_LOG_LENGTH 0x8B84
#define GL_ATTACHED_SHADERS 0x8B85
#define GL_ACTIVE_UNIFORMS 0x8B86
#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87
#define GL_SHADER_SOURCE_LENGTH 0x8B88
#define GL_ACTIVE_ATTRIBUTES 0x8B89
#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A
#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B
#define GL_SHADING_LANGUAGE_VERSION 0x8B8C
#define GL_CURRENT_PROGRAM 0x8B8D
#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0
#define GL_LOWER_LEFT 0x8CA1
#define GL_UPPER_LEFT 0x8CA2
#define GL_STENCIL_BACK_REF 0x8CA3
#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4
#define GL_STENCIL_BACK_WRITEMASK 0x8CA5
#define GL_MULTISAMPLE 0x809D
#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E
#define GL_SAMPLE_ALPHA_TO_ONE 0x809F
#define GL_SAMPLE_COVERAGE 0x80A0
#define GL_SAMPLE_BUFFERS 0x80A8
#define GL_SAMPLES 0x80A9
#define GL_SAMPLE_COVERAGE_VALUE 0x80AA
#define GL_SAMPLE_COVERAGE_INVERT 0x80AB
#define GL_CLAMP_TO_BORDER 0x812D
#define GL_TEXTURE0 0x84C0
#define GL_TEXTURE1 0x84C1
#define GL_TEXTURE2 0x84C2
#define GL_TEXTURE3 0x84C3
#define GL_TEXTURE4 0x84C4
#define GL_TEXTURE5 0x84C5
#define GL_TEXTURE6 0x84C6
#define GL_TEXTURE7 0x84C7
#define GL_TEXTURE8 0x84C8
#define GL_TEXTURE9 0x84C9
#define GL_TEXTURE10 0x84CA
#define GL_TEXTURE11 0x84CB
#define GL_TEXTURE12 0x84CC
#define GL_TEXTURE13 0x84CD
#define GL_TEXTURE14 0x84CE
#define GL_TEXTURE15 0x84CF
#define GL_TEXTURE16 0x84D0
#define GL_TEXTURE17 0x84D1
#define GL_TEXTURE18 0x84D2
#define GL_TEXTURE19 0x84D3
#define GL_TEXTURE20 0x84D4
#define GL_TEXTURE21 0x84D5
#define GL_TEXTURE22 0x84D6
#define GL_TEXTURE23 0x84D7
#define GL_TEXTURE24 0x84D8
#define GL_TEXTURE25 0x84D9
#define GL_TEXTURE26 0x84DA
#define GL_TEXTURE27 0x84DB
#define GL_TEXTURE28 0x84DC
#define GL_TEXTURE29 0x84DD
#define GL_TEXTURE30 0x84DE
#define GL_TEXTURE31 0x84DF
#define GL_ACTIVE_TEXTURE 0x84E0
#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1
#define GL_MAX_TEXTURE_UNITS 0x84E2
#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3
#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4
#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5
#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6
#define GL_SUBTRACT 0x84E7
#define GL_COMPRESSED_ALPHA 0x84E9
#define GL_COMPRESSED_LUMINANCE 0x84EA
#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB
#define GL_COMPRESSED_INTENSITY 0x84EC
#define GL_COMPRESSED_RGB 0x84ED
#define GL_COMPRESSED_RGBA 0x84EE
#define GL_TEXTURE_COMPRESSION_HINT 0x84EF
#define GL_NORMAL_MAP 0x8511
#define GL_REFLECTION_MAP 0x8512
#define GL_TEXTURE_CUBE_MAP 0x8513
#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A
#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C
#define GL_COMBINE 0x8570
#define GL_COMBINE_RGB 0x8571
#define GL_COMBINE_ALPHA 0x8572
#define GL_RGB_SCALE 0x8573
#define GL_ADD_SIGNED 0x8574
#define GL_INTERPOLATE 0x8575
#define GL_CONSTANT 0x8576
#define GL_PRIMARY_COLOR 0x8577
#define GL_PREVIOUS 0x8578
#define GL_SOURCE0_RGB 0x8580
#define GL_SOURCE1_RGB 0x8581
#define GL_SOURCE2_RGB 0x8582
#define GL_SOURCE0_ALPHA 0x8588
#define GL_SOURCE1_ALPHA 0x8589
#define GL_SOURCE2_ALPHA 0x858A
#define GL_OPERAND0_RGB 0x8590
#define GL_OPERAND1_RGB 0x8591
#define GL_OPERAND2_RGB 0x8592
#define GL_OPERAND0_ALPHA 0x8598
#define GL_OPERAND1_ALPHA 0x8599
#define GL_OPERAND2_ALPHA 0x859A
#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0
#define GL_TEXTURE_COMPRESSED 0x86A1
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2
#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3
#define GL_DOT3_RGB 0x86AE
#define GL_DOT3_RGBA 0x86AF
#define GL_MULTISAMPLE_BIT 0x20000000
//
#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F
#define GL_PIXEL_PACK_BUFFER 0x88EB
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED
#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
#define GL_FLOAT_MAT2x3 0x8B65
#define GL_FLOAT_MAT2x4 0x8B66
#define GL_FLOAT_MAT3x2 0x8B67
#define GL_FLOAT_MAT3x4 0x8B68
#define GL_FLOAT_MAT4x2 0x8B69
#define GL_FLOAT_MAT4x3 0x8B6A
#define GL_SRGB 0x8C40
#define GL_SRGB8 0x8C41
#define GL_SRGB_ALPHA 0x8C42
#define GL_SRGB8_ALPHA8 0x8C43
#define GL_SLUMINANCE_ALPHA 0x8C44
#define GL_SLUMINANCE8_ALPHA8 0x8C45
#define GL_SLUMINANCE 0x8C46
#define GL_SLUMINANCE8 0x8C47
#define GL_COMPRESSED_SRGB 0x8C48
#define GL_COMPRESSED_SRGB_ALPHA 0x8C49
#define GL_COMPRESSED_SLUMINANCE 0x8C4A
#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B
//
#define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0
#define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1
#define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2
#define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3
#define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4
#define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5
#define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB
#define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES
#define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS
#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001
#define GL_MAJOR_VERSION 0x821B
#define GL_MINOR_VERSION 0x821C
#define GL_NUM_EXTENSIONS 0x821D
#define GL_CONTEXT_FLAGS 0x821E
#define GL_DEPTH_BUFFER 0x8223
#define GL_STENCIL_BUFFER 0x8224
#define GL_RGBA32F 0x8814
#define GL_RGB32F 0x8815
#define GL_RGBA16F 0x881A
#define GL_RGB16F 0x881B
#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF
#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904
#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905
#define GL_CLAMP_VERTEX_COLOR 0x891A
#define GL_CLAMP_FRAGMENT_COLOR 0x891B
#define GL_CLAMP_READ_COLOR 0x891C
#define GL_FIXED_ONLY 0x891D
#define GL_TEXTURE_RED_TYPE 0x8C10
#define GL_TEXTURE_GREEN_TYPE 0x8C11
#define GL_TEXTURE_BLUE_TYPE 0x8C12
#define GL_TEXTURE_ALPHA_TYPE 0x8C13
#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14
#define GL_TEXTURE_INTENSITY_TYPE 0x8C15
#define GL_TEXTURE_DEPTH_TYPE 0x8C16
#define GL_TEXTURE_1D_ARRAY 0x8C18
#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19
#define GL_TEXTURE_2D_ARRAY 0x8C1A
#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B
#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C
#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D
#define GL_R11F_G11F_B10F 0x8C3A
#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B
#define GL_RGB9_E5 0x8C3D
#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E
#define GL_TEXTURE_SHARED_SIZE 0x8C3F
#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76
#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F
#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80
#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83
#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84
#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85
#define GL_PRIMITIVES_GENERATED 0x8C87
#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88
#define GL_RASTERIZER_DISCARD 0x8C89
#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A
#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B
#define GL_INTERLEAVED_ATTRIBS 0x8C8C
#define GL_SEPARATE_ATTRIBS 0x8C8D
#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E
#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F
#define GL_RGBA32UI 0x8D70
#define GL_RGB32UI 0x8D71
#define GL_RGBA16UI 0x8D76
#define GL_RGB16UI 0x8D77
#define GL_RGBA8UI 0x8D7C
#define GL_RGB8UI 0x8D7D
#define GL_RGBA32I 0x8D82
#define GL_RGB32I 0x8D83
#define GL_RGBA16I 0x8D88
#define GL_RGB16I 0x8D89
#define GL_RGBA8I 0x8D8E
#define GL_RGB8I 0x8D8F
#define GL_RED_INTEGER 0x8D94
#define GL_GREEN_INTEGER 0x8D95
#define GL_BLUE_INTEGER 0x8D96
#define GL_ALPHA_INTEGER 0x8D97
#define GL_RGB_INTEGER 0x8D98
#define GL_RGBA_INTEGER 0x8D99
#define GL_BGR_INTEGER 0x8D9A
#define GL_BGRA_INTEGER 0x8D9B
#define GL_SAMPLER_1D_ARRAY 0x8DC0
#define GL_SAMPLER_2D_ARRAY 0x8DC1
#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3
#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4
#define GL_SAMPLER_CUBE_SHADOW 0x8DC5
#define GL_UNSIGNED_INT_VEC2 0x8DC6
#define GL_UNSIGNED_INT_VEC3 0x8DC7
#define GL_UNSIGNED_INT_VEC4 0x8DC8
#define GL_INT_SAMPLER_1D 0x8DC9
#define GL_INT_SAMPLER_2D 0x8DCA
#define GL_INT_SAMPLER_3D 0x8DCB
#define GL_INT_SAMPLER_CUBE 0x8DCC
#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE
#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF
#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1
#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2
#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3
#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4
#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6
#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7
#define GL_QUERY_WAIT 0x8E13
#define GL_QUERY_NO_WAIT 0x8E14
#define GL_QUERY_BY_REGION_WAIT 0x8E15
#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
//
#define GL_TEXTURE_RECTANGLE 0x84F5
#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6
#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7
#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8
#define GL_SAMPLER_2D_RECT 0x8B63
#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64
#define GL_TEXTURE_BUFFER 0x8C2A
#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B
#define GL_TEXTURE_BINDING_BUFFER 0x8C2C
#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D
#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E
#define GL_SAMPLER_BUFFER 0x8DC2
#define GL_INT_SAMPLER_2D_RECT 0x8DCD
#define GL_INT_SAMPLER_BUFFER 0x8DD0
#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5
#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8
#define GL_RED_SNORM 0x8F90
#define GL_RG_SNORM 0x8F91
#define GL_RGB_SNORM 0x8F92
#define GL_RGBA_SNORM 0x8F93
#define GL_R8_SNORM 0x8F94
#define GL_RG8_SNORM 0x8F95
#define GL_RGB8_SNORM 0x8F96
#define GL_RGBA8_SNORM 0x8F97
#define GL_R16_SNORM 0x8F98
#define GL_RG16_SNORM 0x8F99
#define GL_RGB16_SNORM 0x8F9A
#define GL_RGBA16_SNORM 0x8F9B
#define GL_SIGNED_NORMALIZED 0x8F9C
#define GL_PRIMITIVE_RESTART 0x8F9D
#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E
#define GL_BUFFER_ACCESS_FLAGS 0x911F
#define GL_BUFFER_MAP_LENGTH 0x9120
#define GL_BUFFER_MAP_OFFSET 0x9121
//
#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
#define GL_LINES_ADJACENCY 0x000A
#define GL_LINE_STRIP_ADJACENCY 0x000B
#define GL_TRIANGLES_ADJACENCY 0x000C
#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
#define GL_PROGRAM_POINT_SIZE 0x8642
#define GL_GEOMETRY_VERTICES_OUT 0x8916
#define GL_GEOMETRY_INPUT_TYPE 0x8917
#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
#define GL_GEOMETRY_SHADER 0x8DD9
#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
#define GL_CONTEXT_PROFILE_MASK 0x9126
//
#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE
#define GL_RGB10_A2UI 0x906F
//
#define GL_SAMPLE_SHADING 0x8C36
#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F
#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
//
#define GL_TRANSFORM_FEEDBACK_PAUSED 0x8E23
#define GL_TRANSFORM_FEEDBACK_ACTIVE 0x8E24
#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
#define GL_COPY_READ_BUFFER_BINDING 0x8F36
#define GL_COPY_WRITE_BUFFER_BINDING 0x8F37
//
#define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9
#define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E
//
#define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221
#define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5
#define GL_TEXTURE_BUFFER_BINDING 0x8C2A
//
#define GL_CONTEXT_FLAG_NO_ERROR_BIT 0x00000008
#define GL_PARAMETER_BUFFER 0x80EE
#define GL_PARAMETER_BUFFER_BINDING 0x80EF
#define GL_TRANSFORM_FEEDBACK_OVERFLOW 0x82EC
#define GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW 0x82ED
#define GL_VERTICES_SUBMITTED 0x82EE
#define GL_PRIMITIVES_SUBMITTED 0x82EF
#define GL_VERTEX_SHADER_INVOCATIONS 0x82F0
#define GL_TESS_CONTROL_SHADER_PATCHES 0x82F1
#define GL_TESS_EVALUATION_SHADER_INVOCATIONS 0x82F2
#define GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED 0x82F3
#define GL_FRAGMENT_SHADER_INVOCATIONS 0x82F4
#define GL_COMPUTE_SHADER_INVOCATIONS 0x82F5
#define GL_CLIPPING_INPUT_PRIMITIVES 0x82F6
#define GL_CLIPPING_OUTPUT_PRIMITIVES 0x82F7
#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
#define GL_POLYGON_OFFSET_CLAMP 0x8E1B
#define GL_SHADER_BINARY_FORMAT_SPIR_V 0x9551
#define GL_SPIR_V_BINARY 0x9552
#define GL_SPIR_V_EXTENSIONS 0x9553
#define GL_NUM_SPIR_V_EXTENSIONS 0x9554
//
#define GL_MULTISAMPLE_3DFX 0x86B2
#define GL_SAMPLE_BUFFERS_3DFX 0x86B3
#define GL_SAMPLES_3DFX 0x86B4
#define GL_MULTISAMPLE_BIT_3DFX 0x20000000
//
#define GL_TEXTURE_1D 0x0DE0
#define GL_TEXTURE_2D 0x0DE1
#define GL_PROXY_TEXTURE_1D 0x8063
#define GL_PROXY_TEXTURE_2D 0x8064
#define GL_COLOR_TABLE_FORMAT_EXT 0x80D8
#define GL_COLOR_TABLE_WIDTH_EXT 0x80D9
#define GL_COLOR_TABLE_RED_SIZE_EXT 0x80DA
#define GL_COLOR_TABLE_GREEN_SIZE_EXT 0x80DB
#define GL_COLOR_TABLE_BLUE_SIZE_EXT 0x80DC
#define GL_COLOR_TABLE_ALPHA_SIZE_EXT 0x80DD
#define GL_COLOR_TABLE_LUMINANCE_SIZE_EXT 0x80DE
#define GL_COLOR_TABLE_INTENSITY_SIZE_EXT 0x80DF
#define GL_COLOR_INDEX1_EXT 0x80E2
#define GL_COLOR_INDEX2_EXT 0x80E3
#define GL_COLOR_INDEX4_EXT 0x80E4
#define GL_COLOR_INDEX8_EXT 0x80E5
#define GL_COLOR_INDEX12_EXT 0x80E6
#define GL_COLOR_INDEX16_EXT 0x80E7
#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED
#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT 0x00000001
#define GL_ELEMENT_ARRAY_BARRIER_BIT 0x00000002
#define GL_UNIFORM_BARRIER_BIT 0x00000004
#define GL_TEXTURE_FETCH_BARRIER_BIT 0x00000008
#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT 0x00000020
#define GL_COMMAND_BARRIER_BIT 0x00000040
#define GL_PIXEL_BUFFER_BARRIER_BIT 0x00000080
#define GL_TEXTURE_UPDATE_BARRIER_BIT 0x00000100
#define GL_BUFFER_UPDATE_BARRIER_BIT 0x00000200
#define GL_FRAMEBUFFER_BARRIER_BIT 0x00000400
#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT 0x00000800
#define GL_ATOMIC_COUNTER_BARRIER_BIT 0x00001000
#define GL_MAX_IMAGE_UNITS 0x8F38
#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS 0x8F39
#define GL_IMAGE_BINDING_NAME 0x8F3A
#define GL_IMAGE_BINDING_LEVEL 0x8F3B
#define GL_IMAGE_BINDING_LAYERED 0x8F3C
#define GL_IMAGE_BINDING_LAYER 0x8F3D
#define GL_IMAGE_BINDING_ACCESS 0x8F3E
#define GL_IMAGE_1D 0x904C
#define GL_IMAGE_2D 0x904D
#define GL_IMAGE_3D 0x904E
#define GL_IMAGE_2D_RECT 0x904F
#define GL_IMAGE_CUBE 0x9050
#define GL_IMAGE_BUFFER 0x9051
#define GL_IMAGE_1D_ARRAY 0x9052
#define GL_IMAGE_2D_ARRAY 0x9053
#define GL_IMAGE_CUBE_MAP_ARRAY 0x9054
#define GL_IMAGE_2D_MULTISAMPLE 0x9055
#define GL_IMAGE_2D_MULTISAMPLE_ARRAY 0x9056
#define GL_INT_IMAGE_1D 0x9057
#define GL_INT_IMAGE_2D 0x9058
#define GL_INT_IMAGE_3D 0x9059
#define GL_INT_IMAGE_2D_RECT 0x905A
#define GL_INT_IMAGE_CUBE 0x905B
#define GL_INT_IMAGE_BUFFER 0x905C
#define GL_INT_IMAGE_1D_ARRAY 0x905D
#define GL_INT_IMAGE_2D_ARRAY 0x905E
#define GL_INT_IMAGE_CUBE_MAP_ARRAY 0x905F
#define GL_INT_IMAGE_2D_MULTISAMPLE 0x9060
#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x9061
#define GL_UNSIGNED_INT_IMAGE_1D 0x9062
#define GL_UNSIGNED_INT_IMAGE_2D 0x9063
#define GL_UNSIGNED_INT_IMAGE_3D 0x9064
#define GL_UNSIGNED_INT_IMAGE_2D_RECT 0x9065
#define GL_UNSIGNED_INT_IMAGE_CUBE 0x9066
#define GL_UNSIGNED_INT_IMAGE_BUFFER 0x9067
#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY 0x9068
#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY 0x9069
#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY 0x906A
#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE 0x906B
#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY 0x906C
#define GL_MAX_IMAGE_SAMPLES 0x906D
#define GL_IMAGE_BINDING_FORMAT 0x906E
#define GL_IMAGE_FORMAT_COMPATIBILITY_TYPE 0x90C7
#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE 0x90C8
#define GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS 0x90C9
#define GL_MAX_VERTEX_IMAGE_UNIFORMS 0x90CA
#define GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS 0x90CB
#define GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS 0x90CC
#define GL_MAX_GEOMETRY_IMAGE_UNIFORMS 0x90CD
#define GL_MAX_FRAGMENT_IMAGE_UNIFORMS 0x90CE
#define GL_MAX_COMBINED_IMAGE_UNIFORMS 0x90CF
#define GL_ALL_BARRIER_BITS 0xFFFFFFFF
#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001
#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002
#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004
#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008
#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020
#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040
#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080
#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100
#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200
#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400
#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800
#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000
#define GL_MAX_IMAGE_UNITS_EXT 0x8F38
#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39
#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A
#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B
#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C
#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D
#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E
#define GL_IMAGE_1D_EXT 0x904C
#define GL_IMAGE_2D_EXT 0x904D
#define GL_IMAGE_3D_EXT 0x904E
#define GL_IMAGE_2D_RECT_EXT 0x904F
#define GL_IMAGE_CUBE_EXT 0x9050
#define GL_IMAGE_BUFFER_EXT 0x9051
#define GL_IMAGE_1D_ARRAY_EXT 0x9052
#define GL_IMAGE_2D_ARRAY_EXT 0x9053
#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054
#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055
#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056
#define GL_INT_IMAGE_1D_EXT 0x9057
#define GL_INT_IMAGE_2D_EXT 0x9058
#define GL_INT_IMAGE_3D_EXT 0x9059
#define GL_INT_IMAGE_2D_RECT_EXT 0x905A
#define GL_INT_IMAGE_CUBE_EXT 0x905B
#define GL_INT_IMAGE_BUFFER_EXT 0x905C
#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D
#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E
#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F
#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060
#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061
#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062
#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063
#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064
#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065
#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066
#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067
#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068
#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069
#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A
#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B
#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C
#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D
#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E
#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF
#define GL_SAMPLE_POSITION 0x8E50
#define GL_SAMPLE_MASK 0x8E51
#define GL_SAMPLE_MASK_VALUE 0x8E52
#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
#define GL_TEXTURE_SAMPLES 0x9106
#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
#define GL_MAX_INTEGER_SAMPLES 0x9110
#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
#define GL_VBO_FREE_MEMORY_ATI 0x87FB
#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
typedef char GLchar;
typedef ptrdiff_t GLsizeiptr;
typedef ptrdiff_t GLintptr;
#if _WIN32
#include "OpenglWin32.h"
#else
#include "OpenglLinux.h"
#endif
#endif

View File

@ -0,0 +1,23 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_GPUAPI_OPENGL_LINUX_H
#define TOS_GPUAPI_OPENGL_LINUX_H
typedef void type_glTexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
typedef void type_glBindFramebuffer(GLenum target, GLuint framebuffer);
typedef void type_glGenFramebuffers(GLsizei n, GLuint *framebuffer);
typedef void type_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
typedef GLenum type_glCheckFramebufferStatus(GLenum target);
typedef void type_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
typedef void type_glAttachShader(GLuint program, GLuint shader);
typedef void type_glCompileShader(GLuint shader);
// @todo continue
#endif

511
gpuapi/opengl/OpenglUtils.h Normal file
View File

@ -0,0 +1,511 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_GPUAPI_OPENGL_UTILS_H
#define TOS_GPUAPI_OPENGL_UTILS_H
#include "../../stdlib/Types.h"
#include "../../memory/RingMemory.h"
#include "../../utils/TestUtils.h"
#include "../../models/Attrib.h"
#include "../../object/Texture.h"
#include "../RenderUtils.h"
#include "Opengl.h"
#ifdef _WIN32
#include <windows.h>
#include "../../platform/win32/UtilsWin32.h"
#include "../../platform/win32/Window.h"
#endif
/*
struct Window {
bool is_fullscreen;
int32 width;
int32 height;
char name[32];
int32 x;
int32 y;
GLFWwindow* hwnd_lib;
#ifdef _WIN32
HWND hwnd;
#endif
};
*/
/*
inline
void window_create(Window* window, void*)
{
//GLFWmonitor *monitor = glfwGetPrimaryMonitor();
window->hwnd_lib = glfwCreateWindow(
window->width,
window->height,
window->name,
NULL,
NULL
);
ASSERT_SIMPLE(window->hwnd_lib);
//glfwSetInputMode(window->hwnd_lib, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwMakeContextCurrent(window->hwnd_lib);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
#if GLFW_EXPOSE_NATIVE_WIN32
window->hwnd = glfwGetWin32Window(window->hwnd_lib);
#endif
}
inline
void window_open(Window* window)
{
glfwMakeContextCurrent(window->hwnd_lib);
glViewport(window->x, window->y, window->width, window->height);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
}
inline
void window_close(Window* window)
{
glfwWindowShouldClose(window->hwnd_lib);
}
*/
inline
uint32 get_texture_data_type(uint32 texture_data_type)
{
switch (texture_data_type) {
case TEXTURE_DATA_TYPE_2D: {
return GL_TEXTURE_2D;
}
case TEXTURE_DATA_TYPE_1D: {
return GL_TEXTURE_1D;
}
case TEXTURE_DATA_TYPE_3D: {
return GL_TEXTURE_3D;
}
case TEXTURE_DATA_TYPE_1D_ARRAY: {
return GL_TEXTURE_1D_ARRAY;
}
case TEXTURE_DATA_TYPE_2D_ARRAY: {
return GL_TEXTURE_2D_ARRAY;
}
case TEXTURE_DATA_TYPE_2D_MULTISAMPLED: {
return GL_TEXTURE_2D_MULTISAMPLE;
}
case TEXTURE_DATA_TYPE_2D_MULTISAMPLED_ARRAY: {
return GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
}
default: {
return GL_TEXTURE_2D;
}
}
}
// 1. prepare_texture
// 2. define wrap
// 3. define filter
// 4. load_texture_to_gpu
inline
void prepare_texture(OpenGL* gl, Texture* texture, uint32 texture_unit)
{
uint32 texture_data_type = get_texture_data_type(texture->texture_data_type);
glGenTextures(1, (GLuint *) &texture->id);
gl->glActiveTexture(GL_TEXTURE0 + texture_unit);
glBindTexture(texture_data_type, (GLuint) texture->id);
}
inline
void load_texture_to_gpu(OpenGL* gl, const Texture* texture, int mipmap_level = 0)
{
uint32 texture_data_type = get_texture_data_type(texture->texture_data_type);
glTexImage2D(
texture_data_type, mipmap_level, GL_RGBA,
texture->image.width, texture->image.height,
0, GL_RGBA, GL_UNSIGNED_BYTE,
texture->image.pixels
);
if (mipmap_level > -1) {
gl->glGenerateMipmap(GL_TEXTURE_2D);
}
}
inline
void texture_use(OpenGL* gl, const Texture* texture, uint32 texture_unit)
{
gl->glActiveTexture(GL_TEXTURE0 + texture_unit);
glBindTexture(GL_TEXTURE_2D, (GLuint) texture->id);
}
GLuint shader_make(OpenGL* gl, GLenum type, const char *source, RingMemory* ring)
{
GLuint shader = gl->glCreateShader(type);
gl->glShaderSource(shader, 1, (GLchar **) &source, NULL);
gl->glCompileShader(shader);
GLint status;
gl->glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
ASSERT_SIMPLE(false);
GLint length;
gl->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
GLchar *info = (GLchar *) ring_get_memory(ring, length * sizeof(GLchar));
gl->glGetShaderInfoLog(shader, length, NULL, info);
// @todo log
}
return shader;
}
GLuint shader_load(OpenGL* gl, GLenum type, const char *path, RingMemory* ring) {
uint64 temp = ring->pos;
FileBody file;
// @todo consider to accept file as parameter and load file before
file_read(path, &file, ring);
GLuint result = shader_make(gl, type, (const char *) file.content, ring);
// We can immediately dispose of it we can also reset our ring memory position
ring->pos = temp;
return result;
}
GLuint program_make(OpenGL* gl, GLuint shader1, GLuint shader2, RingMemory* ring) {
GLuint program = gl->glCreateProgram();
gl->glAttachShader(program, shader1);
gl->glAttachShader(program, shader2);
gl->glLinkProgram(program);
GLint status;
gl->glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
ASSERT_SIMPLE(false);
GLint length;
gl->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
GLchar *info = (GLchar *) ring_get_memory(ring, length * sizeof(GLchar));
gl->glGetProgramInfoLog(program, length, NULL, info);
// @todo use global logger
fprintf(stderr, "glLinkProgram failed: %s\n", info);
}
// @question really?
gl->glDetachShader(program, shader1);
gl->glDetachShader(program, shader2);
// @question really?
gl->glDeleteShader(shader1);
gl->glDeleteShader(shader2);
return program;
}
GLuint program_load(OpenGL* gl, const char *path1, const char *path2, RingMemory* ring) {
GLuint shader1 = shader_load(gl, GL_VERTEX_SHADER, path1, ring);
GLuint shader2 = shader_load(gl, GL_FRAGMENT_SHADER, path2, ring);
GLuint program = program_make(gl, shader1, shader2, ring);
return program;
}
inline
void shader_use(OpenGL* gl, uint32 id)
{
gl->glUseProgram(id);
}
inline
void draw_triangles_3d(OpenGL* gl, VertexRef* vertices, GLuint buffer, int count) {
gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
// position attribute
gl->glVertexAttribPointer(vertices->position, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) 0);
gl->glEnableVertexAttribArray(vertices->position);
// normal attribute
gl->glVertexAttribPointer(vertices->normal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 3));
gl->glEnableVertexAttribArray(vertices->normal);
// texture coord attribute
gl->glVertexAttribIPointer(vertices->tex_coord, 2, GL_UNSIGNED_INT, sizeof(Vertex3D), (void *) (sizeof(float) * 6));
gl->glEnableVertexAttribArray(vertices->tex_coord);
// color attribute
gl->glVertexAttribPointer(vertices->color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 8));
gl->glEnableVertexAttribArray(vertices->color);
glDrawArrays(GL_TRIANGLES, 0, count);
gl->glDisableVertexAttribArray(vertices->position);
gl->glDisableVertexAttribArray(vertices->normal);
gl->glDisableVertexAttribArray(vertices->tex_coord);
gl->glDisableVertexAttribArray(vertices->color);
gl->glBindBuffer(GL_ARRAY_BUFFER, 0);
}
inline
void draw_triangles_3d_textureless(OpenGL* gl, VertexRef* vertices, GLuint buffer, int count) {
gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
// position attribute
gl->glVertexAttribPointer(vertices->position, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) 0);
gl->glEnableVertexAttribArray(vertices->position);
// normal attribute
gl->glVertexAttribPointer(vertices->normal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 3));
gl->glEnableVertexAttribArray(vertices->normal);
// color attribute
gl->glVertexAttribPointer(vertices->color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 8));
gl->glEnableVertexAttribArray(vertices->color);
glDrawArrays(GL_TRIANGLES, 0, count);
gl->glDisableVertexAttribArray(vertices->position);
gl->glDisableVertexAttribArray(vertices->normal);
gl->glDisableVertexAttribArray(vertices->color);
gl->glBindBuffer(GL_ARRAY_BUFFER, 0);
}
inline
void draw_triangles_3d_colorless(OpenGL* gl, VertexRef* vertices, GLuint buffer, int count) {
gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
// position attribute
gl->glVertexAttribPointer(vertices->position, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) 0);
gl->glEnableVertexAttribArray(vertices->position);
// normal attribute
gl->glVertexAttribPointer(vertices->normal, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex3D), (void *) (sizeof(float) * 3));
gl->glEnableVertexAttribArray(vertices->normal);
// texture coord attribute
gl->glVertexAttribIPointer(vertices->tex_coord, 2, GL_UNSIGNED_INT, sizeof(Vertex3D), (void *) (sizeof(float) * 6));
gl->glEnableVertexAttribArray(vertices->tex_coord);
glDrawArrays(GL_TRIANGLES, 0, count);
gl->glDisableVertexAttribArray(vertices->position);
gl->glDisableVertexAttribArray(vertices->normal);
gl->glDisableVertexAttribArray(vertices->tex_coord);
gl->glBindBuffer(GL_ARRAY_BUFFER, 0);
}
inline
void draw_triangles_2d(OpenGL* gl, VertexRef* vertices, GLuint buffer, int count) {
gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
// position attribute
gl->glVertexAttribPointer(vertices->position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) 0);
gl->glEnableVertexAttribArray(vertices->position);
// texture coord attribute
gl->glVertexAttribIPointer(vertices->tex_coord, 2, GL_UNSIGNED_INT, sizeof(Vertex2D), (void *) (sizeof(float) * 2));
gl->glEnableVertexAttribArray(vertices->tex_coord);
// color attribute
gl->glVertexAttribPointer(vertices->color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) (sizeof(float) * 4));
gl->glEnableVertexAttribArray(vertices->color);
glDrawArrays(GL_TRIANGLES, 0, count);
gl->glDisableVertexAttribArray(vertices->position);
gl->glDisableVertexAttribArray(vertices->tex_coord);
gl->glDisableVertexAttribArray(vertices->color);
gl->glBindBuffer(GL_ARRAY_BUFFER, 0);
}
inline
void draw_triangles_2d_textureless(OpenGL* gl, VertexRef* vertices, GLuint buffer, int count) {
gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
// position attribute
gl->glVertexAttribPointer(vertices->position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) 0);
gl->glEnableVertexAttribArray(vertices->position);
// color attribute
gl->glVertexAttribPointer(vertices->color, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) (sizeof(float) * 4));
gl->glEnableVertexAttribArray(vertices->color);
glDrawArrays(GL_TRIANGLES, 0, count);
gl->glDisableVertexAttribArray(vertices->position);
gl->glDisableVertexAttribArray(vertices->color);
gl->glBindBuffer(GL_ARRAY_BUFFER, 0);
}
inline
void draw_triangles_2d_colorless(OpenGL* gl, VertexRef* vertices, GLuint buffer, int count) {
gl->glBindBuffer(GL_ARRAY_BUFFER, buffer);
// position attribute
gl->glVertexAttribPointer(vertices->position, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), (void *) 0);
gl->glEnableVertexAttribArray(vertices->position);
// texture coord attribute
gl->glVertexAttribIPointer(vertices->tex_coord, 2, GL_UNSIGNED_INT, sizeof(Vertex2D), (void *) (sizeof(float) * 2));
gl->glEnableVertexAttribArray(vertices->tex_coord);
glDrawArrays(GL_TRIANGLES, 0, count);
gl->glDisableVertexAttribArray(vertices->position);
gl->glDisableVertexAttribArray(vertices->tex_coord);
gl->glBindBuffer(GL_ARRAY_BUFFER, 0);
}
inline
void draw_text(OpenGL* gl, VertexRef* vertices, GLuint buffer, int length)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
draw_triangles_2d(gl, vertices, buffer, length * 6);
glDisable(GL_BLEND);
}
GLuint gen_text_buffer(float x, float y, float n, const char *text) {
size_t length = strlen(text);
GLfloat *data = NULL; //malloc_faces(4, length); // sizeof(GLfloat) * 6 * 4 * length
for (int i = 0; i < length; i++) {
make_character(data + i * 24, x, y, n / 2, n, text[i]);
x += n;
}
return 0; //gen_faces(4, length, data);
}
inline
void render_text(OpenGL* gl, Attrib* attrib, int justify, float x, float y, float n, const char *text)
{
float matrix[16];
//set_matrix_2d(matrix, g->width, g->height);
gl->glUseProgram(attrib->program);
gl->glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix);
gl->glUniform1i(attrib->sampler, 1);
gl->glUniform1i(attrib->extra1, 0);
size_t length = strlen(text);
x -= n * justify * (length - 1) / 2;
GLuint buffer = gen_text_buffer(x, y, n, text);
draw_text(gl, &attrib->vertices, buffer, (int) length);
gl->glDeleteBuffers(1, &buffer);
}
inline
int calculate_face_size(int components, int faces)
{
return sizeof(GLfloat) * 6 * components * faces;
}
// generates faces
// data is no longer needed after this
inline
uint32 gpuapi_buffer_generate(OpenGL* gl, int size, void* data)
{
uint32 vbo;
gl->glGenBuffers(1, &vbo);
gl->glBindBuffer(GL_ARRAY_BUFFER, vbo);
gl->glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
return vbo;
}
inline
uint32 gpuapi_buffer_element_generate(OpenGL* gl, int size, uint32 *data)
{
uint32 ebo;
gl->glGenBuffers(1, &ebo);
gl->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
gl->glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
return ebo;
}
inline
uint32 gpuapi_vertex_array_generate(OpenGL* gl)
{
uint32 vao;
gl->glGenVertexArrays(1, &vao);
gl->glBindVertexArray(vao);
return vao;
}
inline
void gpuapi_unbind_all(OpenGL* gl)
{
gl->glBindBuffer(GL_ARRAY_BUFFER, 0);
gl->glBindVertexArray(0);
}
inline
void gpuapi_buffer_delete(OpenGL* gl, GLuint buffer)
{
gl->glDeleteBuffers(1, &buffer);
}
int get_gpu_free_memory()
{
GLint available = 0;
glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &available);
if (available != 0) {
return available;
}
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, &available);
return available;
}
/*
void render_9_patch(GLuint texture,
int imgWidth, int imgHeight,
int img_x1, int img_x2,
int img_y1, int img_y2,
int renderWidth, int renderHeight,
int repeat
)
{
}
*/
#endif

342
gpuapi/opengl/OpenglWin32.h Normal file
View File

@ -0,0 +1,342 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_GPUAPI_OPENGL_WIN32_H
#define TOS_GPUAPI_OPENGL_WIN32_H
#include <windows.h>
#include "../../platform/win32/Window.h"
#include "../../stdlib/Types.h"
typedef void WINAPI type_glTexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
typedef void WINAPI type_glBindFramebuffer(GLenum target, GLuint framebuffer);
typedef void WINAPI type_glGenFramebuffers(GLsizei n, GLuint *framebuffers);
typedef void WINAPI type_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
typedef GLenum WINAPI type_glCheckFramebufferStatus(GLenum target);
typedef void WINAPI type_glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
typedef void WINAPI type_glAttachShader(GLuint program, GLuint shader);
typedef void WINAPI type_glCompileShader(GLuint shader);
typedef GLuint WINAPI type_glCreateProgram(void);
typedef GLuint WINAPI type_glCreateShader(GLenum type);
typedef void WINAPI type_glLinkProgram(GLuint program);
typedef void WINAPI type_glShaderSource(GLuint shader, GLsizei count, GLchar **string, GLint *length);
typedef void WINAPI type_glUseProgram(GLuint program);
typedef void WINAPI type_glGetProgramInfoLog(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef void WINAPI type_glGetShaderInfoLog(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef void WINAPI type_glValidateProgram(GLuint program);
typedef void WINAPI type_glGetProgramiv(GLuint program, GLenum pname, GLint *params);
typedef GLint WINAPI type_glGetUniformLocation(GLuint program, const GLchar *name);
typedef void WINAPI type_glUniform4fv(GLint location, GLsizei count, const GLfloat *value);
typedef void WINAPI type_glUniform1i(GLint location, GLint v0);
typedef void WINAPI type_glUniform1f(GLint location, GLfloat v0);
typedef void WINAPI type_glUniform2fv(GLint location, GLsizei count, const GLfloat *value);
typedef void WINAPI type_glUniform3fv(GLint location, GLsizei count, const GLfloat *value);
typedef void WINAPI type_glEnableVertexAttribArray(GLuint index);
typedef void WINAPI type_glDisableVertexAttribArray(GLuint index);
typedef GLint WINAPI type_glGetAttribLocation(GLuint program, const GLchar *name);
typedef void WINAPI type_glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
typedef void WINAPI type_glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer);
typedef void WINAPI type_glBindVertexArray(GLuint array);
typedef void WINAPI type_glGenVertexArrays(GLsizei n, GLuint *arrays);
typedef void WINAPI type_glBindBuffer(GLenum target, GLuint buffer);
typedef void WINAPI type_glGenBuffers(GLsizei n, GLuint *buffers);
typedef void WINAPI type_glBufferData(GLenum target, GLsizeiptr size, const void *data, GLenum usage);
typedef void WINAPI type_glActiveTexture(GLenum texture);
typedef void WINAPI type_glDeleteProgram(GLuint program);
typedef void WINAPI type_glDeleteShader(GLuint shader);
typedef void WINAPI type_glDeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
typedef void WINAPI type_glDrawBuffers(GLsizei n, const GLenum *bufs);
typedef void WINAPI type_glTexImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels);
typedef void WINAPI type_glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels);
typedef void WINAPI type_glDrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
typedef void WINAPI type_glGenerateMipmap(GLenum target);
typedef void WINAPI type_glDetachShader(GLuint program, GLuint shader);
typedef void WINAPI type_glDeleteBuffers(GLsizei n, const GLuint* buffers);
typedef void WINAPI type_glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
typedef void WINAPI type_glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
typedef void WINAPI type_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value);
typedef void WINAPI type_glGetShaderiv(GLuint shader, GLenum pname, GLint* param);
//typedef void WINAPI type_glTexImage2D(GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations);
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_TYPE_RGBA_ARB 0x202B
#define WGL_FULL_ACCELERATION_ARB 0x2027
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
#define WGL_RED_BITS_ARB 0x2015
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_BLUE_BITS_ARB 0x2019
#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);
typedef BOOL WINAPI wgl_get_pixel_format_attrib_iv_arb(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
typedef BOOL WINAPI wgl_get_pixel_format_attrib_fv_arb(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
typedef BOOL WINAPI wgl_choose_pixel_format_arb(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
typedef const char * WINAPI wgl_get_extensions_string_ext(void);
struct OpenGL {
type_glTexImage2DMultisample* glTexImage2DMultisample;
type_glBindFramebuffer* glBindFramebuffer;
type_glGenFramebuffers* glGenFramebuffers;
type_glFramebufferTexture2D* glFramebufferTexture2D;
type_glCheckFramebufferStatus* glCheckFramebufferStatus;
type_glBlitFramebuffer* glBlitFramebuffer;
type_glAttachShader* glAttachShader;
type_glCompileShader* glCompileShader;
type_glCreateProgram* glCreateProgram;
type_glCreateShader* glCreateShader;
type_glLinkProgram* glLinkProgram;
type_glShaderSource* glShaderSource;
type_glUseProgram* glUseProgram;
type_glGetProgramInfoLog* glGetProgramInfoLog;
type_glGetShaderInfoLog* glGetShaderInfoLog;
type_glValidateProgram* glValidateProgram;
type_glGetProgramiv* glGetProgramiv;
type_glGetUniformLocation* glGetUniformLocation;
type_glUniform4fv* glUniform4fv;
type_glUniform1i* glUniform1i;
type_glUniform1f* glUniform1f;
type_glUniform2fv* glUniform2fv;
type_glUniform3fv* glUniform3fv;
type_glEnableVertexAttribArray* glEnableVertexAttribArray;
type_glDisableVertexAttribArray* glDisableVertexAttribArray;
type_glGetAttribLocation* glGetAttribLocation;
type_glVertexAttribPointer* glVertexAttribPointer;
type_glVertexAttribIPointer* glVertexAttribIPointer;
type_glBindVertexArray* glBindVertexArray;
type_glGenVertexArrays* glGenVertexArrays;
type_glBindBuffer* glBindBuffer;
type_glGenBuffers* glGenBuffers;
type_glBufferData* glBufferData;
type_glActiveTexture* glActiveTexture;
type_glDeleteProgram* glDeleteProgram;
type_glDeleteShader* glDeleteShader;
type_glDeleteFramebuffers* glDeleteFramebuffers;
type_glDrawBuffers* glDrawBuffers;
type_glTexImage3D* glTexImage3D;
type_glTexSubImage3D* glTexSubImage3D;
type_glDrawElementsBaseVertex* glDrawElementsBaseVertex;
type_glGenerateMipmap* glGenerateMipmap;
type_glDetachShader* glDetachShader;
type_glDeleteBuffers* glDeleteBuffers;
type_glUniformMatrix2fv* glUniformMatrix2fv;
type_glUniformMatrix3fv* glUniformMatrix3fv;
type_glUniformMatrix4fv* glUniformMatrix4fv;
type_glGetShaderiv* glGetShaderiv;
wgl_choose_pixel_format_arb* wglChoosePixelFormatARB;
wgl_create_context_attribs_arb* wglCreateContextAttribsARB;
wgl_get_extensions_string_ext* wglGetExtensionsStringEXT;
};
void set_pixel_format(HDC hdc, OpenGL* gl)
{
int suggested_pixel_format_idx = 0;
unsigned int extended_pick = 0;
if (gl->wglChoosePixelFormatARB) {
int attr_list[] = {
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, GL_TRUE,
0,
};
gl->wglChoosePixelFormatARB(hdc, attr_list, 0, 1, &suggested_pixel_format_idx, &extended_pick);
}
if(!extended_pick) {
PIXELFORMATDESCRIPTOR desired_pixel_format = {};
desired_pixel_format.nSize = sizeof(desired_pixel_format);
desired_pixel_format.nVersion = 1;
desired_pixel_format.iPixelType = PFD_TYPE_RGBA;
desired_pixel_format.dwFlags = PFD_SUPPORT_OPENGL|PFD_DRAW_TO_WINDOW|PFD_DOUBLEBUFFER;
desired_pixel_format.cColorBits = 32;
desired_pixel_format.cAlphaBits = 8;
desired_pixel_format.cDepthBits = 24;
desired_pixel_format.iLayerType = PFD_MAIN_PLANE;
suggested_pixel_format_idx = ChoosePixelFormat(hdc, &desired_pixel_format);
}
PIXELFORMATDESCRIPTOR suggested_pixel_format;
DescribePixelFormat(hdc, suggested_pixel_format_idx, sizeof(suggested_pixel_format), &suggested_pixel_format);
SetPixelFormat(hdc, suggested_pixel_format_idx, &suggested_pixel_format);
}
bool gl_extensions_load(OpenGL* gl)
{
WNDCLASSA wc = {};
wc.lpfnWndProc = DefWindowProcA;
wc.hInstance = GetModuleHandle(0);
wc.lpszClassName = "WGLLoader";
if (!RegisterClassA(&wc)) {
return false;
}
HWND window = CreateWindowExA(
0,
wc.lpszClassName,
"ExtensionLoader",
0,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
0,
0,
wc.hInstance,
0
);
HDC hdc = GetDC(window);
set_pixel_format(hdc, gl);
HGLRC openGLRC = wglCreateContext(hdc);
if (!wglMakeCurrent(hdc, openGLRC) || !gl->wglGetExtensionsStringEXT) {
return false;
}
char *extension = (char *) gl->wglGetExtensionsStringEXT();
char *pos = extension;
while(*pos) {
while(*pos == ' ' || *pos == '\t' || *pos == '\r' || *pos == '\n') {
++pos;
}
char *end = pos;
while(*end && !(*end == ' ' || *end == '\t' || *end == '\r' || *end == '\n')) {
++end;
}
umm count = end - pos;
// OpenGL->SupportsSRGBFramebuffer = strcmp(count, pos, "WGL_EXT_framebuffer_sRGB") == 0 || strcmp(count, pos, "WGL_ARB_framebuffer_sRGB") == 0;
pos = end;
}
wglMakeCurrent(0, 0);
wglDeleteContext(openGLRC);
ReleaseDC(window, hdc);
DestroyWindow(window);
return true;
}
const int win32_opengl_attribs[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 4,
WGL_CONTEXT_MINOR_VERSION_ARB, 6,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0,
};
void opengl_init(Window* window, OpenGL* gl)
{
gl_extensions_load(gl);
gl->wglChoosePixelFormatARB = (wgl_choose_pixel_format_arb *) wglGetProcAddress("wglChoosePixelFormatARB");
gl->wglCreateContextAttribsARB = (wgl_create_context_attribs_arb *) wglGetProcAddress("wglCreateContextAttribsARB");
gl->wglGetExtensionsStringEXT = (wgl_get_extensions_string_ext *) wglGetProcAddress("wglGetExtensionsStringEXT");
set_pixel_format(window->hdc, gl);
HGLRC openGLRC = 0;
if (gl->wglCreateContextAttribsARB) {
openGLRC = gl->wglCreateContextAttribsARB(window->hdc, 0, win32_opengl_attribs);
}
if (!openGLRC) {
openGLRC = wglCreateContext(window->hdc);
}
if(!wglMakeCurrent(window->hdc, openGLRC)) {
return;
}
gl->glTexImage2DMultisample = (type_glTexImage2DMultisample *) wglGetProcAddress("glTexImage2DMultisample");
gl->glBindFramebuffer = (type_glBindFramebuffer *) wglGetProcAddress("glBindFramebuffer");
gl->glGenFramebuffers = (type_glGenFramebuffers *) wglGetProcAddress("glGenFramebuffers");
gl->glFramebufferTexture2D = (type_glFramebufferTexture2D *) wglGetProcAddress("glFramebufferTexture2D");
gl->glCheckFramebufferStatus = (type_glCheckFramebufferStatus *) wglGetProcAddress("glCheckFramebufferStatus");
gl->glBlitFramebuffer = (type_glBlitFramebuffer *) wglGetProcAddress("glBlitFramebuffer");
gl->glAttachShader = (type_glAttachShader *) wglGetProcAddress("glAttachShader");
gl->glCompileShader = (type_glCompileShader *) wglGetProcAddress("glCompileShader");
gl->glCreateProgram = (type_glCreateProgram *) wglGetProcAddress("glCreateProgram");
gl->glCreateShader = (type_glCreateShader *) wglGetProcAddress("glCreateShader");
gl->glLinkProgram = (type_glLinkProgram *) wglGetProcAddress("glLinkProgram");
gl->glShaderSource = (type_glShaderSource *) wglGetProcAddress("glShaderSource");
gl->glUseProgram = (type_glUseProgram *) wglGetProcAddress("glUseProgram");
gl->glGetProgramInfoLog = (type_glGetProgramInfoLog *) wglGetProcAddress("glGetProgramInfoLog");
gl->glGetShaderInfoLog = (type_glGetShaderInfoLog *) wglGetProcAddress("glGetShaderInfoLog");
gl->glValidateProgram = (type_glValidateProgram *) wglGetProcAddress("glValidateProgram");
gl->glGetProgramiv = (type_glGetProgramiv *) wglGetProcAddress("glGetProgramiv");
gl->glGetUniformLocation = (type_glGetUniformLocation *) wglGetProcAddress("glGetUniformLocation");
gl->glUniform4fv = (type_glUniform4fv *) wglGetProcAddress("glUniform4fv");
gl->glUniform1i = (type_glUniform1i *) wglGetProcAddress("glUniform1i");
gl->glUniform1f = (type_glUniform1f *) wglGetProcAddress("glUniform1f");
gl->glUniform2fv = (type_glUniform2fv *) wglGetProcAddress("glUniform2fv");
gl->glUniform3fv = (type_glUniform3fv *) wglGetProcAddress("glUniform3fv");
gl->glEnableVertexAttribArray = (type_glEnableVertexAttribArray *) wglGetProcAddress("glEnableVertexAttribArray");
gl->glDisableVertexAttribArray = (type_glDisableVertexAttribArray *) wglGetProcAddress("glDisableVertexAttribArray");
gl->glGetAttribLocation = (type_glGetAttribLocation *) wglGetProcAddress("glGetAttribLocation");
gl->glVertexAttribPointer = (type_glVertexAttribPointer *) wglGetProcAddress("glVertexAttribPointer");
gl->glVertexAttribIPointer = (type_glVertexAttribIPointer *) wglGetProcAddress("glVertexAttribIPointer");
gl->glBindVertexArray = (type_glBindVertexArray *) wglGetProcAddress("glBindVertexArray");
gl->glGenVertexArrays = (type_glGenVertexArrays *) wglGetProcAddress("glGenVertexArrays");
gl->glBindBuffer = (type_glBindBuffer *) wglGetProcAddress("glBindBuffer");
gl->glGenBuffers = (type_glGenBuffers *) wglGetProcAddress("glGenBuffers");
gl->glBufferData = (type_glBufferData *) wglGetProcAddress("glBufferData");
gl->glActiveTexture = (type_glActiveTexture *) wglGetProcAddress("glActiveTexture");
gl->glDeleteProgram = (type_glDeleteProgram *) wglGetProcAddress("glDeleteProgram");
gl->glDeleteShader = (type_glDeleteShader *) wglGetProcAddress("glDeleteShader");
gl->glDeleteFramebuffers = (type_glDeleteFramebuffers *) wglGetProcAddress("glDeleteFramebuffers");
gl->glDrawBuffers = (type_glDrawBuffers *) wglGetProcAddress("glDrawBuffers");
gl->glTexImage3D = (type_glTexImage3D *) wglGetProcAddress("glTexImage3D");
gl->glTexSubImage3D = (type_glTexSubImage3D *) wglGetProcAddress("glTexSubImage3D");
gl->glDrawElementsBaseVertex = (type_glDrawElementsBaseVertex *) wglGetProcAddress("glDrawElementsBaseVertex");
gl->glGenerateMipmap = (type_glGenerateMipmap *) wglGetProcAddress("glGenerateMipmap");
gl->glDetachShader = (type_glDetachShader *) wglGetProcAddress("glDetachShader");
gl->glDeleteBuffers = (type_glDeleteBuffers *) wglGetProcAddress("glDeleteBuffers");
gl->glUniformMatrix2fv = (type_glUniformMatrix2fv *) wglGetProcAddress("glUniformMatrix2fv");
gl->glUniformMatrix3fv = (type_glUniformMatrix3fv *) wglGetProcAddress("glUniformMatrix3fv");
gl->glUniformMatrix4fv = (type_glUniformMatrix4fv *) wglGetProcAddress("glUniformMatrix4fv");
gl->glGetShaderiv = (type_glGetShaderiv *) wglGetProcAddress("glGetShaderiv");
// @todo now do: OpenGLInit
}
#endif

View File

@ -9,82 +9,79 @@
#ifndef TOS_GPUAPI_OPENGL_SHADER_UTILS_H
#define TOS_GPUAPI_OPENGL_SHADER_UTILS_H
#include "../../../EngineDependencies/opengl/glew/include/GL/glew.h"
#include "../../../EngineDependencies/opengl/glfw/include/glfw3.h"
#include "../../stdlib/Types.h"
inline
void shader_set_value(uint32 id, const char* name, bool value)
void shader_set_value(OpenGL* gl, uint32 id, const char* name, bool value)
{
glUniform1i(glGetUniformLocation(id, name), (int) value);
gl->glUniform1i(gl->glGetUniformLocation(id, name), (int) value);
}
inline
void shader_set_value(uint32 id, const char* name, int value)
void shader_set_value(OpenGL* gl, uint32 id, const char* name, int value)
{
glUniform1i(glGetUniformLocation(id, name), value);
gl->glUniform1i(gl->glGetUniformLocation(id, name), value);
}
inline
void shader_set_value(uint32 id, const char* name, float value)
void shader_set_value(OpenGL* gl, uint32 id, const char* name, float value)
{
glUniform1f(glGetUniformLocation(id, name), value);
gl->glUniform1f(gl->glGetUniformLocation(id, name), value);
}
inline
void shader_set_v2(uint32 id, const char* name, float* value)
void shader_set_v2(OpenGL* gl, uint32 id, const char* name, float* value)
{
glUniform2fv(glGetUniformLocation(id, name), 1, value);
gl->glUniform2fv(gl->glGetUniformLocation(id, name), 1, value);
}
inline
void shader_set_v3(uint32 id, const char* name, float* value)
void shader_set_v3(OpenGL* gl, uint32 id, const char* name, float* value)
{
glUniform3fv(glGetUniformLocation(id, name), 1, value);
gl->glUniform3fv(gl->glGetUniformLocation(id, name), 1, value);
}
inline
void shader_set_v4(uint32 id, const char* name, float* value)
void shader_set_v4(OpenGL* gl, uint32 id, const char* name, float* value)
{
glUniform4fv(glGetUniformLocation(id, name), 1, value);
gl->glUniform4fv(gl->glGetUniformLocation(id, name), 1, value);
}
inline
void shader_set_m2(uint32 id, const char* name, float* value)
void shader_set_m2(OpenGL* gl, uint32 id, const char* name, float* value)
{
glUniformMatrix2fv(glGetUniformLocation(id, name), 1, GL_FALSE, value);
gl->glUniformMatrix2fv(gl->glGetUniformLocation(id, name), 1, GL_FALSE, value);
}
inline
void shader_set_m3(uint32 id, const char* name, float* value)
void shader_set_m3(OpenGL* gl, uint32 id, const char* name, float* value)
{
glUniformMatrix3fv(glGetUniformLocation(id, name), 1, GL_FALSE, value);
gl->glUniformMatrix3fv(gl->glGetUniformLocation(id, name), 1, GL_FALSE, value);
}
inline
void shader_set_m4(uint32 id, const char* name, float* value)
void shader_set_m4(OpenGL* gl, uint32 id, const char* name, float* value)
{
glUniformMatrix4fv(glGetUniformLocation(id, name), 1, GL_FALSE, value);
gl->glUniformMatrix4fv(gl->glGetUniformLocation(id, name), 1, GL_FALSE, value);
}
inline
void shader_check_link_errors(uint32 id, char* log)
void shader_check_link_errors(OpenGL* gl, uint32 id, char* log)
{
GLint success;
glGetProgramiv(id, GL_LINK_STATUS, &success);
gl->glGetProgramiv(id, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(id, 1024, NULL, log);
gl->glGetProgramInfoLog(id, 1024, NULL, log);
}
}
inline
void shader_check_compile_errors(uint32 id, char* log)
void shader_check_compile_errors(OpenGL* gl, uint32 id, char* log)
{
GLint success;
glGetShaderiv(id, GL_COMPILE_STATUS, &success);
gl->glGetShaderiv(id, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(id, 1024, NULL, log);
gl->glGetShaderInfoLog(id, 1024, NULL, log);
}
}

View File

@ -15,8 +15,7 @@
#include "../../ui/UIButton.h"
#include "../../ui/UIWindow.h"
#include "../../../EngineDependencies/opengl/glew/include/GL/glew.h"
#include "../../../EngineDependencies/opengl/glfw/include/glfw3.h"
#include <gl/GL.h>
void render_button(UIButton* btn)
{

View File

@ -1,392 +0,0 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_GPUAPI_OPENGL_UTILS_H
#define TOS_GPUAPI_OPENGL_UTILS_H
#include "../../stdlib/Types.h"
#include "../../memory/RingMemory.h"
#include "../../utils/TestUtils.h"
#include "../../models/Attrib.h"
#include "../../models/Texture.h"
#include "../RenderUtils.h"
#include "../../../EngineDependencies/opengl/glew/include/GL/glew.h"
#include "../../../EngineDependencies/opengl/glfw/include/glfw3.h"
#if GLFW_EXPOSE_NATIVE_WIN32
#include "../../../EngineDependencies/opengl/glfw/include/glfw3native.h"
#endif
#ifdef _WIN32
#include <windows.h>
#include "../../platform/win32/UtilsWin32.h"
#endif
struct Window {
bool is_fullscreen;
int32 width;
int32 height;
char name[32];
int32 x;
int32 y;
GLFWwindow* hwnd_lib;
#ifdef _WIN32
HWND hwnd;
#endif
};
inline
void window_create(Window* window, void*)
{
//GLFWmonitor *monitor = glfwGetPrimaryMonitor();
window->hwnd_lib = glfwCreateWindow(
window->width,
window->height,
window->name,
NULL,
NULL
);
ASSERT_SIMPLE(window->hwnd_lib);
//glfwSetInputMode(window->hwnd_lib, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwMakeContextCurrent(window->hwnd_lib);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
#if GLFW_EXPOSE_NATIVE_WIN32
window->hwnd = glfwGetWin32Window(window->hwnd_lib);
#endif
}
inline
void window_open(Window* window)
{
glfwMakeContextCurrent(window->hwnd_lib);
glViewport(window->x, window->y, window->width, window->height);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
}
inline
void window_close(Window* window)
{
glfwWindowShouldClose(window->hwnd_lib);
}
inline
uint32 get_texture_data_type(uint32 texture_data_type)
{
switch (texture_data_type) {
case TEXTURE_DATA_TYPE_2D: {
return GL_TEXTURE_2D;
}
case TEXTURE_DATA_TYPE_1D: {
return GL_TEXTURE_1D;
}
case TEXTURE_DATA_TYPE_3D: {
return GL_TEXTURE_3D;
}
case TEXTURE_DATA_TYPE_1D_ARRAY: {
return GL_TEXTURE_1D_ARRAY;
}
case TEXTURE_DATA_TYPE_2D_ARRAY: {
return GL_TEXTURE_2D_ARRAY;
}
case TEXTURE_DATA_TYPE_2D_MULTISAMPLED: {
return GL_TEXTURE_2D_MULTISAMPLE;
}
case TEXTURE_DATA_TYPE_2D_MULTISAMPLED_ARRAY: {
return GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
}
default: {
return GL_TEXTURE_2D;
}
}
}
// 1. prepare_texture
// 2. define wrap
// 3. define filter
// 4. load_texture_to_gpu
inline
void prepare_texture(TextureFile* texture, uint32 texture_unit)
{
uint32 texture_data_type = get_texture_data_type(texture->texture_data_type);
glGenTextures(1, (GLuint *) &texture->id);
glActiveTexture(GL_TEXTURE0 + texture_unit);
glBindTexture(texture_data_type, (GLuint) texture->id);
}
inline
void load_texture_to_gpu(const TextureFile* texture, int mipmap_level = 0)
{
uint32 texture_data_type = get_texture_data_type(texture->texture_data_type);
glTexImage2D(
texture_data_type, mipmap_level, GL_RGBA,
texture->image.width, texture->image.height,
0, GL_RGBA, GL_UNSIGNED_BYTE,
texture->image.pixels
);
if (mipmap_level > -1) {
glGenerateMipmap(GL_TEXTURE_2D);
}
}
inline
void texture_use(const TextureFile* texture, uint32 texture_unit)
{
glActiveTexture(GL_TEXTURE0 + texture_unit);
glBindTexture(GL_TEXTURE_2D, (GLuint) texture->id);
}
GLuint make_shader(GLenum type, const char *source, RingMemory* ring)
{
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE) {
GLint length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
GLchar *info = (GLchar *) ring_get_memory(ring, length * sizeof(GLchar));
glGetShaderInfoLog(shader, length, NULL, info);
// @todo log
}
return shader;
}
GLuint load_shader(GLenum type, const char *path, RingMemory* ring) {
uint64 temp = ring->pos;
// @bug potential bug for shaders > 4 mb
FileBody file;
file.content = ring_get_memory(ring, MEGABYTE * 4);
// @todo consider to accept file as parameter and load file before
file_read(path, &file);
GLuint result = make_shader(type, (const char *) file.content, ring);
// 4 mb of memory reservation is a lot and since we immediately can dispose of it
// we can also reset our ring memory position
ring->pos = temp;
return result;
}
GLuint make_program(GLuint shader1, GLuint shader2, RingMemory* ring) {
GLuint program = glCreateProgram();
glAttachShader(program, shader1);
glAttachShader(program, shader2);
glLinkProgram(program);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE) {
GLint length;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &length);
GLchar *info = (GLchar *) ring_get_memory(ring, length * sizeof(GLchar));
glGetProgramInfoLog(program, length, NULL, info);
// @todo use global logger
fprintf(stderr, "glLinkProgram failed: %s\n", info);
}
// @question really?
glDetachShader(program, shader1);
glDetachShader(program, shader2);
// @question really?
glDeleteShader(shader1);
glDeleteShader(shader2);
return program;
}
GLuint load_program(const char *path1, const char *path2, RingMemory* ring) {
GLuint shader1 = load_shader(GL_VERTEX_SHADER, path1, ring);
GLuint shader2 = load_shader(GL_FRAGMENT_SHADER, path2, ring);
GLuint program = make_program(shader1, shader2, ring);
return program;
}
inline
void shader_use(uint32 id)
{
glUseProgram(id);
}
void draw_triangles_3d(Attrib *attrib, GLuint buffer, int count) {
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glEnableVertexAttribArray(attrib->position);
glEnableVertexAttribArray(attrib->normal);
glEnableVertexAttribArray(attrib->uv);
glVertexAttribPointer(attrib->position, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, 0);
glVertexAttribPointer(attrib->normal, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, (GLvoid *)(sizeof(GLfloat) * 3));
glVertexAttribPointer(attrib->uv, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 8, (GLvoid *)(sizeof(GLfloat) * 6));
glDrawArrays(GL_TRIANGLES, 0, count);
glDisableVertexAttribArray(attrib->position);
glDisableVertexAttribArray(attrib->normal);
glDisableVertexAttribArray(attrib->uv);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void draw_triangles_2d(Attrib *attrib, GLuint buffer, size_t count) {
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glEnableVertexAttribArray(attrib->position);
glEnableVertexAttribArray(attrib->uv);
glVertexAttribPointer(attrib->position, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, 0);
glVertexAttribPointer(attrib->uv, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, (GLvoid *)(sizeof(GLfloat) * 2));
glDrawArrays(GL_TRIANGLES, 0, (GLsizei) count);
glDisableVertexAttribArray(attrib->position);
glDisableVertexAttribArray(attrib->uv);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
inline
void draw_text(Attrib *attrib, GLuint buffer, size_t length)
{
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
draw_triangles_2d(attrib, buffer, length * 6);
glDisable(GL_BLEND);
}
GLuint gen_text_buffer(float x, float y, float n, const char *text) {
size_t length = strlen(text);
GLfloat *data = NULL; //malloc_faces(4, length); // sizeof(GLfloat) * 6 * 4 * length
for (int i = 0; i < length; i++) {
make_character(data + i * 24, x, y, n / 2, n, text[i]);
x += n;
}
return 0; //gen_faces(4, length, data);
}
inline
void render_text(Attrib *attrib, int justify, float x, float y, float n, const char *text)
{
float matrix[16];
//set_matrix_2d(matrix, g->width, g->height);
glUseProgram(attrib->program);
glUniformMatrix4fv(attrib->matrix, 1, GL_FALSE, matrix);
glUniform1i(attrib->sampler, 1);
glUniform1i(attrib->extra1, 0);
size_t length = strlen(text);
x -= n * justify * (length - 1) / 2;
GLuint buffer = gen_text_buffer(x, y, n, text);
draw_text(attrib, buffer, length);
glDeleteBuffers(1, &buffer);
}
inline
int calculate_face_size(int components, int faces)
{
return sizeof(GLfloat) * 6 * components * faces;
}
// generates faces
// data is no longer needed after this
inline
uint32 gpuapi_buffer_generate(int size, f32 *data)
{
uint32 vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
return vbo;
}
inline
uint32 gpuapi_buffer_element_generate(int size, uint32 *data)
{
uint32 ebo;
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
return ebo;
}
inline
uint32 gpuapi_vertex_array_generate()
{
uint32 vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
return vao;
}
inline
void gpuapi_unbind_all()
{
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
inline
void gpuapi_buffer_delete(GLuint buffer)
{
glDeleteBuffers(1, &buffer);
}
int get_gpu_free_memory()
{
GLint available = 0;
glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &available);
if (available != 0) {
return available;
}
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, &available);
return available;
}
/*
void render_9_patch(GLuint texture,
int imgWidth, int imgHeight,
int img_x1, int img_x2,
int img_y1, int img_y2,
int renderWidth, int renderHeight,
int repeat
)
{
}
*/
#endif

108
hash/GeneralHash.h Normal file
View File

@ -0,0 +1,108 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_HASH_GENERAL_H
#define TOS_HASH_GENERAL_H
#include "../stdlib/Types.h"
uint64 hash_djb2(const char* key) {
uint64 hash = 5381;
int c;
while ((c = *key++)) {
hash = ((hash << 5) + hash) + c;
}
return hash;
}
uint64 hash_sdbm(const byte* key)
{
uint64 hash = 0;
int c;
while (c = *key++) {
hash = c + (hash << 6) + (hash << 16) - hash;
}
return hash;
}
uint64 hash_lose_lose(const byte* key)
{
uint64 hash = 0;
int c;
while (c = *key++) {
hash += c;
}
return hash;
}
uint64 hash_polynomial_rolling(const char* str) {
const int p = 31;
const int m = 1000000009;
uint64 hash = 0;
uint64 p_pow = 1;
while (*str) {
hash = (hash + (*str - 'a' + 1) * p_pow) % m;
p_pow = (p_pow * p) % m;
str++;
}
return hash;
}
uint64 hash_fnv1a(const char* str) {
const uint64 FNV_OFFSET_BASIS = 14695981039346656037UL;
const uint64 FNV_PRIME = 1099511628211UL;
uint64 hash = FNV_OFFSET_BASIS;
while (*str) {
hash ^= (byte) *str;
hash *= FNV_PRIME;
str++;
}
return hash;
}
uint32 hash_oat(const char* str)
{
uint32 h = 0;
while(*str) {
h += *str++;
h += (h << 10);
h ^= (h >> 6);
}
h += (h << 3);
h ^= (h >> 11);
h += (h << 15);
return h;
}
uint32 hash_ejb(const char* str)
{
const uint32 PRIME1 = 37;
const uint32 PRIME2 = 1048583;
uint32 h = 0;
while (*str) {
h = h * PRIME1 ^ (*str++ - ' ');
}
return h % PRIME2;
}
#endif

View File

@ -43,12 +43,6 @@ struct DIB_BITMAPCOREHEADER {
#define DIB_BITMAP_TYPE_OS21XBITMAPHEADER DIB_BITMAP_TYPE_BITMAPCOREHEADER
#define DIB_OS21XBITMAPHEADER DIB_BITMAPCOREHEADER
#define DIB_BITMAP_TYPE_OS22XBITMAPHEADER 64
struct DIB_OS22XBITMAPHEADER {
// @todo implement
// They don't use a size as first value? how do I know if this is the correct header?
};
#define DIB_BITMAP_TYPE_BITMAPINFOHEADER 40
struct DIB_BITMAPINFOHEADER {
uint32 size;
@ -58,12 +52,37 @@ struct DIB_BITMAPINFOHEADER {
uint16 bits_per_pixel;
uint32 compression_method;
uint32 raw_image_size;
//int32 horizontal_ppm;
//int32 vertical_ppm;
int32 horizontal_ppm;
int32 vertical_ppm;
uint32 color_palette;
uint32 important_colors;
};
#define DIB_BITMAP_TYPE_OS22XBITMAPHEADER 64
// OR BITMAPINFOHEADER2
struct DIB_OS22XBITMAPHEADER {
uint32 size;
int32 width;
int32 height;
uint16 color_planes;
uint16 bits_per_pixel;
uint32 compression_method;
uint32 raw_image_size;
int32 horizontal_ppm;
int32 vertical_ppm;
uint32 color_palette;
uint32 important_colors;
uint16 units;
uint16 padding;
uint16 bit_direction;
uint16 halftoning_algorithm;
int32 halftoning_parameter_1;
int32 halftoning_parameter_2;
int32 color_encoding;
int32 application_identifier;
};
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_RGB 0x0000
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_RLE8 0x0001
#define DIB_BITMAPINFOHEADER_COMPRESSION_BI_RLE4 0x0002
@ -90,16 +109,16 @@ struct DIB_BITMAPV3INFOHEADER {
};
struct CIEXYZ {
struct TOS_CIEXYZ {
int32 ciexyzX;
int32 ciexyzY;
int32 ciexyzZ;
};
struct CIEXYZTRIPLE {
CIEXYZ ciexyzRed;
CIEXYZ ciexyzGreen;
CIEXYZ ciexyzBlue;
struct TOS_CIEXYZTRIPLE {
TOS_CIEXYZ ciexyzRed;
TOS_CIEXYZ ciexyzGreen;
TOS_CIEXYZ ciexyzBlue;
};
#define DIB_BITMAP_TYPE_BITMAPV4HEADER 108
@ -111,8 +130,8 @@ struct DIB_BITMAPV4HEADER {
uint16 bits_per_pixel;
int32 compression_method;
int32 raw_image_size;
//int32 horizontal_ppm;
//int32 vertical_ppm;
int32 horizontal_ppm;
int32 vertical_ppm;
uint32 color_palette;
uint32 important_colors;
@ -121,7 +140,7 @@ struct DIB_BITMAPV4HEADER {
int32 bV4BlueMask;
int32 bV4AlphaMask;
int32 bV4CSType;
CIEXYZTRIPLE bV4Endpoints;
TOS_CIEXYZTRIPLE bV4Endpoints;
int32 bV4GammaRed;
int32 bV4GammaGreen;
int32 bV4GammaBlue;
@ -136,8 +155,8 @@ struct DIB_BITMAPV5HEADER {
uint16 bits_per_pixel;
int32 compression_method;
int32 raw_image_size;
//int32 horizontal_ppm;
//int32 vertical_ppm;
int32 horizontal_ppm;
int32 vertical_ppm;
uint32 color_palette;
uint32 important_colors;
@ -146,7 +165,7 @@ struct DIB_BITMAPV5HEADER {
int32 bV5BlueMask;
int32 bV5AlphaMask;
int32 bV5CSType;
CIEXYZTRIPLE bV5Endpoints;
TOS_CIEXYZTRIPLE bV5Endpoints;
int32 bV5GammaRed;
int32 bV5GammaGreen;
int32 bV5GammaBlue;
@ -158,7 +177,7 @@ struct DIB_BITMAPV5HEADER {
struct Bitmap {
BitmapHeader header;
byte dib_header_type;
uint32 dib_header_type;
DIB_BITMAPINFOHEADER dib_header; // Despite the different header types we use this one for simplicity
uint32* extra_bit_mask; // 3-4 = 12-16 bytes
byte color_table_size;
@ -215,6 +234,7 @@ void generate_default_bitmap_references(const FileBody* file, Bitmap* bitmap)
case DIB_BITMAP_TYPE_BITMAPV4HEADER:
case DIB_BITMAP_TYPE_BITMAPV3INFOHEADER:
case DIB_BITMAP_TYPE_BITMAPV2INFOHEADER:
case DIB_BITMAP_TYPE_OS22XBITMAPHEADER:
case DIB_BITMAP_TYPE_BITMAPINFOHEADER: {
bitmap->dib_header.size = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset)));
bitmap->dib_header.width = SWAP_ENDIAN_LITTLE(*((int32 *) (dib_header_offset + 4)));
@ -223,6 +243,8 @@ void generate_default_bitmap_references(const FileBody* file, Bitmap* bitmap)
bitmap->dib_header.bits_per_pixel = SWAP_ENDIAN_LITTLE(*((uint16 *) (dib_header_offset + 14)));
bitmap->dib_header.compression_method = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset + 16)));
bitmap->dib_header.raw_image_size = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset + 20)));
bitmap->dib_header.horizontal_ppm = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset + 24)));
bitmap->dib_header.vertical_ppm = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset + 28)));
bitmap->dib_header.color_palette = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset + 32)));
bitmap->dib_header.important_colors = SWAP_ENDIAN_LITTLE(*((uint32 *) (dib_header_offset + 36)));

View File

@ -10,10 +10,6 @@
#define TOS_IMAGE_C
#include "../utils/StringUtils.h"
#include "Image.h"
#include "Tga.h"
#include "Bitmap.h"
#include "Png.h"
#include "../memory/RingMemory.h"
#if _WIN32
@ -22,15 +18,15 @@
#include "../platform/linux/UtilsLinux.h"
#endif
#include "Image.h"
#include "Tga.h"
#include "Bitmap.h"
#include "Png.h"
void image_from_file(RingMemory* ring, const char* path, Image* image)
{
char full_path[MAX_PATH];
if (*path == '.') {
relative_to_absolute(path, full_path);
}
FileBody file;
file_read(full_path, &file, ring);
file_read(path, &file, ring);
if (str_ends_with(path, ".png")) {
image_png_generate(&file, image);

View File

@ -128,9 +128,10 @@ void huffman_png_compute(uint32 symbol_count, uint32* symbol_code_length, PngHuf
}
}
inline
PngHuffmanEntry huffman_png_decode(PngHuffman* huff, const byte* data, int pos)
{
uint32 index = get_bits(data, huff->max_code_length, pos);
uint32 index = (uint32) get_bits(data, huff->max_code_length, pos);
return huff->entries[index];
}
@ -142,7 +143,7 @@ void png_filter_reconstruct(uint32 width, uint32 height, const byte* decompresse
for (uint32 y = 0; y < height; ++y) {
byte filter = *decompressed;
byte* current_row = ;
byte* current_row = 0; // @todo need actual value
switch (filter) {
case 0: {
@ -240,6 +241,7 @@ bool image_png_generate(const FileBody* src_data, Image* image, int steps = 8)
int i = 33;
// r is the re-shift value in case we need to go back
// @todo r unused?
int r = 0;
// b is the current bit to read
@ -290,11 +292,11 @@ bool image_png_generate(const FileBody* src_data, Image* image, int steps = 8)
// DEFLATE Algorithm
// @bug the following 3 lines are wrong, they don't have to start at a bit 0/1
// A block doesn't have to start at an byte boundary
byte BFINAL = get_bits(src_data->content + i, 1, b);
byte BFINAL = (byte) get_bits(src_data->content + i, 1, b);
i += (b > 7 - 1);
b = (b + 1) & 7;
byte BTYPE = get_bits(src_data->content + i, 2, b);
byte BTYPE = (byte) get_bits(src_data->content + i, 2, b);
i += (b > 7 - 2);
b = (b + 2) & 7;
@ -305,6 +307,8 @@ bool image_png_generate(const FileBody* src_data, Image* image, int steps = 8)
}
uint16 len = *((uint16 *) (src_data->content + i + 1));
// @todo nlen unused?
uint16 nlen = *((uint16 *) (src_data->content + i + 3));
memcpy(image->pixels + out_pos, src_data->content + i + 5, len);
@ -324,15 +328,15 @@ bool image_png_generate(const FileBody* src_data, Image* image, int steps = 8)
if (BTYPE == 2) {
// Compressed with dynamic Huffman code
huffman_literal = get_bits(src_data->content + i, 5, b);
huffman_literal = (uint32) get_bits(src_data->content + i, 5, b);
i += (b > 7 - 5);
b = (b + 5) & 7;
huffman_dist = get_bits(src_data->content + i, 5, b);
huffman_dist = (uint32) get_bits(src_data->content + i, 5, b);
i += (b > 7 - 5);
b = (b + 5) & 7;
uint32 huffman_code_length = get_bits(src_data->content + i, 4, b);
uint32 huffman_code_length = (uint32) get_bits(src_data->content + i, 4, b);
i += (b > 7 - 4);
b = (b + 4) & 7;
@ -343,7 +347,7 @@ bool image_png_generate(const FileBody* src_data, Image* image, int steps = 8)
uint32 huffman_code_length_table[19] = {};
for (uint32 j = 0; j < huffman_code_length; ++j) {
huffman_code_length_table[HUFFMAN_CODE_LENGTH_ALPHA[j]] = get_bits(src_data->content + i, 3, b);
huffman_code_length_table[HUFFMAN_CODE_LENGTH_ALPHA[j]] = (uint32) get_bits(src_data->content + i, 3, b);
i += (b > 7 - 3);
b = (b + 3) & 7;
}
@ -367,17 +371,17 @@ bool image_png_generate(const FileBody* src_data, Image* image, int steps = 8)
if (encoded_length <= 15) {
rep_val = encoded_length;
} else if (encoded_length == 16) {
rep_count = 3 + get_bits(src_data->content + i, 2, b);
rep_count = 3 + (uint32) get_bits(src_data->content + i, 2, b);
i += (b > 7 - 2);
b = (b + 2) & 7;
rep_val = literal_length_dist_table[literal_length_count - 1];
} else if (encoded_length == 17) {
rep_count = 3 + get_bits(src_data->content + i, 3, b);
rep_count = 3 + (uint32) get_bits(src_data->content + i, 3, b);
i += (b > 7 - 3);
b = (b + 3) & 7;
} else if (encoded_length == 18) {
rep_count = 11 + get_bits(src_data->content + i, 7, b);
rep_count = 11 + (uint32) get_bits(src_data->content + i, 7, b);
i += (b > 7 - 7);
b = (b + 7) & 7;
}
@ -423,7 +427,7 @@ bool image_png_generate(const FileBody* src_data, Image* image, int steps = 8)
uint32 length = length_tab.symbol;
if (length_tab.bits_used) {
uint32 extra_bits = get_bits(src_data->content + i, length_tab.bits_used, b);
uint32 extra_bits = (uint32) get_bits(src_data->content + i, length_tab.bits_used, b);
i += (b + length_tab.bits_used) / 8;
b = (b + length_tab.bits_used) & 7;
@ -440,7 +444,7 @@ bool image_png_generate(const FileBody* src_data, Image* image, int steps = 8)
uint32 dist = dist_tab.symbol;
if (dist_tab.bits_used) {
uint32 extra_bits = get_bits(src_data->content + i, dist_tab.bits_used, b);
uint32 extra_bits = (uint32) get_bits(src_data->content + i, dist_tab.bits_used, b);
i += (b + dist_tab.bits_used) / 8;
b = (b + dist_tab.bits_used) & 7;
@ -461,7 +465,7 @@ bool image_png_generate(const FileBody* src_data, Image* image, int steps = 8)
image->height = src.ihdr.height;
// @todo fix pixels parameter
png_filter_reconstruct(image->width, image->height, image->pixels, image->pixels, steps);
png_filter_reconstruct(image->width, image->height, (byte *) image->pixels, (byte *) image->pixels, steps);
return true;
}

View File

@ -12,6 +12,7 @@
#include "../../stdlib/Intrinsics.h"
#include "../../stdlib/Mathtypes.h"
#include "../../utils/MathUtils.h"
#include <math.h>
void mat3_identity(float* matrix)
{
@ -20,6 +21,11 @@ void mat3_identity(float* matrix)
matrix[6] = 0.0f; matrix[7] = 0.0f; matrix[8] = 1.0f;
}
void mat3_identity_sparse(float* matrix)
{
matrix[0] = 1.0f; matrix[4] = 1.0f; matrix[8] = 1.0f;
}
void mat3_identity(__m128* matrix)
{
matrix[0] = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f);
@ -35,6 +41,11 @@ void mat4_identity(float* matrix)
matrix[12] = 0.0f; matrix[13] = 0.0f; matrix[14] = 0.0f; matrix[15] = 1.0f;
}
void mat4_identity_sparse(float* matrix)
{
matrix[0] = 1.0f; matrix[5] = 1.0f; matrix[10] = 1.0f; matrix[15] = 1.0f;
}
void mat4_identity(__m128* matrix)
{
matrix[0] = _mm_set_ps(1.0f, 0.0f, 0.0f, 0.0f);
@ -43,28 +54,22 @@ void mat4_identity(__m128* matrix)
matrix[3] = _mm_set_ps(0.0f, 0.0f, 0.0f, 1.0f);
}
void mat4_translate(float* matrix, float dx, float dy, float dz)
{
matrix[0] = 1; matrix[1] = 0; matrix[2] = 0; matrix[3] = 0;
matrix[4] = 0; matrix[5] = 1; matrix[6] = 0; matrix[7] = 0;
matrix[8] = 0; matrix[9] = 0; matrix[10] = 1; matrix[11] = 0;
matrix[12] = dx; matrix[13] = dy; matrix[14] = dz; matrix[15] = 1;
}
// x, y, z need to be normalized
void mat4_rotate(float* matrix, float x, float y, float z, float angle)
// https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
void mat4_rotation(float* matrix, float x, float y, float z, float angle)
{
float s = sinf_approx(angle);
float c = cosf_approx(angle);
// @todo replace with quaternions
float s = sinf(angle);
float c = cosf(angle);
float m = 1 - c;
float mx = m * x;
float my = m * y;
float mz = m * z;
float zs = z * s;
float xs = x * s;
float ys = y * s;
float zs = z * s;
float mxy = mx * y;
float mzx = mz * x;
@ -118,7 +123,7 @@ void mat3vec3_mult_sse(const float* matrix, const float* vector, float* result)
__m128 dot = _mm_dp_ps(row, vec, 0xF1);
result[i] = _mm_cvtss(dot);
result[i] = _mm_cvtss_f32(dot);
}
}
@ -128,7 +133,7 @@ void mat3vec3_mult_sse(const __m128* matrix, const __m128* vector, float* result
for (int i = 0; i < 3; ++i) {
__m128 dot = _mm_dp_ps(matrix[i], *vector, 0xF1);
result[i] = _mm_cvtss(dot);
result[i] = _mm_cvtss_f32(dot);
}
}
@ -157,7 +162,7 @@ void mat4vec4_mult_sse(const float* matrix, const float* vector, float* result)
__m128 row = _mm_loadu_ps(&matrix[i * 4]);
__m128 dot = _mm_dp_ps(row, vec, 0xF1);
result[i] = _mm_cvtss(dot);
result[i] = _mm_cvtss_f32(dot);
}
}
@ -167,7 +172,7 @@ void mat4vec4_mult_sse(const __m128* matrix, const __m128* vector, float* result
for (int i = 0; i < 4; ++i) {
__m128 dot = _mm_dp_ps(matrix[i], *vector, 0xF1);
result[i] = _mm_cvtss(dot);
result[i] = _mm_cvtss_f32(dot);
}
}
@ -179,8 +184,75 @@ void mat4vec4_mult_sse(const __m128* matrix, const __m128* vector, __m128* resul
}
}
void mat4mat4_mult(const float* a, const float* b, float* result)
void mat4mat4_mult(const float* a, const float* b, float* result, int steps = 8)
{
if (steps > 1) {
// @todo check http://fhtr.blogspot.com/2010/02/4x4-float-matrix-multiplication-using.html
// @question could simple mul add sse be faster?
// Load rows of matrix a
__m128 a_1 = _mm_loadu_ps(a);
__m128 a_2 = _mm_loadu_ps(&a[4]);
__m128 a_3 = _mm_loadu_ps(&a[8]);
__m128 a_4 = _mm_loadu_ps(&a[12]);
// Load columns of matrix b
__m128 b_1 = _mm_loadu_ps(b);
__m128 b_2 = _mm_loadu_ps(&b[4]);
__m128 b_3 = _mm_loadu_ps(&b[8]);
__m128 b_4 = _mm_loadu_ps(&b[12]);
_mm_storeu_ps(&result[0],
_mm_add_ps(
_mm_add_ps(
_mm_mul_ps(_mm_shuffle_ps(a_1, a_1, _MM_SHUFFLE(0, 0, 0, 0)), b_1),
_mm_mul_ps(_mm_shuffle_ps(a_1, a_1, _MM_SHUFFLE(1, 1, 1, 1)), b_2)
),
_mm_add_ps(
_mm_mul_ps(_mm_shuffle_ps(a_1, a_1, _MM_SHUFFLE(2, 2, 2, 2)), b_3),
_mm_mul_ps(_mm_shuffle_ps(a_1, a_1, _MM_SHUFFLE(3, 3, 3, 3)), b_4)
)
)
);
_mm_storeu_ps(&result[4],
_mm_add_ps(
_mm_add_ps(
_mm_mul_ps(_mm_shuffle_ps(a_2, a_2, _MM_SHUFFLE(0, 0, 0, 0)), b_1),
_mm_mul_ps(_mm_shuffle_ps(a_2, a_2, _MM_SHUFFLE(1, 1, 1, 1)), b_2)
),
_mm_add_ps(
_mm_mul_ps(_mm_shuffle_ps(a_2, a_2, _MM_SHUFFLE(2, 2, 2, 2)), b_3),
_mm_mul_ps(_mm_shuffle_ps(a_2, a_2, _MM_SHUFFLE(3, 3, 3, 3)), b_4)
)
)
);
_mm_storeu_ps(&result[8],
_mm_add_ps(
_mm_add_ps(
_mm_mul_ps(_mm_shuffle_ps(a_3, a_3, _MM_SHUFFLE(0, 0, 0, 0)), b_1),
_mm_mul_ps(_mm_shuffle_ps(a_3, a_3, _MM_SHUFFLE(1, 1, 1, 1)), b_2)
),
_mm_add_ps(
_mm_mul_ps(_mm_shuffle_ps(a_3, a_3, _MM_SHUFFLE(2, 2, 2, 2)), b_3),
_mm_mul_ps(_mm_shuffle_ps(a_3, a_3, _MM_SHUFFLE(3, 3, 3, 3)), b_4)
)
)
);
_mm_storeu_ps(&result[12],
_mm_add_ps(
_mm_add_ps(
_mm_mul_ps(_mm_shuffle_ps(a_4, a_4, _MM_SHUFFLE(0, 0, 0, 0)), b_1),
_mm_mul_ps(_mm_shuffle_ps(a_4, a_4, _MM_SHUFFLE(1, 1, 1, 1)), b_2)
),
_mm_add_ps(
_mm_mul_ps(_mm_shuffle_ps(a_4, a_4, _MM_SHUFFLE(2, 2, 2, 2)), b_3),
_mm_mul_ps(_mm_shuffle_ps(a_4, a_4, _MM_SHUFFLE(3, 3, 3, 3)), b_4)
)
)
);
} else {
// Row 0
result[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12];
result[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13];
@ -204,76 +276,7 @@ void mat4mat4_mult(const float* a, const float* b, float* result)
result[13] = a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13];
result[14] = a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14];
result[15] = a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15];
}
void mat4mat4_mult_sse(const float* a, const float* b, float* result)
{
// @todo check http://fhtr.blogspot.com/2010/02/4x4-float-matrix-multiplication-using.html
// @question could simple mul add sse be faster?
__m128 a_1 = _mm_loadu_ps(a);
__m128 a_2 = _mm_loadu_ps(&a[4]);
__m128 a_3 = _mm_loadu_ps(&a[8]);
__m128 a_4 = _mm_loadu_ps(&a[12]);
__m128 b_1 = _mm_loadu_ps(b);
__m128 b_2 = _mm_loadu_ps(&b[4]);
__m128 b_3 = _mm_loadu_ps(&b[8]);
__m128 b_4 = _mm_loadu_ps(&b[12]);
_MM_TRANSPOSE4_PS(b_1, b_2, b_3, b_4);
__m128 dot;
// b1
dot = _mm_dp_ps(a_1, b_1, 0xF1);
result[0] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_2, b_1, 0xF1);
result[1] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_3, b_1, 0xF1);
result[2] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_4, b_1, 0xF1);
result[3] = _mm_cvtss(dot);
// b2
dot = _mm_dp_ps(a_1, b_2, 0xF1);
result[4] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_2, b_2, 0xF1);
result[5] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_3, b_2, 0xF1);
result[6] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_4, b_2, 0xF1);
result[7] = _mm_cvtss(dot);
// b3
dot = _mm_dp_ps(a_1, b_3, 0xF1);
result[8] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_2, b_3, 0xF1);
result[9] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_3, b_3, 0xF1);
result[10] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_4, b_3, 0xF1);
result[11] = _mm_cvtss(dot);
// b4
dot = _mm_dp_ps(a_1, b_4, 0xF1);
result[12] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_2, b_4, 0xF1);
result[13] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_3, b_4, 0xF1);
result[14] = _mm_cvtss(dot);
dot = _mm_dp_ps(a_4, b_4, 0xF1);
result[15] = _mm_cvtss(dot);
}
}
void mat4mat4_mult_sse(const __m128* a, const __m128* b_transposed, float* result)
@ -283,55 +286,55 @@ void mat4mat4_mult_sse(const __m128* a, const __m128* b_transposed, float* resul
// @question could simple mul add sse be faster?
// b1
dot = _mm_dp_ps(a[0], b_transposed[0], 0xF1);
result[0] = _mm_cvtss(dot);
result[0] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[1], b_transposed[0], 0xF1);
result[1] = _mm_cvtss(dot);
result[1] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[2], b_transposed[0], 0xF1);
result[2] = _mm_cvtss(dot);
result[2] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[3], b_transposed[0], 0xF1);
result[3] = _mm_cvtss(dot);
result[3] = _mm_cvtss_f32(dot);
// b2
dot = _mm_dp_ps(a[0], b_transposed[1], 0xF1);
result[4] = _mm_cvtss(dot);
result[4] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[1], b_transposed[1], 0xF1);
result[5] = _mm_cvtss(dot);
result[5] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[2], b_transposed[1], 0xF1);
result[6] = _mm_cvtss(dot);
result[6] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[3], b_transposed[1], 0xF1);
result[7] = _mm_cvtss(dot);
result[7] = _mm_cvtss_f32(dot);
// b3
dot = _mm_dp_ps(a[0], b_transposed[2], 0xF1);
result[8] = _mm_cvtss(dot);
result[8] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[1], b_transposed[2], 0xF1);
result[9] = _mm_cvtss(dot);
result[9] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[2], b_transposed[2], 0xF1);
result[10] = _mm_cvtss(dot);
result[10] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[3], b_transposed[2], 0xF1);
result[11] = _mm_cvtss(dot);
result[11] = _mm_cvtss_f32(dot);
// b4
dot = _mm_dp_ps(a[0], b_transposed[3], 0xF1);
result[12] = _mm_cvtss(dot);
result[12] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[1], b_transposed[3], 0xF1);
result[13] = _mm_cvtss(dot);
result[13] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[2], b_transposed[3], 0xF1);
result[14] = _mm_cvtss(dot);
result[14] = _mm_cvtss_f32(dot);
dot = _mm_dp_ps(a[3], b_transposed[3], 0xF1);
result[15] = _mm_cvtss(dot);
result[15] = _mm_cvtss_f32(dot);
}
void mat4mat4_mult_sse(const __m128* a, const __m128* b_transpose, __m128* result)
@ -384,10 +387,11 @@ void mat4_frustum_planes(float planes[6][4], float radius, float *matrix) {
planes[5][3] = zfar * m[15] - m[14];
}
void mat4_frustum(
float *matrix, float left, float right, float bottom,
float top, float znear, float zfar)
{
void mat4_frustum_sparse(
float *matrix,
float left, float right, float bottom, float top,
float znear, float zfar
) {
float temp, temp2, temp3, temp4;
temp = 2.0f * znear;
temp2 = right - left;
@ -395,41 +399,45 @@ void mat4_frustum(
temp4 = zfar - znear;
matrix[0] = temp / temp2;
matrix[1] = 0.0;
matrix[2] = 0.0;
matrix[3] = 0.0;
//matrix[1] = 0.0f;
//matrix[2] = 0.0f;
//matrix[3] = 0.0f;
matrix[4] = 0.0;
//matrix[4] = 0.0f;
matrix[5] = temp / temp3;
matrix[6] = 0.0;
matrix[7] = 0.0;
//matrix[6] = 0.0f;
//matrix[7] = 0.0f;
matrix[8] = (right + left) / temp2;
matrix[9] = (top + bottom) / temp3;
matrix[10] = (-zfar - znear) / temp4;
matrix[11] = -1.0;
matrix[10] = -(zfar + znear) / temp4;
matrix[11] = -1.0f;
matrix[12] = 0.0;
matrix[13] = 0.0;
//matrix[12] = 0.0f;
//matrix[13] = 0.0f;
matrix[14] = (-temp * zfar) / temp4;
matrix[15] = 0.0;
//matrix[15] = 0.0f;
}
void mat4_perspective(
// fov needs to be in rad
void mat4_perspective_sparse(
float *matrix, float fov, float aspect,
float znear, float zfar)
{
ASSERT_SIMPLE(znear > 0.0f);
float ymax, xmax;
ymax = znear * tanf_approx(fov * OMS_PI / 360.0f);
ymax = znear * tanf(fov * 0.5f);
xmax = ymax * aspect;
mat4_frustum(matrix, -xmax, xmax, -ymax, ymax, znear, zfar);
mat4_frustum_sparse(matrix, -xmax, xmax, -ymax, ymax, znear, zfar);
}
void mat4_ortho(
float *matrix,
float left, float right, float bottom, float top, float near_dist, float far_dist)
{
float left, float right, float bottom, float top,
float near_dist, float far_dist
) {
float rl_delta = right - left;
float tb_delta = top - bottom;
float fn_delta = far_dist - near_dist;
@ -455,4 +463,18 @@ void mat4_ortho(
matrix[15] = 1;
}
void mat4_translate(float* matrix, float dx, float dy, float dz, int steps = 8)
{
alignas(64) float temp[16];
memcpy(temp, matrix, sizeof(float) * 16);
alignas(64) float translation_matrix[16];
translation_matrix[0] = 1; translation_matrix[1] = 0; translation_matrix[2] = 0; translation_matrix[3] = 0;
translation_matrix[4] = 0; translation_matrix[5] = 1; translation_matrix[6] = 0; translation_matrix[7] = 0;
translation_matrix[8] = 0; translation_matrix[9] = 0; translation_matrix[10] = 1; translation_matrix[11] = 0;
translation_matrix[12] = dx; translation_matrix[13] = dy; translation_matrix[14] = dz; translation_matrix[15] = 1;
mat4mat4_mult(temp, translation_matrix, matrix, steps);
}
#endif

113
memory/Allocation.h Normal file
View File

@ -0,0 +1,113 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_MEMORY_ALLOCATION_H
#define TOS_MEMORY_ALLOCATION_H
#include <malloc.h>
#if _WIN32
#include <windows.h>
inline
void* aligned_alloc(size_t alignment, size_t size) {
return _aligned_malloc(size, alignment);
}
inline
void aligned_free(void* ptr) {
_aligned_free(ptr);
ptr = NULL;
}
inline
void* playform_alloc(size_t size)
{
return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
}
inline
void* playform_alloc_aligned(size_t size, int alignment)
{
void* ptr = VirtualAlloc(NULL, size + alignment + sizeof(void*), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
void* aligned_ptr = (void*)(((uintptr_t)ptr + alignment + sizeof(void*) - 1) & ~(alignment - 1));
((void**) aligned_ptr)[-1] = ptr;
return aligned_ptr;
}
inline
void platform_free(void* ptr, size_t) {
VirtualFree(ptr, 0, MEM_RELEASE);
ptr = NULL;
}
inline
void platform_aligned_free(void* aligned_ptr, size_t) {
void* ptr = ((void**) aligned_ptr)[-1];
VirtualFree(ptr, 0, MEM_RELEASE);
aligned_ptr = NULL;
}
#else
#include <unistd.h>
#include <sys/mman.h>
inline
void aligned_free(void* ptr) {
free(ptr);
ptr = NULL;
}
inline
void* playform_alloc(size_t size)
{
// Get the system page size
size_t page_size = sysconf(_SC_PAGESIZE);
// Round up to the nearest page size
size = (size + page_size - 1) & ~(page_size - 1);
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
inline
void* playform_alloc_aligned(size_t size, int alignment)
{
// Get the system page size
size_t page_size = sysconf(_SC_PAGESIZE);
if (alignment < page_size) {
alignment = page_size;
}
// Round up to the nearest alignment boundary
size = (size + alignment - 1) & ~(alignment - 1);
void* ptr = mmap(NULL, size + alignment + sizeof(void*), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
void* aligned_ptr = (void*)(((uintptr_t)ptr + alignment + sizeof(void*) - 1) & ~(alignment - 1));
((void**) aligned_ptr)[-1] = ptr;
return aligned_ptr;
}
inline
void platform_free(void* ptr, size_t size) {
munmap(ptr, size);
ptr = NULL;
}
inline
void platform_aligned_free(void* aligned_ptr, size_t size) {
void* ptr = ((void**) aligned_ptr)[-1];
munmap(ptr, size + ((uintptr_t)aligned_ptr - (uintptr_t)ptr));
aligned_ptr = NULL;
}
#endif
#endif

View File

@ -11,23 +11,54 @@
#include <string.h>
#include "../stdlib/Types.h"
#include "MathUtils.h"
#include "TestUtils.h"
#include "../utils/MathUtils.h"
#include "../utils/TestUtils.h"
#include "Allocation.h"
struct BufferMemory {
byte* memory;
uint64 size;
uint64 pos;
int alignment;
};
inline
byte* buffer_get_memory(BufferMemory* buf, uint64 size, byte aligned = 1, bool zeroed = false)
void buffer_alloc(BufferMemory* buf, uint64 size, int alignment = 1)
{
buf->memory = alignment < 2
? (byte *) playform_alloc(size)
: (byte *) playform_alloc_aligned(size, alignment);
buf->alignment = alignment;
buf->size = size;
}
inline
void buffer_free(BufferMemory* buf)
{
if (buf->alignment < 2) {
platform_free(buf->memory, buf->size);
} else {
platform_aligned_free(buf->memory, buf->size);
}
}
inline
void buffer_reset(BufferMemory* buf)
{
// @bug arent we wasting element 0 (see get_memory, we are not using 0 only next element)
buf->pos = 0;
}
inline
byte* buffer_get_memory(BufferMemory* buf, uint64 size, int aligned = 1, bool zeroed = false)
{
ASSERT_SIMPLE(size <= buf->size);
if (aligned > 1 && buf->pos > 0) {
buf->pos = ROUND_TO_NEAREST(buf->pos, aligned);
if (aligned > 1) {
uintptr_t address = (uintptr_t) buf->memory;
buf->pos += (aligned - ((address + buf->pos) & (aligned - 1))) % aligned;
}
size = ROUND_TO_NEAREST(size, aligned);

View File

@ -11,50 +11,81 @@
#include <string.h>
#include "../stdlib/Types.h"
#include "MathUtils.h"
#include "../utils/MathUtils.h"
#include "Allocation.h"
struct ChunkMemory {
byte* memory;
uint64 count;
uint64 chunk_size;
uint64 last_pos = -1;
int64 last_pos;
int alignment;
// length = count
// free describes which locations are used and which are free
// @performance using uint32 or even uint64 might be faster
// since we can check for free elements faster if the memory is almost filled
// at the moment we can only check 8 elements at a time
uint64* free;
};
inline
byte* chunk_get_memory(ChunkMemory* buf, uint64 element)
void chunk_alloc(ChunkMemory* buf, uint64 count, uint64 chunk_size, int alignment = 1)
{
return buf->memory + element * buf->chunk_size;
buf->memory = alignment < 2
? (byte *) playform_alloc(count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64))
: (byte *) playform_alloc_aligned(count * chunk_size + sizeof(buf->free) * CEIL_DIV(count, 64), alignment);
buf->count = count;
buf->chunk_size = chunk_size;
buf->last_pos = -1;
buf->alignment = alignment;
buf->free = (uint64 *) (buf->memory + count * chunk_size);
}
inline
void chunk_free(ChunkMemory* buf)
{
if (buf->alignment < 2) {
platform_free(buf->memory, buf->count * buf->chunk_size);
} else {
platform_aligned_free(buf->memory, buf->count * buf->chunk_size);
}
}
inline
byte* chunk_get_element(ChunkMemory* buf, uint64 element, bool zeroed = false)
{
byte* offset = buf->memory + element * buf->chunk_size;
if (zeroed) {
memset((void *) offset, 0, buf->chunk_size);
}
return offset;
}
/**
* In some cases we know exactly which index is free
*/
void chunk_reserve_index(ChunkMemory* buf, int64 index, int elements = 1, bool zeroed = false)
void chunk_reserve_index(ChunkMemory* buf, int64 index, int64 elements = 1, bool zeroed = false)
{
int byte_index = index / 64;
int64 byte_index = index / 64;
int bit_index = index % 64;
// Mark the bits as reserved
for (int j = 0; j < elements; ++j) {
int current_byte_index = byte_index + (bit_index + j) / 64;
int64 current_byte_index = byte_index + (bit_index + j) / 64;
int current_bit_index = (bit_index + j) % 64;
buf->free[current_byte_index] |= (1 << current_bit_index);
buf->free[current_byte_index] |= (1LL << current_bit_index);
}
if (zeroed) {
memset(buf->memory + index * buf->chunk_size, 0, elements * buf->chunk_size);
}
buf->last_pos = index;
}
int64 chunk_reserve(ChunkMemory* buf, int elements = 1, bool zeroed = false)
int64 chunk_reserve(ChunkMemory* buf, uint64 elements = 1, bool zeroed = false)
{
int64 byte_index = (buf->last_pos + 1) / 64;
int bit_index;
@ -63,9 +94,15 @@ int64 chunk_reserve(ChunkMemory* buf, int elements = 1, bool zeroed = false)
byte mask;
int i = 0;
while (free_element < 0 && i < (buf->count + 7) / 64) {
int64 max_bytes = (buf->count + 7) / 64;
while (free_element < 0 && i < buf->count) {
++i;
if (byte_index >= max_bytes) {
byte_index = 0;
}
if (buf->free[byte_index] == 0xFF) {
++byte_index;
@ -78,7 +115,7 @@ int64 chunk_reserve(ChunkMemory* buf, int elements = 1, bool zeroed = false)
// Check if there are 'elements' consecutive free bits
for (int j = 0; j < elements; ++j) {
int current_byte_index = byte_index + (bit_index + j) / 64;
uint64 current_byte_index = byte_index + (bit_index + j) / 64;
int current_bit_index = (bit_index + j) % 64;
if (current_byte_index >= (buf->count + 7) / 64) {
@ -98,9 +135,9 @@ int64 chunk_reserve(ChunkMemory* buf, int elements = 1, bool zeroed = false)
// Mark the bits as reserved
for (int j = 0; j < elements; ++j) {
int current_byte_index = byte_index + (bit_index + j) / 64;
int64 current_byte_index = byte_index + (bit_index + j) / 64;
int current_bit_index = (bit_index + j) % 64;
buf->free[current_byte_index] |= (1 << current_bit_index);
buf->free[current_byte_index] |= (1LL << current_bit_index);
}
break;
@ -119,21 +156,27 @@ int64 chunk_reserve(ChunkMemory* buf, int elements = 1, bool zeroed = false)
memset(buf->memory + free_element * buf->chunk_size, 0, elements * buf->chunk_size);
}
buf->last_pos = free_element;
return free_element;
}
byte* chunk_find_free(ChunkMemory* buf)
{
int byte_index = (buf->last_pos + 1) / 64;
int64 byte_index = (buf->last_pos + 1) / 64;
int bit_index;
int64 free_element = -1;
byte mask;
int i = 0;
int max_loop = buf->count * buf->chunk_size;
int64 max_bytes = (buf->count + 7) / 64;
while (free_element < 0 && i < buf->count) {
if (byte_index >= max_bytes) {
byte_index = 0;
}
while (free_element < 0 && i < max_loop) {
if (buf->free[byte_index] == 0xFF) {
++i;
++byte_index;
@ -148,6 +191,8 @@ byte* chunk_find_free(ChunkMemory* buf)
mask = 1 << bit_index;
if ((buf->free[byte_index] & mask) == 0) {
free_element = byte_index * 64 + bit_index;
buf->free[byte_index] |= (1LL << bit_index);
break;
}
}
@ -157,15 +202,13 @@ byte* chunk_find_free(ChunkMemory* buf)
return NULL;
}
buf->free[byte_index] |= (1 << bit_index);
return buf->memory + free_element * buf->chunk_size;
}
inline
void chunk_element_free(ChunkMemory* buf, uint64 element)
void chunk_free_element(ChunkMemory* buf, uint64 element)
{
int byte_index = element / 64;
int64 byte_index = element / 64;
int bit_index = element % 64;
buf->free[byte_index] &= ~(1 << bit_index);

View File

@ -11,32 +11,86 @@
#include <string.h>
#include "../stdlib/Types.h"
#include "MathUtils.h"
#include "TestUtils.h"
#include "../utils/MathUtils.h"
#include "../utils/TestUtils.h"
#include "Allocation.h"
#include "BufferMemory.h"
struct RingMemory {
byte* memory;
uint64 size;
uint64 pos;
int alignment;
// The following two indices are only used in special cases such as iterating through a portion
// of the ring memory. In such cases it may be necessary to know where the start and end are.
// Examples for such cases are if a worker thread is pulling data from this ring memory in chunks.
// @question Is it guaranteed that if a thread realizes end changed, that also the memory is changed
// or is it possible that end changed but it still has old *memory in the cache?
// if yes we need to also check and wait for *memory != NULL and obviously set the memory to NULL
// after using it.
uint64 start;
uint64 end;
};
inline
void ring_alloc(RingMemory* ring, uint64 size, int alignment = 1)
{
ring->memory = alignment < 2
? (byte *) playform_alloc(size)
: (byte *) playform_alloc_aligned(size, alignment);
ring->size = size;
ring->pos = 0;
ring->alignment = alignment;
ring->start = 0;
ring->end = 0;
}
inline
void ring_create(RingMemory* ring, BufferMemory* buf, uint64 size, int alignment = 1)
{
ring->memory = buffer_get_memory(buf, size, alignment);
ring->size = size;
ring->pos = 0;
ring->alignment = alignment;
ring->start = 0;
ring->end = 0;
}
inline
void ring_free(RingMemory* buf)
{
if (buf->alignment < 2) {
platform_free(buf->memory, buf->size);
} else {
platform_aligned_free(buf->memory, buf->size);
}
}
inline
uint64 ring_calculate_position(const RingMemory* ring, uint64 pos, uint64 size, byte aligned = 1)
{
if (aligned > 1 && ring->pos > 0) {
pos = ROUND_TO_NEAREST(pos, aligned);
if (aligned) {
uintptr_t address = (uintptr_t) ring->memory;
int64 adjustment = (aligned - ((address + ring->pos) & (aligned - 1))) % aligned;
pos += adjustment;
}
size = ROUND_TO_NEAREST(size, aligned);
if (pos + size > ring->size) {
pos = 0;
if (aligned > 1) {
uintptr_t address = (uintptr_t) ring->memory;
int64 adjustment = (aligned - ((address + ring->pos) & (aligned - 1))) % aligned;
pos += adjustment;
}
}
return pos;
@ -46,13 +100,23 @@ byte* ring_get_memory(RingMemory* ring, uint64 size, byte aligned = 1, bool zero
{
ASSERT_SIMPLE(size <= ring->size);
if (aligned > 1 && ring->pos > 0) {
ring->pos = ROUND_TO_NEAREST(ring->pos, aligned);
if (aligned > 1) {
uintptr_t address = (uintptr_t) ring->memory;
int64 adjustment = (aligned - ((address + ring->pos) & (aligned - 1))) % aligned;
ring->pos += adjustment;
}
size = ROUND_TO_NEAREST(size, aligned);
if (ring->pos + size > ring->size) {
ring->pos = 0;
if (aligned > 1) {
uintptr_t address = (uintptr_t) ring->memory;
int64 adjustment = (aligned - ((address + ring->pos) & (aligned - 1))) % aligned;
ring->pos += adjustment;
}
}
byte* offset = (byte *) (ring->memory + ring->pos);
@ -68,11 +132,9 @@ byte* ring_get_memory(RingMemory* ring, uint64 size, byte aligned = 1, bool zero
// Used if the ring only contains elements of a certain size
// This way you can get a certain element
inline
byte *ring_get_element(const RingMemory* ring, uint64 element_count, uint64 element, uint64 size)
byte* ring_get_element(const RingMemory* ring, uint64 element_count, uint64 element, uint64 size)
{
uint64 index = (element % element_count) - 1;
index = index < 0 ? element_count : index;
int64 index = (element % element_count) - 1;
return ring->memory + index * size;
}

View File

@ -10,13 +10,12 @@
#define TOS_ATTRIB_H
#if OPENGL
#include "../../EngineDependencies/opengl/glew/include/GL/glew.h"
#include "../gpuapi/opengl/Opengl.h"
#include "../object/Vertex.h"
struct Attrib {
GLuint program;
GLuint position;
GLuint normal;
GLuint uv;
VertexRef vertices;
GLuint matrix;
GLuint sampler;
GLuint camera;

View File

@ -10,11 +10,17 @@
#define TOS_MODELS_CHAT_TYPE_H
enum ChatType {
CHAT_TYPE_LOCAL,
CHAT_TYPE_GLOBAL,
CHAT_TYPE_PLAYER,
CHAT_TYPE_GROUP,
CHAT_TYPE_GUILD
CHAT_TYPE_MIXED = 1,
CHAT_TYPE_LOCAL = 2,
CHAT_TYPE_GLOBAL = 4,
CHAT_TYPE_PLAYER = 8,
CHAT_TYPE_GROUP = 16,
CHAT_TYPE_GUILD = 32,
CHAT_TYPE_AUCTION_HOUSE = 64,
CHAT_TYPE_TRADE = 128,
CHAT_TYPE_PRIVATE = 256, // e.g. direct messages, also used in raid finders etc.
CHAT_TYPE_FRIENDS = 512,
CHAT_TYPE_CHAT_ROOM = 1024
};
#endif

View File

@ -0,0 +1 @@
# makes feared run from caster/target?

View File

@ -101,7 +101,7 @@ struct CSettings {
byte gpu_api = SETTING_TYPE_GPU_API_NONE;
byte gpu_type = SETTING_TYPE_GPU_MEDIUM;
byte gpu_fps = SETTING_TYPE_UNLIMITED;
byte gpu_memory = 4;
byte gpu_memory = 4; // how much vram are we using on the gpu
byte gpu_aspect_ratio;
byte gpu_resolution;
@ -145,9 +145,6 @@ struct CSettings {
byte gpu_footprint_quality; // mostly used for snow, sand mud
bool gpu_screen_effects; // e.g. water droplets/dust/freezing on screen
byte gpu_memory = 7;
byte cpu_memory = 10;
bool gpu_raytracing = false;
bool gpu_lense_effect = true;
bool gpu_fog_effect = true;
@ -414,6 +411,14 @@ struct CSettings {
byte hotkeys_marker_3 = 0x33; // 3
byte hotkeys_marker_4 = 0x34; // 4
byte hotkeys_marker_5 = 0x35; // 5
// Camera settings/positions
// Makes it easy to switch to customizable camera positions
byte hotkeys_camera_1 = 0x0;
byte hotkeys_camera_2 = 0x0;
byte hotkeys_camera_3 = 0x0;
// @todo implement the actual camera settings
};
#endif

15
noise/FractalNoise.h Normal file
View File

@ -0,0 +1,15 @@
/**
* Jingga
*
* @package Utils
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_NOISE_FRACTAL_H
#define TOS_NOISE_FRACTAL_H
#include <stdio.h>
#endif

221
noise/SimplexNoise.h Normal file
View File

@ -0,0 +1,221 @@
/**
* Jingga
*
* @package Utils
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_NOISE_SIMPLEX_H
#define TOS_NOISE_SIMPLEX_H
#include <stdio.h>
#define SIMPLEX_NOISE_F2 0.5 * (sqrt(3.0) - 1.0)
#define SIMPLEX_NOISE_G2 (3.0 - sqrt(3.0)) / 6.0
static const int perm[512] = {
151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,
151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,
};
static const int grad3_2[12][2] = {
{1,1}, {-1,1}, {1,-1}, {-1,-1},
{1,0}, {-1,0}, {1,0}, {-1,0},
{0,1}, {0,-1}, {0,1}, {0,-1}
};
static const int grad3_3[12][3] = {
{1,1,0}, {-1,1,0}, {1,-1,0}, {-1,-1,0},
{1,0,1}, {-1,0,1}, {1,0,-1}, {-1,0,-1},
{0,1,1}, {0,-1,1}, {0,1,-1}, {0,-1,-1}
};
static inline double simplex_noise_dot2(const int* g, double x, double y) {
return g[0] * x + g[1] * y;
}
static inline double simplex_noise_dot3(const int* g, double x, double y, double z) {
return g[0] * x + g[1] * y + g[2] * z;
}
double simplex_noise_2d(double x, double y) {
double n0, n1, n2; // Noise contributions from the three corners
// Skew the input space to determine which simplex cell we're in
double s = (x + y) * SIMPLEX_NOISE_F2; // Hairy factor for 2D
int i = floor(x + s);
int j = floor(y + s);
double t = (i + j) * SIMPLEX_NOISE_G2;
double X0 = i - t; // Unskew the cell origin back to (x, y) space
double Y0 = j - t;
double x0 = x - X0; // The x, y distances from the cell origin
double y0 = y - Y0;
// For the 2D case, the simplex shape is an equilateral triangle.
// Determine which simplex we are in.
int i1, j1; // Offsets for the second (middle) corner of simplex in (i, j)
if (x0 > y0) {
i1 = 1; j1 = 0; // Lower triangle, XY order
} else {
i1 = 0; j1 = 1; // Upper triangle, YX order
}
// A step of (1, 0) in (i, j) means a step of (1 - c, -c) in (x, y), and
// a step of (0, 1) in (i, j) means a step of (-c, 1 - c) in (x, y), where
// c = (3 - sqrt(3)) / 6
double x1 = x0 - i1 + SIMPLEX_NOISE_G2; // Offsets for middle corner in (x, y) unskewed coords
double y1 = y0 - j1 + SIMPLEX_NOISE_G2;
double x2 = x0 - 1.0 + 2.0 * SIMPLEX_NOISE_G2; // Offsets for last corner in (x, y) unskewed coords
double y2 = y0 - 1.0 + 2.0 * SIMPLEX_NOISE_G2;
// Work out the hashed gradient indices of the three simplex corners
int ii = i & 255;
int jj = j & 255;
int gi0 = perm[ii + perm[jj]] % 12;
int gi1 = perm[ii + i1 + perm[jj + j1]] % 12;
int gi2 = perm[ii + 1 + perm[jj + 1]] % 12;
// Calculate the contribution from the three corners
double t0 = 0.5 - x0 * x0 - y0 * y0;
if (t0 < 0) {
n0 = 0.0;
} else {
t0 *= t0;
n0 = t0 * t0 * simplex_noise_dot2(grad3_2[gi0], x0, y0); // (x,y) of grad3_2 used for 2D gradient
}
double t1 = 0.5 - x1 * x1 - y1 * y1;
if (t1 < 0) {
n1 = 0.0;
} else {
t1 *= t1;
n1 = t1 * t1 * simplex_noise_dot2(grad3_2[gi1], x1, y1);
}
double t2 = 0.5 - x2 * x2 - y2 * y2;
if (t2 < 0) {
n2 = 0.0;
} else {
t2 *= t2;
n2 = t2 * t2 * simplex_noise_dot2(grad3_2[gi2], x2, y2);
}
// Add contributions from each corner to get the final noise value.
// The result is scaled to return values in the interval [-1,1].
return 70.0 * (n0 + n1 + n2);
}
double simplex_noise_3d(double x, double y, double z) {
double n0, n1, n2, n3; // Noise contributions from the four corners
// Skew the input space to determine which simplex cell we're in
double s = (x + y + z) * SIMPLEX_NOISE_F2; // Skew factor for 3D
int i = floor(x + s);
int j = floor(y + s);
int k = floor(z + s);
double t = (i + j + k) * SIMPLEX_NOISE_G2;
double X0 = i - t; // Unskew the cell origin back to (x, y, z) space
double Y0 = j - t;
double Z0 = k - t;
double x0 = x - X0; // The x, y, z distances from the cell origin
double y0 = y - Y0;
double z0 = z - Z0;
// For the 3D case, the simplex shape is a slightly irregular tetrahedron.
// Determine which simplex we are in.
int i1, j1, k1; // Offsets for second corner of simplex in (i, j, k)
int i2, j2, k2; // Offsets for third corner of simplex in (i, j, k)
if (x0 >= y0) {
if (y0 >= z0) {
i1 = 1; j1 = 0; k1 = 0; // X Y Z order
i2 = 1; j2 = 1; k2 = 0;
} else if (x0 >= z0) {
i1 = 1; j1 = 0; k1 = 0; // X Z Y order
i2 = 1; j2 = 0; k2 = 1;
} else {
i1 = 0; j1 = 0; k1 = 1; // Z X Y order
i2 = 1; j2 = 0; k2 = 1;
}
} else { // x0 < y0
if (y0 < z0) {
i1 = 0; j1 = 0; k1 = 1; // Z Y X order
i2 = 0; j2 = 1; k2 = 1;
} else if (x0 < z0) {
i1 = 0; j1 = 1; k1 = 0; // Y Z X order
i2 = 0; j2 = 1; k2 = 1;
} else {
i1 = 0; j1 = 1; k1 = 0; // Y X Z order
i2 = 1; j2 = 1; k2 = 0;
}
}
// Offsets for second corner in (x, y, z) unskewed coords
double x1 = x0 - i1 + SIMPLEX_NOISE_G2;
double y1 = y0 - j1 + SIMPLEX_NOISE_G2;
double z1 = z0 - k1 + SIMPLEX_NOISE_G2;
// Offsets for third corner in (x, y, z) unskewed coords
double x2 = x0 - i2 + 2.0 * SIMPLEX_NOISE_G2;
double y2 = y0 - j2 + 2.0 * SIMPLEX_NOISE_G2;
double z2 = z0 - k2 + 2.0 * SIMPLEX_NOISE_G2;
// Offsets for last corner in (x, y, z) unskewed coords
double x3 = x0 - 1.0 + 3.0 * SIMPLEX_NOISE_G2;
double y3 = y0 - 1.0 + 3.0 * SIMPLEX_NOISE_G2;
double z3 = z0 - 1.0 + 3.0 * SIMPLEX_NOISE_G2;
// Work out the hashed gradient indices of the four simplex corners
int ii = i & 255;
int jj = j & 255;
int kk = k & 255;
int gi0 = perm[ii + perm[jj + perm[kk]]] % 12;
int gi1 = perm[ii + i1 + perm[jj + j1 + perm[kk + k1]]] % 12;
int gi2 = perm[ii + i2 + perm[jj + j2 + perm[kk + k2]]] % 12;
int gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] % 12;
// Calculate the contribution from the four corners
double t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
if (t0 < 0) {
n0 = 0.0;
} else {
t0 *= t0;
n0 = t0 * t0 * simplex_noise_dot3(grad3_3[gi0], x0, y0, z0);
}
double t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
if (t1 < 0) {
n1 = 0.0;
} else {
t1 *= t1;
n1 = t1 * t1 * simplex_noise_dot3(grad3_3[gi1], x1, y1, z1);
}
double t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
if (t2 < 0) {
n2 = 0.0;
} else {
t2 *= t2;
n2 = t2 * t2 * simplex_noise_dot3(grad3_3[gi2], x2, y2, z2);
}
double t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
if (t3 < 0) {
n3 = 0.0;
} else {
t3 *= t3;
n3 = t3 * t3 * simplex_noise_dot3(grad3_3[gi3], x3, y3, z3);
}
// Add contributions from each corner to get the final noise value.
// The result is scaled to return values in the interval [-1,1].
return 32.0 * (n0 + n1 + n2 + n3);
}
#endif

111
noise/ValueNoise.h Normal file
View File

@ -0,0 +1,111 @@
/**
* Jingga
*
* @package Utils
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_NOISE_VALUE_H
#define TOS_NOISE_VALUE_H
#include <stdio.h>
#include <stdlib.h>
#include "../animation/Animation.h"
// Initialize the grid with random values
void initialize_value_noise_2d(float* grid, int grid_size) {
for (int i = 0; i < grid_size * grid_size; ++i) {
grid[i] = (float) rand() / (float) RAND_MAX;
}
}
void initialize_value_noise_3d(float* grid, int rows, int cols, int depth) {
for (int i = 0; i < rows * cols * depth; ++i) {
grid[i] = (float) rand() / (float) RAND_MAX;
}
}
// @todo whenever we actually need this and we want to iterate over all x,y,z of a grid we will NOT iterate value_noise_2d.
// this would be way to slow!!!
// Instead we need to implement a simd version that performs the algorithm in value_noise_2d with a step size of 16/8/4
float value_noise_2d(float* grid, float x, float y, int rows, int cols) {
int grid_size = rows * cols;
// Calculate grid cell coordinates
int x0 = (int) floor(x) % grid_size;
int y0 = (int) floor(y) % grid_size;
int x1 = (x0 + 1) % grid_size;
int y1 = (y0 + 1) % grid_size;
// Calculate interpolation weights
float tx = x - floor(x);
float ty = y - floor(y);
// Smooth the weights using smoothstep function
tx = smoothstep(tx);
ty = smoothstep(ty);
// Interpolate the four corner values
float v00 = grid[y0 * rows + x0];
float v10 = grid[y0 * rows + x1];
float v01 = grid[y1 * rows + x0];
float v11 = grid[y1 * rows + x1];
// Interpolate along x direction
float v0 = lerp(v00, v10, tx);
float v1 = lerp(v01, v11, tx);
// Interpolate along y direction and return the final noise value
return lerp(v0, v1, ty);
}
float value_noise_3d(float* grid, float x, float y, float z, int rows, int cols, int depth) {
int grid_size = rows * cols * depth;
// Calculate grid cell coordinates
int x0 = (int) floor(x) % grid_size;
int y0 = (int) floor(y) % grid_size;
int z0 = (int) floor(z) % grid_size;
int x1 = (x0 + 1) % grid_size;
int y1 = (y0 + 1) % grid_size;
int z1 = (z0 + 1) % grid_size;
// Calculate interpolation weights
float tx = x - floor(x);
float ty = y - floor(y);
float tz = z - floor(z);
// Smooth the weights using smoothstep function
tx = smoothstep(tx);
ty = smoothstep(ty);
tz = smoothstep(tz);
// Interpolate the eight corner values
float v000 = grid[(y0 * rows + x0) * cols + z0];
float v100 = grid[(y0 * rows + x1) * cols + z0];
float v010 = grid[(y1 * rows + x0) * cols + z0];
float v110 = grid[(y1 * rows + x1) * cols + z0];
float v001 = grid[(y0 * rows + x0) * cols + z1];
float v101 = grid[(y0 * rows + x1) * cols + z1];
float v011 = grid[(y1 * rows + x0) * cols + z1];
float v111 = grid[(y1 * rows + x1) * cols + z1];
// Interpolate along x direction
float v00 = lerp(v000, v100, tx);
float v10 = lerp(v010, v110, tx);
float v01 = lerp(v001, v101, tx);
float v11 = lerp(v011, v111, tx);
// Interpolate along y direction
float v0 = lerp(v00, v10, ty);
float v1 = lerp(v01, v11, ty);
// Interpolate along z direction and return the final noise value
return lerp(v0, v1, tz);
}
#endif

117
noise/WorleyNoise.h Normal file
View File

@ -0,0 +1,117 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_NOISE_WORLEY_H
#define TOS_NOISE_WORLEY_H
#include <stdio.h>
#include <stdlib.h>
#include "../stdlib/Mathtypes.h"
#define WORLEY_FEATURE_POINTS 4
void generate_feature_points_2d(v2_f32* points, int feature_points, int rows, int cols) {
for (int i = 0; i < rows * cols * feature_points; ++i) {
points[i].x = (float) rand() / RAND_MAX;
points[i].y = (float) rand() / RAND_MAX;
}
}
void generate_feature_points_3d(v3_f32* points, int feature_points, int rows, int cols, int depth) {
for (int i = 0; i < rows * cols * depth * feature_points; ++i) {
points[i].x = (float) rand() / RAND_MAX;
points[i].y = (float) rand() / RAND_MAX;
points[i].z = (float) rand() / RAND_MAX;
}
}
float distance_squared_2d(float x1, float y1, float x2, float y2) {
return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
}
float distance_squared_3d(float x1, float y1, float z1, float x2, float y2, float z2) {
return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1);
}
float worley_noise_2d(v2_f32* points, int feature_points, float x, float y, int rows, int cols) {
int grid_size = rows * cols;
int cell_x = (int) floor(x);
int cell_y = (int) floor(y);
float min_dist_squared = INFINITY;
// Check the surrounding cells and the current cell
for (int i = -1; i <= 1; ++i) {
for (int j = -1; j <= 1; ++j) {
int neighbor_x = cell_x + i;
int neighbor_y = cell_y + j;
// Ensure the neighboring cell is within bounds
if (neighbor_x < 0 || neighbor_x >= cols
|| neighbor_y < 0 || neighbor_y >= rows
) {
continue;
}
for (int p = 0; p < feature_points; p++) {
v2_f32 fp = points[(neighbor_y * rows + neighbor_x) * cols + p];
float dist_squared = distance_squared_2d(x, y, fp.x, fp.y);
if (dist_squared < min_dist_squared) {
min_dist_squared = dist_squared;
}
}
}
}
return sqrt(min_dist_squared);
}
float worley_noise_3d(v3_f32* points, int feature_points, float x, float y, float z, int rows, int cols, int depth) {
int grid_size = rows * cols * depth;
int cell_x = (int) floor(x);
int cell_y = (int) floor(y);
int cell_z = (int) floor(z);
float min_dist_squared = INFINITY;
// Check the surrounding cells and the current cell
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
for (int k = -1; k <= 1; k++) {
int neighbor_x = cell_x + i;
int neighbor_y = cell_y + j;
int neighbor_z = cell_z + k;
// Ensure the neighboring cell is within bounds
if (neighbor_x < 0 || neighbor_x >= cols
|| neighbor_y < 0 || neighbor_y >= rows
|| neighbor_z < 0 || neighbor_z >= depth
) {
continue;
}
for (int p = 0; p < feature_points; ++p) {
v3_f32 fp = points[((neighbor_y * rows + neighbor_x) * cols + neighbor_z) * depth + p];
float dist_squared = distance_squared_3d(x, y, z, fp.x, fp.y, fp.z);
if (dist_squared < min_dist_squared) {
min_dist_squared = dist_squared;
}
}
}
}
}
return sqrt(min_dist_squared);
}
#endif

48
object/Animation.h Normal file
View File

@ -0,0 +1,48 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_OBJECT_ANIMATION_H
#define TOS_OBJECT_ANIMATION_H
#include "../stdlib/Types.h"
#include "../memory/RingMemory.h"
#if _WIN32
#include "../platform/win32/UtilsWin32.h"
#else
#include "../platform/linux/UtilsLinux.h"
#endif
struct Skeleton {
};
struct Animation {
};
void animation_from_file_txt(
RingMemory*,
const char*,
Animation*
)
{
}
void animation_from_file()
{
}
void animation_to_file()
{
}
#endif

20
object/FaceType.h Normal file
View File

@ -0,0 +1,20 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_OBJECT_FACE_TYPE_H
#define TOS_OBJECT_FACE_TYPE_H
enum FaceType {
FACE_TYPE_VERTICES = 1,
FACE_TYPE_TEXTURES = 2,
FACE_TYPE_NORMALS = 4,
FACE_TYPE_COLORS = 8,
FACE_TYPE_ALL = 15
};
#endif

44
object/Hitbox.h Normal file
View File

@ -0,0 +1,44 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_OBJECT_HITBOX_H
#define TOS_OBJECT_HITBOX_H
#include "../stdlib/Types.h"
#include "../memory/RingMemory.h"
#if _WIN32
#include "../platform/win32/UtilsWin32.h"
#else
#include "../platform/linux/UtilsLinux.h"
#endif
struct Hitbox {
};
void hitbox_from_file_txt(
RingMemory*,
const char*,
Hitbox*
)
{
}
void hitbox_from_file()
{
}
void hitbox_to_file()
{
}
#endif

44
object/Material.h Normal file
View File

@ -0,0 +1,44 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_OBJECT_MATERIAL_H
#define TOS_OBJECT_MATERIAL_H
#include "../stdlib/Types.h"
#include "../memory/RingMemory.h"
#if _WIN32
#include "../platform/win32/UtilsWin32.h"
#else
#include "../platform/linux/UtilsLinux.h"
#endif
struct Material {
};
void material_from_file_txt(
RingMemory*,
const char*,
Material*
)
{
}
void material_from_file()
{
}
void material_to_file()
{
}
#endif

26
object/Materials.md Normal file
View File

@ -0,0 +1,26 @@
| Name | Ambient | | | Diffuse | | | Specular | | | Shininess |
|----------------|----------|----------|----------|----------|------------|------------|------------|------------|------------|------------|
| emerald | 0.0215 | 0.1745 | 0.0215 | 0.07568 | 0.61424 | 0.07568 | 0.633 | 0.727811 | 0.633 | 0.6 |
| jade | 0.135 | 0.2225 | 0.1575 | 0.54 | 0.89 | 0.63 | 0.316228 | 0.316228 | 0.316228 | 0.1 |
| obsidian | 0.05375 | 0.05 | 0.06625 | 0.18275 | 0.17 | 0.22525 | 0.332741 | 0.328634 | 0.346435 | 0.3 |
| pearl | 0.25 | 0.20725 | 0.20725 | 1 | 0.829 | 0.829 | 0.296648 | 0.296648 | 0.296648 | 0.088 |
| ruby | 0.1745 | 0.01175 | 0.01175 | 0.61424 | 0.04136 | 0.04136 | 0.727811 | 0.626959 | 0.626959 | 0.6 |
| turquoise | 0.1 | 0.18725 | 0.1745 | 0.396 | 0.74151 | 0.69102 | 0.297254 | 0.30829 | 0.306678 | 0.1 |
| brass | 0.329412 | 0.223529 | 0.027451 | 0.780392 | 0.568627 | 0.113725 | 0.992157 | 0.941176 | 0.807843 | 0.21794872 |
| bronze | 0.2125 | 0.1275 | 0.054 | 0.714 | 0.4284 | 0.18144 | 0.393548 | 0.271906 | 0.166721 | 0.2 |
| chrome | 0.25 | 0.25 | 0.25 | 0.4 | 0.4 | 0.4 | 0.774597 | 0.774597 | 0.774597 | 0.6 |
| copper | 0.19125 | 0.0735 | 0.0225 | 0.7038 | 0.27048 | 0.0828 | 0.256777 | 0.137622 | 0.086014 | 0.1 |
| gold | 0.24725 | 0.1995 | 0.0745 | 0.75164 | 0.60648 | 0.22648 | 0.628281 | 0.555802 | 0.366065 | 0.4 |
| silver | 0.19225 | 0.19225 | 0.19225 | 0.50754 | 0.50754 | 0.50754 | 0.508273 | 0.508273 | 0.508273 | 0.4 |
| black plastic | 0 | 0 | 0 | 0.01 | 0.01 | 0.01 | 0.5 | 0.5 | 0.5 | 0.25 |
| cyan plastic | 0 | 0.1 | 0.06 | 0 | 0.50980392 | 0.50980392 | 0.50196078 | 0.50196078 | 0.50196078 | 0.25 |
| green plastic | 0 | 0 | 0 | 0.1 | 0.35 | 0.1 | 0.45 | 0.55 | 0.45 | 0.25 |
| red plastic | 0 | 0 | 0 | 0.5 | 0 | 0 | 0.7 | 0.6 | 0.6 | 0.25 |
| white plastic | 0 | 0 | 0 | 0.55 | 0.55 | 0.55 | 0.7 | 0.7 | 0.7 | 0.25 |
| yellow plastic | 0 | 0 | 0 | 0.5 | 0.5 | 0 | 0.6 | 0.6 | 0.5 | 0.25 |
| black rubber | 0.02 | 0.02 | 0.02 | 0.01 | 0.01 | 0.01 | 0.4 | 0.4 | 0.4 | 0.078125 |
| cyan rubber | 0 | 0.05 | 0.05 | 0.4 | 0.5 | 0.5 | 0.04 | 0.7 | 0.7 | 0.078125 |
| green rubber | 0 | 0.05 | 0 | 0.4 | 0.5 | 0.4 | 0.04 | 0.7 | 0.04 | 0.078125 |
| red rubber | 0.05 | 0 | 0 | 0.5 | 0.4 | 0.4 | 0.7 | 0.04 | 0.04 | 0.078125 |
| white rubber | 0.05 | 0.05 | 0.05 | 0.5 | 0.5 | 0.5 | 0.7 | 0.7 | 0.7 | 0.078125 |
| yellow rubber | 0.05 | 0.05 | 0 | 0.5 | 0.5 | 0.4 | 0.7 | 0.7 | 0.04 | 0.078125 |

82
object/Mesh.h Normal file
View File

@ -0,0 +1,82 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_OBJECT_MESH_H
#define TOS_OBJECT_MESH_H
#include "Vertex.h"
#include "FaceType.h"
#include "../stdlib/Types.h"
#include "../memory/RingMemory.h"
// @todo how to handle different objects and groups?
// maybe make a mesh hold other meshes?
// @todo handle vertice arrays where for example no texture coordinates are defined/used
struct Mesh {
byte* data; // memory owner that subdevides into the pointers below
uint32 object;
uint32 group_count;
uint32* groups;
// the following section allows us to create 2 types of data
// Interleaved: [position normal tex_coord] [color] (elements depend on vertex_type)
// Separate: [position] [normal] [tex_coord] [color] (separate array for elements)
uint32 vertex_type;
uint32 vertex_count; // can mean only position or combination of position, normal, tex, ...
uint32 normal_count;
uint32 tex_coord_count;
uint32 color_count;
float* vertices;
// The following references only exist in some situations
// depends on the settings above
float* normals;
float* tex_coords;
float* colors;
uint32 face_type;
uint32 face_count;
uint32 face_normal_count;
uint32 face_tex_coord_count;
uint32 face_color_count;
uint32* faces;
// The following references only exist in some situations
// depends on the settings above
uint32* face_textures;
uint32* face_normals;
uint32* face_colors;
// @todo this only works if you have sub meshes e.g. one for body, one for hat, one for weapon etc.
uint32 vertex_ref;
uint32 vao;
uint32 vbo;
uint32 ebo;
uint32 material_count;
uint32* materials;
uint32 texture;
uint32 animation_count;
uint32* animations;
uint32 hitbox_count;
uint32* hitboxes;
uint32 audio_count;
uint32* audios;
uint32 mesh_count;
Mesh* meshes;
};
#endif

943
object/Object.h Normal file
View File

@ -0,0 +1,943 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_OBJECT_H
#define TOS_OBJECT_H
#include "Vertex.h"
#include "../stdlib/Types.h"
#include "../memory/RingMemory.h"
#include "../utils/EndianUtils.h"
#include "../compression/LZP.h"
#if _WIN32
#include "../platform/win32/UtilsWin32.h"
#else
#include "../platform/linux/UtilsLinux.h"
#endif
#include "Mesh.h"
#include "../stdlib/simd/SIMD_I32.h"
// @todo also handle textures etc.
void object_from_file_txt(
RingMemory* ring,
const char* path,
Mesh* mesh
)
{
FileBody file;
file_read(path, &file, ring);
char* pos = (char *) file.content;
int object_index = 0;
int group_index = 0;
mesh->vertices = (float *) mesh->data;
mesh->vertex_count = 0;
mesh->normal_count = 0;
mesh->tex_coord_count = 0;
mesh->color_count = 0;
mesh->face_count = 0;
mesh->face_normal_count = 0;
mesh->face_tex_coord_count = 0;
mesh->face_color_count = 0;
uint32 temp_color_count = 0;
while (*pos != '\0') {
while (*pos == ' ') {
++pos;
}
if (*pos == '\n') {
++pos;
continue;
}
// Parse type
// WARNING: The code below could fail if [1] is outside of range
// However that should never happen for well formed files
int state = 0;
if (*pos == 'v' && pos[1] == ' ') {
state = 1;
} else if (*pos == 'v' && pos[1] == 'n') {
state = 2;
} else if (*pos == 'v' && pos[1] == 't') {
state = 3;
} else if (*pos == 'v' && pos[1] == 'p') {
state = 4;
} else if (*pos == 'o' && pos[1] == ' ') {
state = 5;
} else if (*pos == 's' && pos[1] == ' ') {
state = 6;
} else if (*pos == 'f' && pos[1] == ' ') {
state = 7;
} else if (*pos == 'g' && pos[1] == ' ') {
state = 8;
} else if (*pos == 'l' && pos[1] == ' ') {
state = 9;
} else if (*pos == 'm' && pos[1] == 't') {
state = 10;
} else if (*pos == 'h' && pos[1] == 'i') {
state = 11;
} else if (*pos == 'a' && pos[1] == 'n') {
state = 12;
} else if (*pos == 'u' && pos[3] == 'm') {
state = 13;
} else if (*pos == 'u' && pos[3] == 'h') {
state = 14;
} else {
// not supported or comment
while (*pos != '\n' && *pos != '\0') {
++pos;
}
}
// move past keyword
while (*pos != ' ' && *pos != '\n' && *pos != '\0') {
++pos;
}
// move past whitespaces and newline
bool is_next_line = false;
while (*pos == ' ' || *pos == '\n') {
is_next_line |= *pos == '\n';
++pos;
}
if (*pos == '\0' || is_next_line) {
continue;
}
// NOTE: we always load a file in the format: POSITON + NORMAL + TEXTURE + COLOR
// EVEN if some of the data is missing. This is necessary to keep the memory kinda in line.
// The actual binary file later will have the minimized layout.
// handle data types
switch (state) {
case 0: break;
case 1: {
// 'v'
if (mesh->vertex_count == 0) {
mesh->vertex_type |= VERTEX_TYPE_POSITION;
}
mesh->vertices[mesh->vertex_count * 3] = strtof(pos, &pos); ++pos;
mesh->vertices[mesh->vertex_count * 3 + 1] = strtof(pos, &pos); ++pos;
mesh->vertices[mesh->vertex_count * 3 + 2] = strtof(pos, &pos); ++pos;
// has color information
// @todo Move to own case statement // 'co'
if (*pos != '\n' && pos[1] != ' ' && pos[1] != '\n') {
if (mesh->vertex_count == 0) {
mesh->vertex_type |= VERTEX_TYPE_COLOR;
}
mesh->vertices[mesh->vertex_count * 12 + 8] = strtof(pos, &pos); ++pos;
mesh->vertices[mesh->vertex_count * 12 + 9] = strtof(pos, &pos); ++pos;
mesh->vertices[mesh->vertex_count * 12 + 10] = strtof(pos, &pos); ++pos;
// handle optional alpha [a]
if (*pos != '\n' && pos[1] != ' ' && pos[1] != '\n') {
mesh->vertices[mesh->vertex_count * 12 + 11] = strtof(pos, &pos); ++pos;
} else {
mesh->vertices[mesh->vertex_count * 12 + 11] = 1.0f;
}
++temp_color_count;
}
++mesh->vertex_count;
} break;
case 2: {
// 'vn'
// @bug This requires normals to be defined before textures
if (mesh->normal_count == 0) {
mesh->normals = mesh->vertices + mesh->vertex_count * 3;
}
mesh->normals[mesh->normal_count * 3] = strtof(pos, &pos); ++pos;
mesh->normals[mesh->normal_count * 3 + 1] = strtof(pos, &pos); ++pos;
mesh->normals[mesh->normal_count * 3 + 2] = strtof(pos, &pos); ++pos;
++mesh->normal_count;
} break;
case 3: {
// 'vt'
if (mesh->tex_coord_count == 0) {
mesh->tex_coords = mesh->vertices + mesh->vertex_count * 3 + mesh->normal_count * 3;
}
mesh->tex_coords[mesh->tex_coord_count * 2] = strtof(pos, &pos); ++pos;
mesh->tex_coords[mesh->tex_coord_count * 2 + 1] = strtof(pos, &pos); ++pos;
++mesh->tex_coord_count;
} break;
case 4: {
// 'vp'
strtof(pos, &pos); ++pos;
// handle optional [v]
if (*pos != '\n' && pos[1] != ' ' && pos[1] != '\n') {
strtof(pos, &pos); ++pos;
// handle optional [w]
if (*pos != '\n' && pos[1] != ' ' && pos[1] != '\n') {
strtof(pos, &pos); ++pos;
}
}
} break;
case 5: {
// 'o'
char text[100];
int i = 0;
while (*pos != '\0' && *pos != ' ') {
text[i++] = *pos++;
}
text[i] = '\0';
++object_index;
} break;
case 6: {
// 's'
strtol(pos, &pos, 10); ++pos;
} break;
case 7: {
// 'f'
if (mesh->face_count == 0) {
mesh->faces = (uint32 *) (mesh->vertices + mesh->vertex_count * 3 + mesh->normal_count * 3 + mesh->tex_coord_count * 2 + mesh->color_count * 4);
}
int ftype = 0;
char* tmp = pos;
while (*tmp != ' ') {
if (*tmp++ == '/') {
++ftype;
if (*tmp++ == '/') {
ftype = 3;
break;
}
}
}
const int max_blocks = 3; // @todo this could actually be N. Might have to change in the future
int block = 0;
while (*pos != '\0' && *pos != '\n') {
if (ftype == 0) {
// v1 v2 v3 ...
if (mesh->face_count == 0) {
mesh->face_type = FACE_TYPE_VERTICES;
}
mesh->faces[(mesh->face_count * max_blocks * 1) + block] = strtol(pos, &pos, 10) - 1; ++pos;
} else if (ftype == 1) {
// v1/vt1 v2/vt2 v3/vt3 ...
if (mesh->face_count == 0) {
mesh->face_type = FACE_TYPE_VERTICES | FACE_TYPE_TEXTURES;
}
mesh->faces[(mesh->face_count * max_blocks * 2) + block * 2] = strtol(pos, &pos, 10) - 1; ++pos;
mesh->faces[(mesh->face_count * max_blocks * 2) + block * 2 + 1] = strtol(pos, &pos, 10) - 1; ++pos;
} else if (ftype == 2) {
// v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ...
if (mesh->face_count == 0) {
mesh->face_type = FACE_TYPE_VERTICES | FACE_TYPE_TEXTURES | FACE_TYPE_NORMALS;
}
mesh->faces[(mesh->face_count * max_blocks * 3) + block * 3] = strtol(pos, &pos, 10) - 1; ++pos;
mesh->faces[(mesh->face_count * max_blocks * 3) + block * 3 + 1] = strtol(pos, &pos, 10) - 1; ++pos;
mesh->faces[(mesh->face_count * max_blocks * 3) + block * 3 + 2] = strtol(pos, &pos, 10) - 1; ++pos;
} else if (ftype == 3) {
// v1//vn1 v2//vn2 v3//vn3 ...
if (mesh->face_count == 0) {
mesh->face_type = FACE_TYPE_VERTICES | FACE_TYPE_NORMALS;
}
mesh->faces[(mesh->face_count * max_blocks * 2) + block * 2] = strtol(pos, &pos, 10) - 1; ++pos;
++pos;
mesh->faces[(mesh->face_count * max_blocks * 2) + block * 2 + 1] = strtol(pos, &pos, 10) - 1; ++pos;
}
++block;
}
++mesh->face_count;
} break;
case 8: {
// 'g'
char text[100];
int i = 0;
while (*pos != '\0' && *pos != ' ') {
text[i++] = *pos++;
}
text[i] = '\0';
++group_index;
} break;
case 9: {
//l
while (*pos != '\0' && *pos != '\n') {
strtol(pos, &pos, 10); ++pos;
}
} break;
case 10: {
// 'mtllib'
char text[100];
int i = 0;
while (*pos != '\0' && *pos != ' ') {
text[i++] = *pos++;
}
text[i] = '\0';
} break;
case 11: {
// 'hitlib'
char text[100];
int i = 0;
while (*pos != '\0' && *pos != ' ') {
text[i++] = *pos++;
}
text[i] = '\0';
} break;
case 12: {
// 'anilib'
char text[100];
int i = 0;
while (*pos != '\0' && *pos != ' ') {
text[i++] = *pos++;
}
text[i] = '\0';
} break;
case 13: {
// 'usemtl'
char text[100];
int i = 0;
while (*pos != '\0' && *pos != ' ') {
text[i++] = *pos++;
}
text[i] = '\0';
} break;
case 14: {
// 'usehit'
char text[100];
int i = 0;
while (*pos != '\0' && *pos != ' ') {
text[i++] = *pos++;
}
text[i] = '\0';
} break;
}
}
}
enum ObjectLoadingRestriction {
OBJECT_LOADING_RESTRICTION_POSITION = 1,
OBJECT_LOADING_RESTRICTION_NORMAL = 2,
OBJECT_LOADING_RESTRICTION_TEXTURE = 4,
OBJECT_LOADING_RESTRICTION_COLOR = 8,
OBJECT_LOADING_RESTRICTION_FACES = 16,
OBJECT_LOADING_RESTRICTION_EVERYTHING = 31
};
// @todo sometimes we don't care about some data, we should have an option which defines which data should be loaded
// this can improve performance for algorithms on this. e.g.:
// on the server side we only care about the vertex positions for collision (no normals, no color, ...)
int32 object_from_file(
RingMemory* ring,
const char* path,
Mesh* mesh,
const char* group = NULL,
int load_format = OBJECT_LOADING_RESTRICTION_EVERYTHING,
int size = 8
)
{
FileBody file;
file_read(path, &file, ring);
byte* pos = file.content;
// Read base data
mesh->vertex_type = *((int *) pos);
pos += sizeof(mesh->vertex_type);
mesh->vertex_count = *((int *) pos);
pos += sizeof(mesh->vertex_count);
mesh->normal_count = *((int *) pos);
pos += sizeof(mesh->normal_count);
mesh->tex_coord_count = *((int *) pos);
pos += sizeof(mesh->tex_coord_count);
mesh->color_count = *((int *) pos);
pos += sizeof(mesh->color_count);
#if !_WIN32 && !__LITTLE_ENDIAN
mesh->vertex_type = endian_swap(mesh->vertex_type);
mesh->verted_count = endian_swap(mesh->verted_count);
mesh->normal_count = endian_swap(mesh->normal_count);
mesh->tex_coord_count = endian_swap(mesh->tex_coord_count);
mesh->color_count = endian_swap(mesh->color_count);
#endif
int32 vertex_size = 0;
if (mesh->vertex_type & VERTEX_TYPE_POSITION) {
vertex_size += 3;
}
if (mesh->vertex_type & VERTEX_TYPE_NORMAL) {
vertex_size += 3;
}
if (mesh->vertex_type & VERTEX_TYPE_TEXTURE_COORD) {
vertex_size += 2;
}
if (mesh->vertex_type & VERTEX_TYPE_COLOR) {
vertex_size += 4;
}
int offset = 0;
if (mesh->vertex_count > 0) {
memcpy(mesh->data, pos, sizeof(float) * vertex_size * mesh->vertex_count);
mesh->vertices = (float *) mesh->data;
pos += sizeof(float) * vertex_size * mesh->vertex_count;
offset += sizeof(float) * vertex_size * mesh->vertex_count;
}
if (mesh->normal_count > 0) {
memcpy(mesh->data + offset, pos, sizeof(float) * 3 * mesh->normal_count);
mesh->normals = (float *) (mesh->data + offset);
pos += sizeof(float) * 3 * mesh->normal_count;
offset += sizeof(float) * 3 * mesh->normal_count;
}
if (mesh->tex_coord_count > 0) {
memcpy(mesh->data + offset, pos, sizeof(float) * 3 * mesh->tex_coord_count);
mesh->tex_coords = (float *) (mesh->data + offset);
pos += sizeof(float) * 2 * mesh->tex_coord_count;
offset += sizeof(float) * 2 * mesh->tex_coord_count;
}
if (mesh->color_count > 0) {
memcpy(mesh->data + offset, pos, sizeof(float) * 4 * mesh->color_count);
mesh->colors = (float *) (mesh->data + offset);
pos += sizeof(float) * 4 * mesh->color_count;
offset += sizeof(float) * 4 * mesh->color_count;
}
// Read face data
mesh->face_type = *((int *) pos);
pos += sizeof(mesh->face_type);
mesh->face_count = *((int *) pos);
pos += sizeof(mesh->face_count);
mesh->face_normal_count = *((int *) pos);
pos += sizeof(mesh->face_normal_count);
mesh->face_tex_coord_count = *((int *) pos);
pos += sizeof(mesh->face_tex_coord_count);
mesh->face_color_count = *((int *) pos);
pos += sizeof(mesh->face_color_count);
#if !_WIN32 && !__LITTLE_ENDIAN
mesh->face_type = endian_swap(mesh->face_type);
mesh->face_count = endian_swap(mesh->face_count);
mesh->face_normal_count = endian_swap(mesh->face_normal_count);
mesh->face_tex_coord_count = endian_swap(mesh->face_tex_coord_count);
mesh->face_color_count = endian_swap(mesh->face_color_count);
#endif
int face_size = 0;
if (mesh->face_type & FACE_TYPE_VERTICES) {
face_size += 3;
}
if ((mesh->face_type & FACE_TYPE_NORMALS)) {
face_size += 3;
}
if ((mesh->face_type & FACE_TYPE_TEXTURES)) {
face_size += 3;
}
if ((mesh->face_type & FACE_TYPE_COLORS)) {
face_size += 3;
}
// faces can be either in the form
// f: v/vt/vn ...
// or:
// f: v ...
// f: vn ...
// f: vt ...
if (mesh->face_count > 0) {
memcpy(mesh->data + offset, pos, sizeof(uint32) * face_size * mesh->face_count);
mesh->faces = (uint32 *) (mesh->data + offset);
pos += sizeof(uint32) * face_size * mesh->face_count;
offset += sizeof(uint32) * face_size * mesh->face_count;
}
if (mesh->face_normal_count > 0) {
memcpy(mesh->data + offset, pos, sizeof(uint32) * 3 * mesh->face_normal_count);
mesh->face_normals = (uint32 *) (mesh->data + offset);
pos += sizeof(uint32) * 3 * mesh->face_normal_count;
offset += sizeof(uint32) * 3 * mesh->face_normal_count;
}
if (mesh->face_tex_coord_count > 0) {
memcpy(mesh->data + offset, pos, sizeof(uint32) * 3 * mesh->face_tex_coord_count);
mesh->face_textures = (uint32 *) (mesh->data + offset);
pos += sizeof(uint32) * 3 * mesh->face_tex_coord_count;
offset += sizeof(uint32) * 3 * mesh->face_tex_coord_count;
}
if (mesh->face_color_count > 0) {
memcpy(mesh->data + offset, pos, sizeof(uint32) * 3 * mesh->face_color_count);
mesh->face_colors = (uint32 *) (mesh->data + offset);
pos += sizeof(uint32) * 3 * mesh->face_color_count;
offset += sizeof(uint32) * 3 * mesh->face_color_count;
}
SWAP_ENDIAN_LITTLE_SIMD(
(int *) mesh->data,
(int *) mesh->data,
offset / 4, // everything is 4 bytes -> super easy to swap
steps
);
return offset;
}
void object_to_file(
RingMemory* ring,
const char* path,
const Mesh* mesh,
int vertex_save_format = VERTEX_TYPE_POSITION,
int face_save_format = FACE_TYPE_VERTICES,
int size = 8
)
{
FileBody file;
// Temporary file size for buffer
file.size = sizeof(mesh) + sizeof(Vertex3D) * mesh->vertex_count + sizeof(float) * 12 * mesh->vertex_count + 4096;
file.content = ring_get_memory(ring, file.size, 64);
byte* pos = file.content;
// vertices
memcpy(pos, &vertex_save_format, sizeof(vertex_save_format));
pos += sizeof(vertex_save_format);
memcpy(pos, &mesh->vertex_count, sizeof(mesh->vertex_count));
pos += sizeof(mesh->vertex_count);
// We are can save the mesh in a different format from the current format -> need to adjust some values
uint32 normal_count = mesh->normal_count == 0 && (mesh->vertex_type & VERTEX_TYPE_NORMAL)
? mesh->vertex_count
: mesh->normal_count;
memcpy(pos, &normal_count, sizeof(mesh->normal_count));
pos += sizeof(mesh->normal_count);
uint32 tex_coord_count = mesh->tex_coord_count == 0 && (mesh->vertex_type & VERTEX_TYPE_TEXTURE_COORD)
? mesh->vertex_count
: mesh->tex_coord_count;
memcpy(pos, &tex_coord_count, sizeof(mesh->tex_coord_count));
pos += sizeof(mesh->tex_coord_count);
uint32 color_count = mesh->color_count == 0 && (mesh->vertex_type & VERTEX_TYPE_COLOR)
? mesh->vertex_count
: mesh->color_count;
memcpy(pos, &color_count, sizeof(mesh->color_count));
pos += sizeof(mesh->color_count);
// verticies
if (mesh->vertex_count > 0) {
int vertex_size = 0;
if (mesh->vertex_type & VERTEX_TYPE_POSITION) {
vertex_size += 3;
}
if (mesh->vertex_type & VERTEX_TYPE_NORMAL) {
vertex_size += 3;
}
if (mesh->vertex_type & VERTEX_TYPE_TEXTURE_COORD) {
vertex_size += 2;
}
if (mesh->vertex_type & VERTEX_TYPE_COLOR) {
vertex_size += 4;
}
int out_vertex_size = 0;
if (vertex_save_format & VERTEX_TYPE_POSITION) {
out_vertex_size += 3;
}
if (vertex_save_format & VERTEX_TYPE_NORMAL) {
out_vertex_size += 3;
}
if (vertex_save_format & VERTEX_TYPE_TEXTURE_COORD) {
out_vertex_size += 2;
}
if (vertex_save_format & VERTEX_TYPE_COLOR) {
out_vertex_size += 4;
}
if ((mesh->vertex_type == VERTEX_TYPE_ALL && vertex_save_format == VERTEX_TYPE_ALL)
|| (mesh->vertex_type == VERTEX_TYPE_POSITION && vertex_save_format == VERTEX_TYPE_POSITION)
) {
// data is the same as in the array
memcpy(pos, mesh->vertices, vertex_size * sizeof(float) * mesh->vertex_count);
pos += vertex_size * sizeof(float) * mesh->vertex_count;
} else {
float* temp = mesh->vertices;
float* end = mesh->vertices + mesh->vertex_count * vertex_size;
int offset;
byte* vertice_start = pos;
// @bug index gets increased every iteration BUT different groups and objects in the source may have different data
// This comes again down to how to handle hierarchal data with multiple groups and objects
int index = 0;
// iterate over all vertices to create new output format
while (temp < end) {
// @question why do I even need offset? couldn't I just directly manipulate temp?
offset = 0;
// First we save everything in one large array if that is the setting
if (vertex_save_format & VERTEX_TYPE_POSITION) {
if (mesh->vertex_type & VERTEX_TYPE_POSITION) {
memcpy(pos, temp, sizeof(float) * 3);
pos += sizeof(float) * 3;
offset += 3;
} else {
memset(pos, 0, sizeof(float) * 3);
pos += sizeof(float) * 3;
}
}
// We want separate arrays for some data
if ((mesh->vertex_type & VERTEX_TYPE_NORMAL) && !(vertex_save_format & VERTEX_TYPE_NORMAL)) {
// go to end of vertices * shift by previous array sizes + shift by current vertex -> creates one continous array with this data
memcpy(vertice_start
+ sizeof(float) * out_vertex_size * mesh->vertex_count
+ index * sizeof(float) * 3, temp + offset, sizeof(float) * 3);
offset += 3;
} else if (vertex_save_format & VERTEX_TYPE_NORMAL) {
if (mesh->vertex_type & VERTEX_TYPE_NORMAL) {
memcpy(pos, temp + offset, sizeof(float) * 3);
pos += sizeof(float) * 3;
offset += 3;
} else {
memset(pos, 0, sizeof(float) * 3);
pos += sizeof(float) * 3;
}
}
// We want separate arrays for some data
if ((mesh->vertex_type & VERTEX_TYPE_TEXTURE_COORD) && !(vertex_save_format & VERTEX_TYPE_TEXTURE_COORD)) {
// go to end of vertices * shift by previous array sizes + shift by current vertex -> creates one continous array with this data
memcpy(vertice_start
+ sizeof(float) * out_vertex_size * mesh->vertex_count
+ sizeof(float) * normal_count * 3
+ index * sizeof(float) * 3, temp + offset, sizeof(float) * 3);
offset += 2;
} else if (vertex_save_format & VERTEX_TYPE_TEXTURE_COORD) {
if (mesh->vertex_type & VERTEX_TYPE_TEXTURE_COORD) {
memcpy(pos, temp + offset, sizeof(float) * 2);
pos += sizeof(float) * 2;
offset += 2;
} else {
memset(pos, 0, sizeof(float) * 2);
pos += sizeof(float) * 2;
}
}
// We want separate arrays for some data
if ((mesh->vertex_type & VERTEX_TYPE_COLOR) && !(vertex_save_format & VERTEX_TYPE_COLOR)) {
// go to end of vertices * shift by previous array sizes + shift by current vertex -> creates one continous array with this data
memcpy(vertice_start
+ sizeof(float) * out_vertex_size * mesh->vertex_count
+ sizeof(float) * normal_count * 3
+ sizeof(float) * tex_coord_count * 2
+ index * sizeof(float) * 4, temp + offset, sizeof(float) * 4);
offset += 4;
} else if (vertex_save_format & VERTEX_TYPE_COLOR) {
if (mesh->vertex_type & VERTEX_TYPE_COLOR) {
memcpy(pos, temp + offset, sizeof(float) * 4);
pos += sizeof(float) * 4;
offset += 4;
} else {
memset(pos, 0, sizeof(float) * 4);
pos += sizeof(float) * 4;
}
}
temp += offset;
++index;
}
}
// check if we have clean array data already -> output this array data directly
if (mesh->normals && mesh->normal_count > 0) {
memcpy(pos, mesh->normals, mesh->normal_count * sizeof(float) * 3);
pos += mesh->normal_count * sizeof(float) * 3;
}
if (mesh->tex_coords && mesh->tex_coord_count > 0) {
memcpy(pos, mesh->tex_coords, mesh->tex_coord_count * sizeof(float) * 2);
pos += mesh->tex_coord_count * sizeof(float) * 2;
}
if (mesh->colors && mesh->color_count > 0) {
memcpy(pos, mesh->colors, mesh->color_count * sizeof(float) * 4);
pos += mesh->color_count * sizeof(float) * 4;
}
}
// faces/indices
memcpy(pos, &face_save_format, sizeof(face_save_format));
pos += sizeof(face_save_format);
memcpy(pos, &mesh->face_count, sizeof(mesh->face_count));
pos += sizeof(mesh->face_count);
// We are can save the mesh in a different format from the current format -> need to adjust some values
uint32 face_normal_count = mesh->face_normal_count == 0 && (mesh->face_type & FACE_TYPE_NORMALS)
? mesh->face_count
: mesh->face_normal_count;
memcpy(pos, &face_normal_count, sizeof(mesh->face_normal_count));
pos += sizeof(mesh->face_normal_count);
uint32 face_tex_coord_count = mesh->face_tex_coord_count == 0 && (mesh->face_type & FACE_TYPE_TEXTURES)
? mesh->face_count
: mesh->face_tex_coord_count;
memcpy(pos, &face_tex_coord_count, sizeof(mesh->face_tex_coord_count));
pos += sizeof(mesh->face_tex_coord_count);
uint32 face_color_count = mesh->face_color_count == 0 && (mesh->face_type & FACE_TYPE_COLORS)
? mesh->face_count
: mesh->face_color_count;
memcpy(pos, &face_color_count, sizeof(mesh->face_color_count));
pos += sizeof(mesh->face_color_count);
if (mesh->face_count > 0) {
// WARNING: Carefull, we again assume only 3 elements per face
int face_size = 0;
if (mesh->face_type & FACE_TYPE_VERTICES) {
face_size += 3;
}
if (mesh->face_type & FACE_TYPE_NORMALS) {
face_size += 3;
}
if (mesh->face_type & FACE_TYPE_TEXTURES) {
face_size += 3;
}
if (mesh->face_type & FACE_TYPE_COLORS) {
face_size += 3;
}
int out_face_size = 0;
if (face_save_format & FACE_TYPE_VERTICES) {
out_face_size += 3;
}
if (face_save_format & FACE_TYPE_NORMALS) {
out_face_size += 3;
}
if (face_save_format & FACE_TYPE_TEXTURES) {
out_face_size += 3;
}
if (face_save_format & FACE_TYPE_COLORS) {
out_face_size += 3;
}
if ((mesh->face_type == FACE_TYPE_ALL && face_save_format == FACE_TYPE_ALL)
|| (mesh->face_type == FACE_TYPE_VERTICES && face_save_format == FACE_TYPE_VERTICES)
) {
// data is the same as in the array
memcpy(pos, mesh->faces, face_size * sizeof(uint32) * mesh->face_count);
pos += face_size * sizeof(uint32) * mesh->face_count;
} else {
uint32* temp = mesh->faces;
uint32* end = mesh->faces + mesh->face_count * face_size;
int offset;
byte* face_start = pos;
// @bug index gets increased every iteration BUT different groups and objects in the source may have different data
// This comes again down to how to handle hierarchal data with multiple groups and objects
int index = 0;
// iterate over all faces to create new output format
// one iteration represents 1 block (a block could be v/vt/vn or, v, or v//vn, ...)
while (temp < end) {
// @question why do I even need offset? couldn't I just directly manipulate temp?
offset = 0;
// First we save everything in one large array if that is the setting
if (face_save_format & FACE_TYPE_VERTICES) {
if (mesh->face_type & FACE_TYPE_VERTICES) {
memcpy(pos, temp, sizeof(uint32));
pos += sizeof(uint32);
offset += 1;
} else {
memset(pos, 0, sizeof(float));
pos += sizeof(float);
}
}
// We want separate arrays for some data
if (mesh->face_type & FACE_TYPE_NORMALS && !(face_save_format & FACE_TYPE_NORMALS)) {
// go to end of faces * shift by previous array sizes + shift by current face -> creates one continous array with this data
memcpy(face_start
+ sizeof(uint32) * out_face_size * mesh->face_count
+ index * sizeof(uint32), temp + offset, sizeof(uint32));
offset += 1;
} else if (face_save_format & FACE_TYPE_NORMALS) {
if (mesh->face_type & FACE_TYPE_NORMALS) {
memcpy(pos, temp + offset, sizeof(uint32));
pos += sizeof(uint32);
offset += 1;
} else {
memset(pos, 0, sizeof(uint32));
pos += sizeof(uint32);
}
}
// We want separate arrays for some data
if (mesh->face_type & FACE_TYPE_TEXTURES && !(face_save_format & FACE_TYPE_TEXTURES)) {
// go to end of faces * shift by previous array sizes + shift by current face -> creates one continous array with this data
memcpy(face_start
+ sizeof(uint32) * out_face_size * mesh->face_count
+ sizeof(uint32) * 3 * face_normal_count
+ index * sizeof(uint32), temp + offset, sizeof(uint32));
offset += 1;
} else if (face_save_format & FACE_TYPE_TEXTURES) {
if (mesh->face_type & FACE_TYPE_TEXTURES) {
memcpy(pos, temp + offset, sizeof(uint32));
pos += sizeof(uint32);
offset += 1;
} else {
memset(pos, 0, sizeof(uint32));
pos += sizeof(uint32);
}
}
// We want separate arrays for some data
if (mesh->face_type & VERTEX_TYPE_COLOR && !(face_save_format & VERTEX_TYPE_COLOR)) {
// go to end of faces * shift by previous array sizes + shift by current face -> creates one continous array with this data
memcpy(face_start
+ sizeof(uint32) * out_face_size * mesh->face_count
+ sizeof(uint32) * 3 * face_normal_count
+ sizeof(uint32) * 3 * face_tex_coord_count
+ index * sizeof(uint32), temp + offset, sizeof(uint32));
offset += 1;
} else if (face_save_format & VERTEX_TYPE_COLOR) {
if (mesh->face_type & VERTEX_TYPE_COLOR) {
memcpy(pos, temp + offset, sizeof(uint32));
pos += sizeof(uint32);
offset += 1;
} else {
memset(pos, 0, sizeof(uint32));
pos += sizeof(uint32);
}
}
temp += offset;
++index;
}
}
// check if we have clean array data already -> output this array data directly
if (mesh->face_normals && mesh->face_normal_count > 0) {
memcpy(pos, mesh->face_normals, mesh->face_normal_count * sizeof(uint32) * 3);
pos += mesh->face_normal_count * sizeof(uint32) * 3;
}
if (mesh->face_textures && mesh->face_tex_coord_count > 0) {
memcpy(pos, mesh->face_textures, mesh->face_tex_coord_count * sizeof(uint32) * 3);
pos += mesh->face_tex_coord_count * sizeof(uint32) * 3;
}
if (mesh->face_colors && mesh->face_color_count > 0) {
memcpy(pos, mesh->face_colors, mesh->face_color_count * sizeof(uint32) * 3);
pos += mesh->face_color_count * sizeof(uint32) * 3;
}
}
file.size = pos - file.content;
SWAP_ENDIAN_LITTLE_SIMD(
(int *) file.content,
(int *) file.content,
(pos - file.content) / 4, // everything in here is 4 bytes -> super easy to swap
steps
);
/*
FileBody file2;
file2.content = ring_get_memory(ring, file.size, 64);
file2.size = encode_lzp(file.content, file.size, file2.content);
file_write(path, &file2);
*/
file_write(path, &file);
}
#endif

View File

@ -34,12 +34,13 @@
#include "../stdlib/Types.h"
#include "../image/Image.h"
#include "Attrib.h"
#include "../models/Attrib.h"
struct TextureFile {
struct Texture {
uint64 id;
// @question Should the texture hold the texture unit? If yes remember to update prepare_texture()
// @question Should the texture hold the texture unit?
// If yes remember to update prepare_texture()
byte texture_data_type;
@ -51,9 +52,7 @@ struct TextureFile {
Image image;
#if OPENGL
Attrib attrib;
#endif
int32 texture_ref;
};
#endif

43
object/Vertex.h Normal file
View File

@ -0,0 +1,43 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_OBJECT_VERTEX_H
#define TOS_OBJECT_VERTEX_H
#include "../stdlib/Types.h"
struct Vertex3D {
float position[3];
float normal[3];
uint32 tex_coord[2];
float color[4];
};
struct Vertex2D {
float position[2];
uint32 tex_coord[2];
float color[4];
};
struct VertexRef {
uint32 position;
uint32 normal;
uint32 tex_coord;
uint32 color;
uint32 index;
};
enum VertexType {
VERTEX_TYPE_POSITION = 1,
VERTEX_TYPE_NORMAL = 2,
VERTEX_TYPE_TEXTURE_COORD = 4,
VERTEX_TYPE_COLOR = 8,
VERTEX_TYPE_ALL = 15
};
#endif

19
particle/Particle.h Normal file
View File

@ -0,0 +1,19 @@
/**
* Jingga
*
* @package Utils
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PARTICLE_H
#define TOS_PARTICLE_H
#include "../stdlib/Mathtypes.h"
struct Particle {
v3_f32 position;
};
#endif

69
pathfinding/Metric2d.h Normal file
View File

@ -0,0 +1,69 @@
/**
* Jingga
*
* @package Utils
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PATHFINDING_METRIC2D_H
#define TOS_PATHFINDING_METRIC2D_H
#include <stdio.h>
#include <stdlib.h>
#include "../stdlib/Mathtypes.h"
#include "../utils/MathUtils.h"
#include "../memory/RingMemory.h"
float manhattan_2d(v2_f32 a, v2_f32 b) {
return fabs(a.x - b.x) + fabs(a.y - b.y);
}
float euclidean_2d(v2_f32 a, v2_f32 b) {
float dx = fabs(a.x - b.x);
float dy = fabs(a.y - b.y);
return sqrt(dx * dx + dy * dy);
}
float octile_2d(v2_f32 a, v2_f32 b) {
float dx = fabs(a.x - b.x);
float dy = fabs(a.y - b.y);
return dx < dy
? (SQRT_2 - 1) * dx + dy
: (SQRT_2 - 1) * dy + dx;
}
float chebyshev_2d(v2_f32 a, v2_f32 b) {
float dx = fabs(a.x - b.x);
float dy = fabs(a.y - b.y);
return fmax(dx, dy);
}
float minkowski_2d(v2_f32 a, v2_f32 b, int lambda) {
float dx = fabs(a.x - b.x);
float dy = fabs(a.y - b.y);
return pow(pow(dx, lambda) + pow(dy, lambda), 1.0 / lambda);
}
float canberra_2d(v2_f32 a, v2_f32 b) {
return (fabs(a.x - b.x) / (fabs(a.x) + fabs(b.x)))
+ (fabs(a.y - b.y) / (fabs(a.y) + fabs(b.y)));
}
float bray_curtis_2d(v2_f32 a, v2_f32 b) {
return (fabs(a.x - b.x) + fabs(a.y - b.y))
/ ((a.x + b.x) + (a.y + b.y));
}
float angular_separation_2d(v2_f32 a, v2_f32 b) {
return (a.x * b.x + a.y * b.y)
/ (sqrt(a.x * a.x + a.y * a.y) * sqrt(b.x * b.x + b.y * b.y));
}
#endif

90
pathfinding/Metric3d.h Normal file
View File

@ -0,0 +1,90 @@
/**
* Jingga
*
* @package Utils
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_PATHFINDING_METRIC3D_H
#define TOS_PATHFINDING_METRIC3D_H
#include <stdio.h>
#include <stdlib.h>
#include "../stdlib/Mathtypes.h"
#include "../memory/RingMemory.h"
// Manhattan distance for 3D
float manhattan_3d(v3_f32 a, v3_f32 b) {
return fabs(a.x - b.x)
+ fabs(a.y - b.y)
+ fabs(a.z - b.z);
}
// Euclidean distance for 3D
float euclidean_3d(v3_f32 a, v3_f32 b) {
float dx = a.x - b.x;
float dy = a.y - b.y;
float dz = a.z - b.z;
return sqrt(dx * dx + dy * dy + dz * dz);
}
// Chebyshev distance for 3D
float chebyshev_3d(v3_f32 a, v3_f32 b) {
float dx = fabs(a.x - b.x);
float dy = fabs(a.y - b.y);
float dz = fabs(a.z - b.z);
return fmax(fmax(dx, dy), dz);
}
// Minkowski distance for 3D
float minkowski_3d(v3_f32 a, v3_f32 b, int lambda) {
float dx = fabs(a.x - b.x);
float dy = fabs(a.y - b.y);
float dz = fabs(a.z - b.z);
return pow(
pow(dx, lambda)
+ pow(dy, lambda)
+ pow(dz, lambda),
1.0 / lambda
);
}
// Canberra distance for 3D
float canberra_3d(v3_f32 a, v3_f32 b) {
return fabs(a.x - b.x) / (fabs(a.x) + fabs(b.x))
+ fabs(a.y - b.y) / (fabs(a.y) + fabs(b.y))
+ fabs(a.z - b.z) / (fabs(a.z) + fabs(b.z));
}
// Bray-Curtis distance for 3D
float bray_curtis_3d(v3_f32 a, v3_f32 b) {
return (fabs(a.x - b.x) + fabs(a.y - b.y) + fabs(a.z - b.z))
/ ((a.x + b.x) + (a.y + b.y) + (a.z + b.z));
}
// Angular separation for 3D
float angular_separation_3d(v3_f32 a, v3_f32 b) {
return (a.x * b.x + a.y * b.y + a.z * b.z)
/ (sqrt(a.x * a.x + a.y * a.y + a.z * a.z) * sqrt(b.x * b.x + b.y * b.y + b.z * b.z));
}
// Hamming distance for arrays
int hamming(int* a, int* b, int size) {
int dist = 0;
for (int i = 0; i < size; ++i) {
if (a[i] != b[i]) {
++dist;
}
}
return dist;
}
#endif

View File

@ -52,6 +52,29 @@ int sprintf_s(char *buffer, size_t sizeOfBuffer, const char *format, ...) {
return result;
}
inline void relative_to_absolute(const char* rel, char* path)
{
const char* temp = rel;
if (temp[0] == '.' && temp[1] == '/') {
temp += 2;
}
char self_path[MAX_PATH];
ssize_t count = readlink("/proc/self/exe", self_path, MAX_PATH - 1);
if (count == -1) {
return;
}
self_path[count] = '\0';
char* last = strrchr(self_path, '/');
if (last != NULL) {
*(last + 1) = '\0';
}
snprintf(path, MAX_PATH, "%s%s", self_path, temp);
}
// @todo implement relative path support, similar to UtilsWin32
inline
uint64 file_size(const char* filename) {
struct stat st;
@ -209,28 +232,6 @@ void self_path(char* path) {
}
}
inline void relative_to_absolute(const char* rel, char* path)
{
const char* temp = rel;
if (temp[0] == '.' && temp[1] == '/') {
temp += 2;
}
char self_path[MAX_PATH];
ssize_t count = readlink("/proc/self/exe", self_path, MAX_PATH - 1);
if (count == -1) {
return;
}
self_path[count] = '\0';
char* last = strrchr(self_path, '/');
if (last != NULL) {
*(last + 1) = '\0';
}
snprintf(path, MAX_PATH, "%s%s", self_path, temp);
}
inline
void strncpy_s(char *dest, size_t destsz, const char *src, size_t count) {
size_t i;

View File

@ -12,6 +12,8 @@
#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <malloc.h>
#ifdef _MSC_VER
#include <io.h>
#endif
@ -19,20 +21,57 @@
#include "../../stdlib/Types.h"
#include "../../utils/Utils.h"
#include "../../utils/TestUtils.h"
#include "../../memory/RingMemory.h"
#define strtok_r strtok_s
inline void relative_to_absolute(const char* rel, char* path)
{
char self_path[MAX_PATH];
if (GetModuleFileNameA(NULL, self_path, MAX_PATH) == 0) {
return;
}
const char* temp = rel;
if (temp[0] == '.' && temp[1] == '/') {
temp += 2;
}
char* last = strrchr(self_path, '\\');
if (last != NULL) {
*(last + 1) = '\0';
}
snprintf(path, MAX_PATH, "%s%s", self_path, temp);
}
inline uint64
file_size(const char* filename)
file_size(const char* path)
{
// @performance Profile against fseek strategy
HANDLE fp = CreateFileA((LPCSTR) filename,
HANDLE fp;
if (*path == '.') {
char full_path[MAX_PATH];
relative_to_absolute(path, full_path);
fp = CreateFileA((LPCSTR) full_path,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
NULL
);
} else {
fp = CreateFileA((LPCSTR) path,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
}
if (fp == INVALID_HANDLE_VALUE) {
return 0;
@ -48,16 +87,47 @@ file_size(const char* filename)
return size.QuadPart;
}
inline void
file_read(const char* filename, FileBody* file, RingMemory* ring = NULL)
inline
uint64 time_ms()
{
HANDLE fp = CreateFileA((LPCSTR) filename,
LARGE_INTEGER frequency;
LARGE_INTEGER counter;
if (!QueryPerformanceFrequency(&frequency)) {
return 0;
}
QueryPerformanceCounter(&counter);
return (counter.QuadPart * 1000) / frequency.QuadPart;
}
inline void
file_read(const char* path, FileBody* file, RingMemory* ring = NULL)
{
HANDLE fp;
if (*path == '.') {
char full_path[MAX_PATH];
relative_to_absolute(path, full_path);
fp = CreateFileA((LPCSTR) full_path,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
NULL
);
} else {
fp = CreateFileA((LPCSTR) path,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
}
if (fp == INVALID_HANDLE_VALUE) {
file->size = 0;
@ -92,15 +162,31 @@ file_read(const char* filename, FileBody* file, RingMemory* ring = NULL)
}
inline uint64
file_read_struct(const char* filename, void* file, uint32 size)
file_read_struct(const char* path, void* file, uint32 size)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
HANDLE fp;
if (*path == '.') {
char full_path[MAX_PATH];
relative_to_absolute(path, full_path);
fp = CreateFileA((LPCSTR) full_path,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
NULL
);
} else {
fp = CreateFileA((LPCSTR) path,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
}
if (fp == INVALID_HANDLE_VALUE) {
return 0;
@ -127,15 +213,31 @@ file_read_struct(const char* filename, void* file, uint32 size)
}
inline bool
file_write(const char* filename, const FileBody* file)
file_write(const char* path, const FileBody* file)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
HANDLE fp;
if (*path == '.') {
char full_path[MAX_PATH];
relative_to_absolute(path, full_path);
fp = CreateFileA((LPCSTR) full_path,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
NULL
);
} else {
fp = CreateFileA((LPCSTR) path,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
}
if (fp == INVALID_HANDLE_VALUE) {
return false;
@ -155,18 +257,30 @@ file_write(const char* filename, const FileBody* file)
}
inline bool
file_write_struct(const char* filename, const void* file, uint32 size)
file_write_struct(const char* path, const void* file, uint32 size)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
HANDLE fp;
if (*path == '.') {
char full_path[MAX_PATH];
relative_to_absolute(path, full_path);
fp = CreateFileA((LPCSTR) full_path,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (fp == INVALID_HANDLE_VALUE) {
return false;
NULL
);
} else {
fp = CreateFileA((LPCSTR) path,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
}
DWORD written;
@ -188,15 +302,31 @@ file_copy(const char* src, const char* dst)
}
inline
HANDLE get_append_handle(const char* filename)
HANDLE get_append_handle(const char* path)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
HANDLE fp;
if (*path == '.') {
char full_path[MAX_PATH];
relative_to_absolute(path, full_path);
fp = CreateFileA((LPCSTR) full_path,
FILE_APPEND_DATA,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
NULL
);
} else {
fp = CreateFileA((LPCSTR) path,
FILE_APPEND_DATA,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
}
if (fp == INVALID_HANDLE_VALUE) {
return NULL;
@ -206,15 +336,31 @@ HANDLE get_append_handle(const char* filename)
}
inline bool
file_append(const char* filename, const char* file)
file_append(const char* path, const char* file)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
HANDLE fp;
if (*path == '.') {
char full_path[MAX_PATH];
relative_to_absolute(path, full_path);
fp = CreateFileA((LPCSTR) full_path,
FILE_APPEND_DATA,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
NULL
);
} else {
fp = CreateFileA((LPCSTR) path,
FILE_APPEND_DATA,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
}
if (fp == INVALID_HANDLE_VALUE) {
return false;
@ -242,6 +388,7 @@ file_append(HANDLE fp, const char* file)
DWORD written;
DWORD length = (DWORD) strlen(file); // @question WHY is WriteFile not supporting larger data?
ASSERT_SIMPLE(length < MAX_INT32);
if (!WriteFile(fp, file, length, &written, NULL)) {
CloseHandle(fp);
return false;
@ -252,15 +399,48 @@ file_append(HANDLE fp, const char* file)
}
inline bool
file_append(const char* filename, const FileBody* file)
file_append(HANDLE fp, const char* file, size_t length)
{
HANDLE fp = CreateFileA((LPCSTR) filename,
if (fp == INVALID_HANDLE_VALUE) {
return false;
}
DWORD written;
if (!WriteFile(fp, file, (uint32) length, &written, NULL)) {
CloseHandle(fp);
return false;
}
CloseHandle(fp);
return true;
}
inline bool
file_append(const char* path, const FileBody* file)
{
HANDLE fp;
if (*path == '.') {
char full_path[MAX_PATH];
relative_to_absolute(path, full_path);
fp = CreateFileA((LPCSTR) full_path,
FILE_APPEND_DATA,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
NULL
);
} else {
fp = CreateFileA((LPCSTR) path,
FILE_APPEND_DATA,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
}
if (fp == INVALID_HANDLE_VALUE) {
return false;
@ -279,12 +459,21 @@ file_append(const char* filename, const FileBody* file)
}
inline
uint64 last_modified(const char* filename)
uint64 last_modified(const char* path)
{
FILETIME modified = {};
WIN32_FIND_DATA find_data;
HANDLE fp = FindFirstFileA(filename, (LPWIN32_FIND_DATAA) &find_data);
HANDLE fp;
if (*path == '.') {
char full_path[MAX_PATH];
relative_to_absolute(path, full_path);
fp = FindFirstFileA(full_path, (LPWIN32_FIND_DATAA) &find_data);
} else {
fp = FindFirstFileA(path, (LPWIN32_FIND_DATAA) &find_data);
}
FILETIME modified = {};
if(fp != INVALID_HANDLE_VALUE) {
modified = find_data.ftLastWriteTime;
FindClose(fp);
@ -299,98 +488,45 @@ uint64 last_modified(const char* filename)
inline void self_path(char* path)
{
//HMODULE dll = GetModuleHandle(NULL);
GetModuleFileNameA(NULL, (LPSTR) path, MAX_PATH);
}
inline void relative_to_absolute(const char* rel, char* path)
{
char self_path[MAX_PATH];
if (GetModuleFileNameA(NULL, self_path, MAX_PATH) == 0) {
return;
}
const char* temp = rel;
if (temp[0] == '.' && temp[1] == '/') {
temp += 2;
}
char* last = strrchr(self_path, '\\');
if (last != NULL) {
*(last + 1) = '\0';
}
snprintf(path, MAX_PATH, "%s%s", self_path, temp);
}
void log_to_file(LogPool* logs, HANDLE fp)
void log_to_file(RingMemory* logs, HANDLE fp)
{
// we don't log an empty log pool
if (logs->pos == 0) {
return;
}
char *offset = logs->memory;
for (uint32 i = 0; i < logs->pos * MAX_LOG_LENGTH + MAX_LOG_LENGTH; ++i) {
if (*offset == '\0') {
*offset = '\n';
// @performance would it make sense to jump to the next log message
// we know that after \0 until the end of this log message everything is 0
}
++offset;
}
logs->memory[logs->count * MAX_LOG_LENGTH - 1] = '\0';
file_append(fp, logs->memory);
file_append(fp, (char *) logs->memory, logs->size);
memset(logs->memory, 0, logs->size);
// reset log position to start of memory pool
logs->pos = 0;
logs->start = 0;
}
// snprintf(logs->memory + logs->pos * MAX_LOG_LENGTH, MAX_LOG_LENGTH, "My text %s", str1);
// log(log, NULL);
void log(LogPool* logs, HANDLE fp = NULL)
void log(RingMemory* logs, const char* str, HANDLE fp = NULL)
{
// Zero memory after \0 until end of THIS log message
// Older log messages that are coming after are retained
// Older log messages can come after this log message due to the ring memory
char *offset = logs->memory + logs->pos * MAX_LOG_LENGTH;
bool ended = false;
for (uint32 i = 0; i < MAX_LOG_LENGTH; ++i) {
if (ended) {
*offset = 0;
++offset;
size_t length = strlen(str);
ASSERT_SIMPLE(length < MAX_LOG_LENGTH);
continue;
}
char* temp = (char *) ring_get_memory(logs, length + 1);
strcpy(temp, str);
temp[length] = '\0';
if (*offset == '\0') {
ended = true;
}
++offset;
}
++logs->pos;
// write log pool to file
if (logs->pos >= logs->count) {
if (fp != NULL) {
if (fp != NULL && logs->size - logs->pos < MAX_LOG_LENGTH) {
log_to_file(logs, fp);
}
// reset log position to start of memory pool
logs->pos = 0;
}
}
#if (LOG_LEVEL == 0)
// Don't perform any logging at log level 0
#define LOG(logs, fp)
#define LOG_TO_FILE(logs, fp)
#define LOG(logs, str, fp) ((void)0)
#define LOG_TO_FILE(logs, fp) ((void)0)
#else
#define LOG(logs, fp) log(logs, fp);
#define LOG(logs, str, fp) log(logs, str, fp);
#define LOG_TO_FILE(logs, fp) log_to_file(logs, fp);
#endif

View File

@ -10,33 +10,27 @@
#define TOS_UTILS_WINDOWS_H
#include <windows.h>
#include "Window.h"
#include "../../stdlib/Types.h"
struct Window {
bool is_fullscreen;
int32 width;
int32 height;
char name[32];
int32 x;
int32 y;
HWND hwnd;
};
#include "../../utils/TestUtils.h"
void window_create(Window* window, void* proc)
{
ASSERT_SIMPLE(proc);
WNDPROC wndproc = (WNDPROC) proc;
WNDCLASSEX wc = {};
WNDCLASSEXA wc = {};
HINSTANCE hinstance = GetModuleHandle(0);
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbSize = sizeof(WNDCLASSEXA);
wc.style = CS_OWNDC;
wc.lpfnWndProc = wndproc;
wc.hInstance = hinstance;
wc.lpszClassName = (LPCWSTR) window->name;
wc.lpszClassName = (LPCSTR) window->name;
RegisterClassEx(&wc);
if (!RegisterClassExA(&wc)) {
return;
}
if (window->is_fullscreen) {
window->width = GetSystemMetrics(SM_CXSCREEN);
@ -57,7 +51,7 @@ void window_create(Window* window, void* proc)
window->y = 0;
}
window->hwnd = CreateWindowEx((DWORD) NULL,
window->hwnd = CreateWindowExA((DWORD) NULL,
wc.lpszClassName, NULL,
WS_OVERLAPPEDWINDOW,
window->x, window->y,
@ -66,6 +60,10 @@ void window_create(Window* window, void* proc)
NULL, NULL, hinstance, window
);
window->hdc = GetDC(window->hwnd);
ASSERT_SIMPLE(window->hwnd);
//SetWindowLongA(window->hwnd, GWL_STYLE, 0);
}

28
platform/win32/Window.h Normal file
View File

@ -0,0 +1,28 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_UTILS_WINDOW_H
#define TOS_UTILS_WINDOW_H
#include <windows.h>
#include "../../stdlib/Types.h"
struct Window {
bool is_fullscreen;
int32 width;
int32 height;
char name[32];
int32 x;
int32 y;
HWND hwnd;
HDC hdc;
};
#endif

View File

@ -77,9 +77,6 @@ void audio_load(HWND hwnd, AudioSetting* setting, DirectSoundSetting* api_settin
return;
}
setting->buffer_size = setting->sample_rate * setting->sample_size;
setting->buffer = (int16 *) calloc(setting->sample_rate, setting->sample_size);
// Create secondary buffer
DSBUFFERDESC bufferDesc2;
ZeroMemory(&bufferDesc2, sizeof(DSBUFFERDESC));

223
stdlib/HashMap.h Normal file
View File

@ -0,0 +1,223 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_STDLIB_HASHMAP_H
#define TOS_STDLIB_HASHMAP_H
#include "../hash/GeneralHash.h"
#include "../memory/RingMemory.h"
#include "../memory/BufferMemory.h"
#include "../memory/ChunkMemory.h"
#include "Types.h"
#define MAX_KEY_LENGTH 32
struct HashEntryInt32 {
int64 element_id;
char key[MAX_KEY_LENGTH];
HashEntryInt32* next;
int value;
};
struct HashEntryInt64 {
int64 element_id;
char key[MAX_KEY_LENGTH];
HashEntryInt64* next;
int64 value;
};
struct HashEntryFloat {
int64 element_id;
char key[MAX_KEY_LENGTH];
HashEntryFloat* next;
float value;
};
struct HashEntryStr {
int64 element_id;
char key[MAX_KEY_LENGTH];
HashEntryStr* next;
char value[MAX_KEY_LENGTH];
};
struct HashEntry {
int64 element_id;
char key[MAX_KEY_LENGTH];
HashEntry* next;
byte* value;
};
struct HashMap {
void** table;
ChunkMemory buf;
};
// WARNING: element_size = element size + remaining HashEntry data size
void hashmap_create(HashMap* hm, int count, int element_size, RingMemory* ring)
{
hm->table = (void **) ring_get_memory(ring, count * sizeof(void *));
hm->buf.memory = ring_get_memory(ring, count * element_size);
hm->buf.free = (uint64 *) ring_get_memory(ring, CEIL_DIV(count, 64) * sizeof(hm->buf.free));
hm->buf.count = count;
hm->buf.chunk_size = element_size;
hm->buf.last_pos = -1;
hm->buf.alignment = 1;
}
void hashmap_create(HashMap* hm, int count, int element_size, BufferMemory* buf)
{
hm->table = (void **) buffer_get_memory(buf, count * sizeof(void *));
hm->buf.memory = buffer_get_memory(buf, count * element_size);
hm->buf.free = (uint64 *) buffer_get_memory(buf, CEIL_DIV(count, 64) * sizeof(hm->buf.free));
hm->buf.count = count;
hm->buf.chunk_size = element_size;
hm->buf.last_pos = -1;
hm->buf.alignment = 1;
}
inline
int64 hashmap_get_buffer_size(int count, int element_size)
{
return sizeof(void *) * count // table
+ count * element_size // elements
+ sizeof(uint64) * CEIL_DIV(count, 64); // free
}
void hashmap_create(HashMap* hm, int count, int element_size, byte* buf)
{
hm->table = (void **) buf;
hm->buf.memory = buf + sizeof(void *) * count;
hm->buf.free = (uint64 *) (hm->buf.memory + count * element_size);
hm->buf.count = count;
hm->buf.chunk_size = element_size;
hm->buf.last_pos = -1;
hm->buf.alignment = 1;
}
void hashmap_insert(HashMap* hm, const char* key, int32 value) {
uint64 index = hash_djb2(key) % hm->buf.count;
int64 element = chunk_reserve(&hm->buf, 1);
HashEntryInt32* entry = (HashEntryInt32 *) 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 = (HashEntryInt32 *) hm->table[index];
hm->table[index] = entry;
}
void hashmap_insert(HashMap* hm, const char* key, int64 value) {
uint64 index = hash_djb2(key) % hm->buf.count;
int64 element = chunk_reserve(&hm->buf, 1);
HashEntryInt64* entry = (HashEntryInt64 *) 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 = (HashEntryInt64 *) hm->table[index];
hm->table[index] = entry;
}
void hashmap_insert(HashMap* hm, const char* key, float value) {
uint64 index = hash_djb2(key) % hm->buf.count;
int64 element = chunk_reserve(&hm->buf, 1);
HashEntryFloat* entry = (HashEntryFloat *) 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 = (HashEntryFloat *) hm->table[index];
hm->table[index] = entry;
}
void hashmap_insert(HashMap* hm, const char* key, const char* value) {
uint64 index = hash_djb2(key) % hm->buf.count;
int64 element = chunk_reserve(&hm->buf, 1);
HashEntryStr* entry = (HashEntryStr *) 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';
strncpy(entry->value, value, MAX_KEY_LENGTH);
entry->value[MAX_KEY_LENGTH - 1] = '\0';
entry->next = (HashEntryStr *) hm->table[index];
hm->table[index] = entry;
}
void hashmap_insert(HashMap* hm, const char* key, byte* value) {
uint64 index = hash_djb2(key) % hm->buf.count;
int64 element = chunk_reserve(&hm->buf, 1);
HashEntry* entry = (HashEntry *) chunk_get_element(&hm->buf, element, true);
entry->element_id = element;
entry->value = (byte *) entry + sizeof(HashEntry);
strncpy(entry->key, key, MAX_KEY_LENGTH);
entry->key[MAX_KEY_LENGTH - 1] = '\0';
memcpy(entry->value, value, hm->buf.chunk_size - sizeof(HashEntry));
entry->next = (HashEntry *) hm->table[index];
hm->table[index] = entry;
}
void* hashmap_get_entry(HashMap* hm, const char* key) {
uint64 index = hash_djb2(key) % hm->buf.count;
HashEntry* entry = (HashEntry *) hm->table[index];
while (entry != NULL) {
if (strncmp(entry->key, key, MAX_KEY_LENGTH) == 0) {
return entry;
}
entry = (HashEntry *) entry->next;
}
return NULL;
}
void hashmap_delete_entry(HashMap* hm, const char* key) {
uint64 index = hash_djb2(key);
HashEntry* entry = (HashEntry *) hm->table[index];
HashEntry* prev = NULL;
while (entry != NULL) {
if (strncmp(entry->key, key, MAX_KEY_LENGTH) == 0) {
if (prev == NULL) {
hm->table[index] = entry->next;
} else {
prev->next = entry->next;
}
chunk_free_element(&hm->buf, entry->element_id);
return;
}
prev = entry;
entry = entry->next;
}
}
#endif

View File

@ -19,6 +19,7 @@
#include "Types.h"
/*
inline f32 sqrt(f32 a) { return _mm_cvtss_f32(_mm_sqrt_ss(_mm_set_ss(a))); }
inline f64 sqrt(f64 a)
{
@ -26,6 +27,7 @@ inline f64 sqrt(f64 a)
return _mm_cvtsd_f64(_mm_sqrt_sd(temp, temp));
}
*/
inline f32 rsqrt(f32 a) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(a))); }
inline f64 rsqrt(f64 a)

View File

@ -26,6 +26,10 @@ typedef float f32;
typedef double f64;
typedef unsigned char byte;
typedef char sbyte;
typedef uintptr_t umm;
typedef intptr_t smm;
#define KILOBYTE 1024
#define MEGABYTE 1048576

View File

@ -13,6 +13,7 @@
#include <xmmintrin.h>
#include "../Types.h"
#include "../../utils/BitUtils.h"
#include "SIMD_F32.h"
// @todo a lot of sse functions require high level (e.g. sse4.1) this needs to be changed to be more general
@ -1557,12 +1558,78 @@ void simd_add(const int32* a, const f32* b, int32* result, int size, int steps)
}
// WARNING: only works with SSE4.2
// WARNING: incl. \0 both strings must be <= 16
bool simd_str_compare(const char* str1, const char* str2) {
__m128i s1 = _mm_loadu_si128((const __m128i*) str1);
__m128i s2 = _mm_loadu_si128((const __m128i*) str2);
// WARNING: incl. \0 both strings must be <= 16 length
bool str_compare_avx512(const char* str1, const char* str2) {
__m128i s1 = _mm_loadu_si128((const __m128i *) str1);
__m128i s2 = _mm_loadu_si128((const __m128i *) str2);
return _mm_cmpistrc(s1, s2, _SIDD_UBYTE_OPS | _SIDD_CMP_EQUAL_EACH) == 0;
}
void
endian_swap(const int* val, int* result, int size, int steps)
{
int i = 0;
if (steps == 16) {
const __m512i mask_512 = _mm512_setr_epi8(
3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12,
19, 18, 17, 16, 23, 22, 21, 20, 27, 26, 25, 24, 31, 30, 29, 28,
35, 34, 33, 32, 39, 38, 37, 36, 43, 42, 41, 40, 47, 46, 45, 44,
51, 50, 49, 48, 55, 54, 53, 60, 59, 58, 57, 56, 64, 63, 62, 61
);
for (i = 0; i <= size - steps; i += steps) {
__m512i vec = _mm512_loadu_si512((const __m512i *) (val + i));
vec = _mm512_shuffle_epi8(vec, mask_512);
_mm512_storeu_si512((__m512i *) (result + i), vec);
}
} else if (steps == 8) {
const __m256i mask_256 = _mm256_setr_epi8(
3, 2, 1, 0, 7, 6, 5, 4,
11, 10, 9, 8, 15, 14, 13, 12,
19, 18, 17, 16, 23, 22, 21, 20,
27, 26, 25, 24, 31, 30, 29, 28
);
for (i = 0; i <= size - steps; i += steps) {
__m256i vec = _mm256_loadu_si256((const __m256i *) (val + i));
vec = _mm256_shuffle_epi8(vec, mask_256);
_mm256_storeu_si256((__m256i *) (result + i), vec);
}
} else if (steps == 4) {
const __m128i mask_128 = _mm_setr_epi8(
3, 2, 1, 0,
7, 6, 5, 4,
11, 10, 9, 8,
15, 14, 13, 12
);
for (i = 0; i <= size - steps; i += steps) {
__m128i vec = _mm_loadu_si128((const __m128i *) (val + i));
vec = _mm_shuffle_epi8(vec, mask_128);
_mm_storeu_si128((__m128i *) (result + i), vec);
}
}
for (; i < size; ++i) {
uint32 v = ((uint32 *) val)[i];
((int32 *) result)[i] = ((v << 24)
| ((v & 0xFF00) << 8)
| ((v >> 8) & 0xFF00)
| (v >> 24));
}
}
#if _WIN32 || __LITTLE_ENDIAN
#define SWAP_ENDIAN_LITTLE_SIMD(val, result, size, steps) ((void)0)
#define SWAP_ENDIAN_BIG_SIMD(val, result, size, steps) endian_swap((val), (result), (size), (steps))
#else
#define SWAP_ENDIAN_LITTLE_SIMD(val, result, size, steps) endian_swap((val), (result), (size), (steps))
#define SWAP_ENDIAN_BIG_SIMD(val, result, size, steps) ((void)0)
#endif
#endif

View File

@ -9,6 +9,7 @@
#ifndef TOS_UTILS_BIT_H
#define TOS_UTILS_BIT_H
#include <intrin.h>
#include "../stdlib/Types.h"
inline
@ -30,16 +31,44 @@ uint64 bytes_merge(
) {
uint64 result = 0;
result |= ((uint32) b0 << 56);
result |= ((uint32) b1 << 48);
result |= ((uint32) b2 << 40);
result |= ((uint32) b3 << 32);
result |= ((uint32) b4 << 24);
result |= ((uint32) b5 << 16);
result |= ((uint32) b6 << 8);
result |= (uint32) b3;
result |= ((uint64) b0 << 56);
result |= ((uint64) b1 << 48);
result |= ((uint64) b2 << 40);
result |= ((uint64) b3 << 32);
result |= ((uint64) b4 << 24);
result |= ((uint64) b5 << 16);
result |= ((uint64) b6 << 8);
result |= (uint64) b7;
return result;
}
static
inline int find_first_set_bit(int value) {
if (value == 0) {
return 0;
}
#if __GNUC__ || __clang__
return __builtin_ffs(value);
#elif _MSC_VER
unsigned long index; // For _BitScanForward, an unsigned long is expected
if (_BitScanForward(&index, value)) {
return (int)index + 1; // Convert to 1-based index
} else {
return 0; // No set bit found
}
#else
int index = 1; // Start at 1 for 1-based index
while (value) {
if (value & 1) {
return index;
}
value >>= 1; // Shift right to check the next bit
index++;
}
return 0; // No set bit found
#endif
}
#endif

View File

@ -1,34 +0,0 @@
/**
* Jingga
*
* @copyright Jingga
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
#ifndef TOS_UTILS_COMPILER_H
#define TOS_UTILS_COMPILER_H
#include <stdio.h>
#include <stdlib.h>
#ifdef _MSC_VER
#include <malloc.h>
inline
void* aligned_alloc(size_t alignment, size_t size) {
return _aligned_malloc(size, alignment);
}
inline
void aligned_free(void* ptr) {
_aligned_free(ptr);
}
#else
inline
void aligned_free(void* ptr) {
free(ptr);
}
#endif
#endif

View File

@ -23,14 +23,14 @@
wchar_t pipe_name[32];
wsprintfW(pipe_name, L"\\\\.\\pipe\\fastpipe%x", GetCurrentProcessId());
HANDLE fast_pip = CreateFileW(pipe_name, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
HANDLE fast_pip = CreateFileW(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
if(fast_pip != INVALID_HANDLE_VALUE) {
SetStdHandle(STD_OUTPUT_HANDLE, fast_pip);
SetStdHandle(STD_INPUT_HANDLE, fast_pip);
int std_out = _open_osfhandle((intptr_t) fast_pip, O_WRONLY|O_TEXT);
int std_in = _open_osfhandle((intptr_t) fast_pip, O_RDONLY|O_TEXT);
int std_out = _open_osfhandle((intptr_t) fast_pip, O_WRONLY | O_TEXT);
int std_in = _open_osfhandle((intptr_t) fast_pip, O_RDONLY | O_TEXT);
_dup2(std_out, _fileno(stdout));
_dup2(std_in, _fileno(stdin));

View File

@ -11,11 +11,12 @@
#define TOS_UTILS_MATH_UTILS_H
#include "../stdlib/Intrinsics.h"
#include <math.h>
#define OMS_PI 3.14159265358979323846f
#define OMS_PI_OVER_TWO OMS_PI / 2.0f
#define OMS_PI_OVER_FOUR OMS_PI / 4.0f
#define OMS_TWO_PI 2 * OMS_PI
#define OMS_PI_OVER_TWO (OMS_PI / 2.0f)
#define OMS_PI_OVER_FOUR (OMS_PI / 4.0f)
#define OMS_TWO_PI (2 * OMS_PI)
#define OMS_MAX(a, b) ((a) > (b) ? (a) : (b))
#define OMS_MIN(a, b) ((a) > (b) ? (b) : (a))
@ -24,6 +25,9 @@
#define OMS_DEG2RAD(angle) ((angle) * OMS_PI / 180.0f)
#define OMS_RAD2DEG(angle) ((angle) * 180.0f / OMS_PI)
#define ROUND_TO_NEAREST(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
#define CEIL_DIV(a, b) (((a) + (b) - 1) / (b))
#define SQRT_2 1.4142135623730950488016887242097f
// @question Consider to implement table based sine wave + approximation if necessary
// [-PI/2, PI/2]
@ -42,7 +46,7 @@ float sinf_approx(float x)
inline
float cosf_approx(float x)
{
return sinf_approx(x + OMS_PI_OVER_TWO);
return sinf_approx(x + OMS_RAD2DEG(OMS_PI_OVER_TWO));
}
inline
@ -103,7 +107,7 @@ float asinf_approx(float x)
result -= 0.2121144f;
result *= x;
result += 1.5707288f;
result *= sqrt(1.0f - x);
result *= sqrtf(1.0f - x);
result -= 2 * negate * result;
return negate * OMS_PI + result;

View File

@ -147,7 +147,21 @@ char* format_number(int number, char* buffer, const char thousands = ',')
return buffer;
}
void create_const_name(const unsigned char* name, unsigned char* modified_name)
char toupper_ascii(char c)
{
return c >= 'a' && c <= 'z'
? c & 0x5f
: c;
}
char tolower_ascii(char c)
{
return c >= 'A' && c <= 'Z'
? c | 0x20
: c;
}
void create_const_name(const unsigned char* name, char* modified_name)
{
// Print block
if (name == NULL) {
@ -156,7 +170,7 @@ void create_const_name(const unsigned char* name, unsigned char* modified_name)
size_t i;
const size_t length = strlen((const char* ) name);
for (i = 0; i < length; ++i) {
modified_name[i] = name[i] == ' ' ? '_' : (unsigned char) toupper(name[i]);
modified_name[i] = name[i] == ' ' ? '_' : toupper_ascii(name[i]);
}
modified_name[i] = '\0';
@ -202,4 +216,36 @@ bool str_ends_with(const char* str, const char* suffix) {
return strncmp(str + str_len - suffix_len, suffix, suffix_len) == 0;
}
// WARNING: result needs to have the correct length
void str_replace(const char* str, const char* search, const char* replace, char* result) {
if (str == NULL || search == NULL || replace == NULL || result == NULL) {
return;
}
size_t search_len = strlen(search);
size_t replace_len = strlen(replace);
if (search_len == 0) {
strcpy(result, str);
return;
}
const char* current = str;
char* result_ptr = result;
while ((current = strstr(current, search)) != NULL) {
size_t bytes_to_copy = current - str;
memcpy(result_ptr, str, bytes_to_copy);
result_ptr += bytes_to_copy;
memcpy(result_ptr, replace, replace_len);
result_ptr += replace_len;
current += search_len;
str = current;
}
strcpy(result_ptr, str);
}
#endif

View File

@ -425,6 +425,37 @@ unsigned int get_gpu_info(GpuInfo* info) {
return i;
}
struct DisplayInfo {
char name[64];
int width;
int height;
int hz;
};
unsigned int get_display_info(DisplayInfo* info) {
DISPLAY_DEVICE device;
DEVMODE mode;
device.cb = sizeof(DISPLAY_DEVICE);
int i = 0;
while (EnumDisplayDevices(NULL, i, &device, 0)) {
mode.dmSize = sizeof(mode);
if (EnumDisplaySettings(device.DeviceName, ENUM_CURRENT_SETTINGS, &mode)) {
strcpy(info[i].name, device.DeviceName);
info[i].width = mode.dmPelsWidth;
info[i].height = mode.dmPelsHeight;
info[i].hz = mode.dmDisplayFrequency;
}
++i;
}
return i;
}
struct SystemInfo {
OSInfo os;
MainboardInfo mainboard;
@ -437,6 +468,9 @@ struct SystemInfo {
GpuInfo gpu[2];
int gpu_count;
DisplayInfo display[6];
int display_count;
};
void render_system_info(char* buf, const SystemInfo* info) {
@ -487,9 +521,17 @@ void render_system_info(char* buf, const SystemInfo* info) {
"GPU:\n"
"==============\n"
"Name: %s\n" "VRAM: %d\n"
"\n"
"Name: %s\n" "VRAM: %d\n"
"\n"
"Display:\n"
"==============\n"
"Name: %s\n" "Width: %d\n" "Height: %d\n" "Hz: %d\n"
"Name: %s\n" "Width: %d\n" "Height: %d\n" "Hz: %d\n"
"Name: %s\n" "Width: %d\n" "Height: %d\n" "Hz: %d\n"
"Name: %s\n" "Width: %d\n" "Height: %d\n" "Hz: %d\n"
"Name: %s\n" "Width: %d\n" "Height: %d\n" "Hz: %d\n"
"Name: %s\n" "Width: %d\n" "Height: %d\n" "Hz: %d\n"
"\n"
"RAM:\n"
"==============\n"
"Memory: %d MB",
@ -507,6 +549,12 @@ void render_system_info(char* buf, const SystemInfo* info) {
info->cpu.simd.sse, info->cpu.simd.avx256, info->cpu.simd.avx512 > 0 ? avx512[info->cpu.simd.avx512 - 1] : "0",
info->gpu[0].name, info->gpu[0].vram,
info->gpu_count < 2 ? "" : info->gpu[1].name, info->gpu_count < 2 ? 0 : info->gpu[1].vram,
info->display[0].name, info->display[0].width, info->display[0].height, info->display[0].hz,
info->display_count < 2 ? "" : info->display[1].name, info->display_count < 2 ? 0 : info->display[1].width, info->display_count < 2 ? 0 : info->display[1].height, info->display_count < 2 ? 0 : info->display[1].hz,
info->display_count < 3 ? "" : info->display[2].name, info->display_count < 3 ? 0 : info->display[2].width, info->display_count < 3 ? 0 : info->display[2].height, info->display_count < 3 ? 0 : info->display[2].hz,
info->display_count < 4 ? "" : info->display[3].name, info->display_count < 4 ? 0 : info->display[3].width, info->display_count < 4 ? 0 : info->display[3].height, info->display_count < 4 ? 0 : info->display[3].hz,
info->display_count < 5 ? "" : info->display[4].name, info->display_count < 5 ? 0 : info->display[4].width, info->display_count < 5 ? 0 : info->display[4].height, info->display_count < 5 ? 0 : info->display[4].hz,
info->display_count < 6 ? "" : info->display[5].name, info->display_count < 6 ? 0 : info->display[5].width, info->display_count < 6 ? 0 : info->display[5].height, info->display_count < 6 ? 0 : info->display[5].hz,
info->ram.memory
);
}
@ -519,6 +567,7 @@ void get_system_info(SystemInfo* info)
get_cpu_info(&info->cpu);
get_ram_info(&info->ram);
info->gpu_count = get_gpu_info(info->gpu);
info->display_count = get_display_info(info->display);
}
#endif

View File

@ -29,14 +29,6 @@ struct TimingStat {
double delta_time;
};
struct LogPool {
char* memory;
uint32 pos;
uint32 count;
// uint32 size = count * MAX_LOG_LENGTH
};
// IMPORTANT: This function should only be called when you actually use this data
// e.g. log to display or file
inline

View File

@ -71,17 +71,37 @@ byte get_bits(byte data, int bits_to_read, int start_pos)
}
inline
uint32 get_bits(const byte* data, int bits_to_read, int start_pos)
uint64 get_bits(const byte* data, int bits_to_read, int start_pos)
{
if (bits_to_read <= 0 || bits_to_read > sizeof(uint64)) {
return 0;
}
int byte_index = start_pos / 8;
int bit_offset = start_pos % 8;
uint32_t mask = (1 << bits_to_read) - 1;
uint64_t mask = (1ULL << bits_to_read) - 1;
uint64_t result = 0;
uint32_t result = (data[byte_index] >> bit_offset);
int bits_read = 0;
if (bit_offset + bits_to_read > 8) {
result |= (data[byte_index + 1] << (8 - bit_offset));
while (bits_read < bits_to_read) {
int bits_in_current_byte = 8 - bit_offset;
int bits_to_take = bits_to_read - bits_read;
if (bits_to_take > bits_in_current_byte) {
bits_to_take = bits_in_current_byte;
}
uint8_t current_byte = data[byte_index];
current_byte >>= bit_offset;
current_byte &= (1 << bits_to_take) - 1;
result |= ((uint64_t)current_byte << bits_read);
bits_read += bits_to_take;
bit_offset = 0;
byte_index++;
}
result &= mask;