mirror of
https://github.com/Karaka-Management/cOMS.git
synced 2026-01-11 03:08:41 +00:00
rotating cubes
This commit is contained in:
parent
7f1a35d61a
commit
8335444c03
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
ASSERT_SIMPLE(free_asset >= 0);
|
||||
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?
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
738
gpuapi/opengl/Opengl.h
Normal 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
|
||||
23
gpuapi/opengl/OpenglLinux.h
Normal file
23
gpuapi/opengl/OpenglLinux.h
Normal 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
511
gpuapi/opengl/OpenglUtils.h
Normal 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
342
gpuapi/opengl/OpenglWin32.h
Normal 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
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
108
hash/GeneralHash.h
Normal 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
|
||||
|
|
@ -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)));
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
32
image/Png.h
32
image/Png.h
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,101 +184,99 @@ 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)
|
||||
{
|
||||
// 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];
|
||||
result[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14];
|
||||
result[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15];
|
||||
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]);
|
||||
|
||||
// Row 1
|
||||
result[4] = a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12];
|
||||
result[5] = a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13];
|
||||
result[6] = a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14];
|
||||
result[7] = a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15];
|
||||
// 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]);
|
||||
|
||||
// Row 2
|
||||
result[8] = a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12];
|
||||
result[9] = a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13];
|
||||
result[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14];
|
||||
result[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15];
|
||||
_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)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
// Row 3
|
||||
result[12] = a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12];
|
||||
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];
|
||||
}
|
||||
_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)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
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]);
|
||||
_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)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
__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);
|
||||
_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];
|
||||
result[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14];
|
||||
result[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15];
|
||||
|
||||
__m128 dot;
|
||||
// Row 1
|
||||
result[4] = a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12];
|
||||
result[5] = a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13];
|
||||
result[6] = a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14];
|
||||
result[7] = a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15];
|
||||
|
||||
// b1
|
||||
dot = _mm_dp_ps(a_1, b_1, 0xF1);
|
||||
result[0] = _mm_cvtss(dot);
|
||||
// Row 2
|
||||
result[8] = a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12];
|
||||
result[9] = a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13];
|
||||
result[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14];
|
||||
result[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15];
|
||||
|
||||
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);
|
||||
// Row 3
|
||||
result[12] = a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12];
|
||||
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 __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
113
memory/Allocation.h
Normal 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
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
1
models/mob/skill/definitions/fear.cfg
Normal file
1
models/mob/skill/definitions/fear.cfg
Normal file
|
|
@ -0,0 +1 @@
|
|||
# makes feared run from caster/target?
|
||||
|
|
@ -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
15
noise/FractalNoise.h
Normal 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
221
noise/SimplexNoise.h
Normal 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
111
noise/ValueNoise.h
Normal 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
117
noise/WorleyNoise.h
Normal 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
48
object/Animation.h
Normal 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
20
object/FaceType.h
Normal 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
44
object/Hitbox.h
Normal 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
44
object/Material.h
Normal 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
26
object/Materials.md
Normal 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
82
object/Mesh.h
Normal 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
943
object/Object.h
Normal 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
|
||||
|
|
@ -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
43
object/Vertex.h
Normal 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
19
particle/Particle.h
Normal 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
69
pathfinding/Metric2d.h
Normal 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
90
pathfinding/Metric3d.h
Normal 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
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
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
|
||||
);
|
||||
} 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,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
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
|
||||
);
|
||||
} 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,
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
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
|
||||
);
|
||||
} 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,
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
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
|
||||
);
|
||||
} 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,
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
HANDLE fp;
|
||||
if (*path == '.') {
|
||||
char full_path[MAX_PATH];
|
||||
relative_to_absolute(path, full_path);
|
||||
|
||||
if (fp == INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
fp = CreateFileA((LPCSTR) full_path,
|
||||
GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
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,
|
||||
FILE_APPEND_DATA,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
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
|
||||
);
|
||||
} 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,
|
||||
FILE_APPEND_DATA,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
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
|
||||
);
|
||||
} 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,
|
||||
FILE_APPEND_DATA,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
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
|
||||
);
|
||||
} 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) {
|
||||
log_to_file(logs, fp);
|
||||
}
|
||||
|
||||
// reset log position to start of memory pool
|
||||
logs->pos = 0;
|
||||
if (fp != NULL && logs->size - logs->pos < MAX_LOG_LENGTH) {
|
||||
log_to_file(logs, fp);
|
||||
}
|
||||
}
|
||||
|
||||
#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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
28
platform/win32/Window.h
Normal 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
|
||||
|
|
@ -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
223
stdlib/HashMap.h
Normal 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
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ char* format_number(size_t number, char* buffer, const char thousands = ',')
|
|||
return buffer;
|
||||
}
|
||||
|
||||
char* format_number(int number, char* buffer, const char thousands = ',')
|
||||
char* format_number(int number, char* buffer, const char thousands = ',')
|
||||
{
|
||||
int length = snprintf(buffer, 32, "%i", number);
|
||||
format_number_render(length, buffer, thousands);
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user