Merge branch 'raysan5:master' into master
This commit is contained in:
commit
e30fa528a3
10
BINDINGS.md
10
BINDINGS.md
|
|
@ -6,7 +6,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
|
||||
| name | raylib version | language | license | repo |
|
||||
|:------------------:|:---------------:|:---------:|:----------:|-----------------------------------------------------------|
|
||||
| raylib | **4.0** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib | https://github.com/raysan5/raylib |
|
||||
| raylib | **4.2** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib | https://github.com/raysan5/raylib |
|
||||
| raylib-boo | 3.7 | [Boo](http://boo-language.github.io/)| MIT | https://github.com/Rabios/raylib-boo |
|
||||
| Raylib-cs | **4.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | Zlib | https://github.com/ChrisDill/Raylib-cs |
|
||||
| Raylib-CsLo | **4.0** | [C#](https://en.wikipedia.org/wiki/C_Sharp_(programming_language)) | MPL-2.0 | https://github.com/NotNotTech/Raylib-CsLo |
|
||||
|
|
@ -15,7 +15,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| dart-raylib | **4.0** | [Dart](https://dart.dev/) | MIT | https://gitlab.com/wolfenrain/dart-raylib |
|
||||
| bindbc-raylib3 | **4.0** | [D](https://dlang.org/) | BSL-1.0 | https://github.com/o3o/bindbc-raylib3 |
|
||||
| dray | **4.0** | [D](https://dlang.org/) | Apache-2.0 | https://github.com/xdrie/dray |
|
||||
| raylib-d | **4.0** | [D](https://dlang.org/) | Zlib | https://github.com/schveiguy/raylib-d |
|
||||
| raylib-d | **4.2** | [D](https://dlang.org/) | Zlib | https://github.com/schveiguy/raylib-d |
|
||||
| dlang_raylib | **4.0** | [D](https://dlang.org) | MPL-2.0 |https://github.com/rc-05/dlang_raylib |
|
||||
| rayex | 3.7 | [elixir](https://elixir-lang.org/) | Apache-2.0 | https://github.com/shiryel/rayex |
|
||||
| raylib-factor | **4.0** | [Factor](https://factorcode.org/) | BSD | https://github.com/factor/factor/blob/master/extra/raylib/raylib.factor |
|
||||
|
|
@ -29,7 +29,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| raylib-j | **4.0** | [Java](https://en.wikipedia.org/wiki/Java_(programming_language)) | Zlib | https://github.com/CreedVI/Raylib-J |
|
||||
| raylib.jl | **4.2** | [Julia](https://julialang.org/) | Zlib | https://github.com/irishgreencitrus/raylib.jl |
|
||||
| kaylib | 3.7 | [Kotlin/native](https://kotlinlang.org) | ? | https://github.com/electronstudio/kaylib |
|
||||
| raylib-lua | **4.0** | [Lua](http://www.lua.org/) | ISC | https://github.com/TSnake41/raylib-lua |
|
||||
| raylib-lua | **4.2** | [Lua](http://www.lua.org/) | ISC | https://github.com/TSnake41/raylib-lua |
|
||||
| raylua | **4.0** | [Lua](http://www.lua.org/) | MIT | https://github.com/Rabios/raylua |
|
||||
| nelua-raylib | 4.0 | [nelua](https://nelua.io/) | MIT | https://github.com/AKDev21/nelua-raylib |
|
||||
| NimraylibNow! | 4.2 | [Nim](https://nim-lang.org/) | MIT | https://github.com/greenfork/nimraylib_now |
|
||||
|
|
@ -39,7 +39,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| raylib_odin_bindings | 4.0-dev | [Odin](https://odin-lang.org/) | MIT | https://github.com/Deathbat2190/raylib_odin_bindings |
|
||||
| raylib-odin | **4.0** | [Odin](https://odin-lang.org/) | BSD-3Clause | https://github.com/odin-lang/Odin/tree/master/vendor/raylib |
|
||||
| raylib-ocaml | **4.0** | [OCaml](https://ocaml.org/) | MIT | https://github.com/tjammer/raylib-ocaml |
|
||||
| Ray4Laz | **4.2** | [Pascal](https://en.wikipedia.org/wiki/Pascal_(programming_language))| Zlib | https://github.com/GuvaCode/Ray4Laz |
|
||||
| Ray4Laz | **4.2** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)| Zlib | https://github.com/GuvaCode/Ray4Laz |
|
||||
| Raylib.4.0.Pascal | **4.0** | [Free Pascal](https://en.wikipedia.org/wiki/Free_Pascal)| Zlib | https://github.com/sysrpl/Raylib.4.0.Pascal |
|
||||
| pyraylib | 3.7 | [Python](https://www.python.org/) | Zlib | https://github.com/Ho011/pyraylib |
|
||||
| raylib-python-cffi | **4.2** | [Python](https://www.python.org/) | EPL-2.0 | https://github.com/electronstudio/raylib-python-cffi |
|
||||
|
|
@ -54,7 +54,7 @@ Some people ported raylib to other languages in form of bindings or wrappers to
|
|||
| raylib-smallBasic | 4.1-dev | [SmallBASIC](https://github.com/smallbasic/SmallBASIC) | GPLv3 | https://github.com/smallbasic/smallbasic.plugins/tree/master/raylib |
|
||||
| raylib.v | **4.2** | [V](https://vlang.io/) | Zlib | https://github.com/irishgreencitrus/raylib.v |
|
||||
| raylib-wren | **4.0** | [Wren](http://wren.io/) | ISC | https://github.com/TSnake41/raylib-wren |
|
||||
| raylib-zig | **4.0** | [Zig](https://ziglang.org/) | MIT | https://github.com/Not-Nik/raylib-zig |
|
||||
| raylib-zig | **4.2** | [Zig](https://ziglang.org/) | MIT | https://github.com/Not-Nik/raylib-zig |
|
||||
| raylib.zig | **4.2** | [Zig](https://ziglang.org/) | MIT | https://github.com/ryupold/raylib.zig |
|
||||
| hare-raylib | auto | [Hare](https://harelang.org/) | Zlib | https://git.sr.ht/~evantj/hare-raylib |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [cpre] example - loading thread
|
||||
* raylib [core] example - loading thread
|
||||
*
|
||||
* NOTE: This example requires linking with pthreads library on MinGW,
|
||||
* it can be accomplished passing -static parameter to compiler
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ int main(void)
|
|||
Model cube = LoadModelFromMesh(GenMeshCube(2.0f, 4.0f, 2.0f));
|
||||
|
||||
// Load basic lighting shader
|
||||
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/base_lighting.vs", GLSL_VERSION),
|
||||
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/lighting.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/lighting.fs", GLSL_VERSION));
|
||||
// Get some required shader locations
|
||||
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ int main(void)
|
|||
modelC.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture;
|
||||
|
||||
// Load shader and set up some uniforms
|
||||
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/base_lighting.vs", GLSL_VERSION),
|
||||
Shader shader = LoadShader(TextFormat("resources/shaders/glsl%i/lighting.vs", GLSL_VERSION),
|
||||
TextFormat("resources/shaders/glsl%i/fog.fs", GLSL_VERSION));
|
||||
shader.locs[SHADER_LOC_MATRIX_MODEL] = GetShaderLocation(shader, "matModel");
|
||||
shader.locs[SHADER_LOC_VECTOR_VIEW] = GetShaderLocation(shader, "viewPos");
|
||||
|
|
|
|||
|
|
@ -57,6 +57,10 @@ int main(void)
|
|||
|
||||
bool showFontAtlas = false;
|
||||
|
||||
int codepointSize = 0;
|
||||
int codepoint = 0;
|
||||
char *ptr = text;
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -66,6 +70,20 @@ int main(void)
|
|||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyPressed(KEY_SPACE)) showFontAtlas = !showFontAtlas;
|
||||
|
||||
// Testing code: getting next and previous codepoints on provided text
|
||||
if (IsKeyPressed(KEY_RIGHT))
|
||||
{
|
||||
// Get next codepoint in string and move pointer
|
||||
codepoint = GetCodepointNext(ptr, &codepointSize);
|
||||
ptr += codepointSize;
|
||||
}
|
||||
else if (IsKeyPressed(KEY_LEFT))
|
||||
{
|
||||
// Get previous codepoint in string and move pointer
|
||||
codepoint = GetCodepointPrevious(ptr, &codepointSize);
|
||||
ptr -= codepointSize;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ int main(void)
|
|||
|
||||
// Draw on the image with a few image draw methods
|
||||
ImageDrawPixel(&parrots, 10, 10, RAYWHITE);
|
||||
ImageDrawCircle(&parrots, 10, 10, 5, RAYWHITE);
|
||||
ImageDrawCircleLines(&parrots, 10, 10, 5, RAYWHITE);
|
||||
ImageDrawRectangle(&parrots, 5, 20, 10, 10, RAYWHITE);
|
||||
|
||||
UnloadImage(cat); // Unload image from RAM
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@ project(example)
|
|||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
# Dependencies
|
||||
find_package(raylib 4.2.0 QUIET) # QUIET or REQUIRED
|
||||
set(RAYLIB_VERSION 4.2.0)
|
||||
find_package(raylib ${RAYLIB_VERSION} QUIET) # QUIET or REQUIRED
|
||||
if (NOT raylib_FOUND) # If there's none, fetch and build raylib
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
raylib
|
||||
URL https://github.com/raysan5/raylib/archive/refs/tags/4.0.0.tar.gz
|
||||
URL https://github.com/raysan5/raylib/archive/refs/tags/${RAYLIB_VERSION}.tar.gz
|
||||
)
|
||||
FetchContent_GetProperties(raylib)
|
||||
if (NOT raylib_POPULATED) # Have we downloaded raylib yet?
|
||||
|
|
|
|||
170
src/external/glad.h
vendored
170
src/external/glad.h
vendored
|
|
@ -1,9 +1,9 @@
|
|||
/**
|
||||
* Loader generated by glad 2.0.0-beta on Sun Oct 17 18:39:09 2021
|
||||
* Loader generated by glad 2.0.0-beta on Sun Sep 18 18:12:12 2022
|
||||
*
|
||||
* Generator: C/C++
|
||||
* Specification: gl
|
||||
* Extensions: 110
|
||||
* Extensions: 116
|
||||
*
|
||||
* APIs:
|
||||
* - gl:core=4.3
|
||||
|
|
@ -12,16 +12,16 @@
|
|||
* - ALIAS = False
|
||||
* - DEBUG = False
|
||||
* - HEADER_ONLY = True
|
||||
* - LOADER = True
|
||||
* - LOADER = False
|
||||
* - MX = False
|
||||
* - MX_GLOBAL = False
|
||||
* - ON_DEMAND = False
|
||||
*
|
||||
* Commandline:
|
||||
* --api='gl:core=4.3' --extensions='GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_map_buffer_range,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_pipeline_statistics_query,GL_ARB_query_buffer_object,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_texture_lod,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_spirv_extensions,GL_ARB_tessellation_shader,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_compression,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_rg,GL_ARB_texture_storage,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_OES_compressed_paletted_texture,GL_OES_fixed_point' c --header-only --loader
|
||||
* --api='gl:core=4.3' --extensions='GL_ARB_ES2_compatibility,GL_ARB_ES3_1_compatibility,GL_ARB_ES3_2_compatibility,GL_ARB_ES3_compatibility,GL_ARB_blend_func_extended,GL_ARB_buffer_storage,GL_ARB_clear_buffer_object,GL_ARB_clear_texture,GL_ARB_color_buffer_float,GL_ARB_compatibility,GL_ARB_compressed_texture_pixel_storage,GL_ARB_compute_shader,GL_ARB_compute_variable_group_size,GL_ARB_copy_buffer,GL_ARB_copy_image,GL_ARB_debug_output,GL_ARB_depth_buffer_float,GL_ARB_depth_clamp,GL_ARB_depth_texture,GL_ARB_direct_state_access,GL_ARB_draw_buffers,GL_ARB_draw_buffers_blend,GL_ARB_draw_elements_base_vertex,GL_ARB_draw_indirect,GL_ARB_draw_instanced,GL_ARB_enhanced_layouts,GL_ARB_explicit_attrib_location,GL_ARB_explicit_uniform_location,GL_ARB_fragment_coord_conventions,GL_ARB_fragment_layer_viewport,GL_ARB_fragment_program,GL_ARB_fragment_program_shadow,GL_ARB_fragment_shader,GL_ARB_fragment_shader_interlock,GL_ARB_framebuffer_no_attachments,GL_ARB_framebuffer_object,GL_ARB_framebuffer_sRGB,GL_ARB_geometry_shader4,GL_ARB_get_program_binary,GL_ARB_get_texture_sub_image,GL_ARB_gl_spirv,GL_ARB_gpu_shader5,GL_ARB_gpu_shader_fp64,GL_ARB_gpu_shader_int64,GL_ARB_half_float_pixel,GL_ARB_half_float_vertex,GL_ARB_instanced_arrays,GL_ARB_internalformat_query,GL_ARB_internalformat_query2,GL_ARB_map_buffer_range,GL_ARB_multi_bind,GL_ARB_multi_draw_indirect,GL_ARB_multisample,GL_ARB_multitexture,GL_ARB_occlusion_query,GL_ARB_occlusion_query2,GL_ARB_pipeline_statistics_query,GL_ARB_query_buffer_object,GL_ARB_sample_locations,GL_ARB_sample_shading,GL_ARB_seamless_cube_map,GL_ARB_seamless_cubemap_per_texture,GL_ARB_shader_atomic_counter_ops,GL_ARB_shader_atomic_counters,GL_ARB_shader_bit_encoding,GL_ARB_shader_clock,GL_ARB_shader_image_load_store,GL_ARB_shader_image_size,GL_ARB_shader_objects,GL_ARB_shader_storage_buffer_object,GL_ARB_shader_texture_lod,GL_ARB_shading_language_100,GL_ARB_shading_language_420pack,GL_ARB_shading_language_include,GL_ARB_shading_language_packing,GL_ARB_spirv_extensions,GL_ARB_tessellation_shader,GL_ARB_texture_border_clamp,GL_ARB_texture_buffer_object_rgb32,GL_ARB_texture_compression,GL_ARB_texture_cube_map,GL_ARB_texture_cube_map_array,GL_ARB_texture_env_add,GL_ARB_texture_filter_anisotropic,GL_ARB_texture_filter_minmax,GL_ARB_texture_float,GL_ARB_texture_mirror_clamp_to_edge,GL_ARB_texture_mirrored_repeat,GL_ARB_texture_multisample,GL_ARB_texture_non_power_of_two,GL_ARB_texture_rg,GL_ARB_texture_storage,GL_ARB_texture_swizzle,GL_ARB_texture_view,GL_ARB_timer_query,GL_ARB_transpose_matrix,GL_ARB_uniform_buffer_object,GL_ARB_vertex_array_bgra,GL_ARB_vertex_array_object,GL_ARB_vertex_attrib_binding,GL_ARB_vertex_buffer_object,GL_ARB_vertex_program,GL_ARB_vertex_shader,GL_EXT_draw_instanced,GL_EXT_fog_coord,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object,GL_EXT_framebuffer_sRGB,GL_EXT_texture_compression_s3tc,GL_EXT_texture_filter_anisotropic,GL_EXT_texture_mirror_clamp,GL_KHR_texture_compression_astc_hdr,GL_KHR_texture_compression_astc_ldr,GL_OES_compressed_paletted_texture,GL_OES_fixed_point' c --header-only
|
||||
*
|
||||
* Online:
|
||||
* http://glad.sh/#api=gl%3Acore%3D4.3&generator=c&options=HEADER_ONLY%2CLOADER
|
||||
* http://glad.sh/#api=gl%3Acore%3D4.3&generator=c&options=HEADER_ONLY
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -54,7 +54,6 @@
|
|||
|
||||
#define GLAD_GL
|
||||
#define GLAD_OPTION_GL_HEADER_ONLY
|
||||
#define GLAD_OPTION_GL_LOADER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -381,11 +380,25 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||
#define GL_COMPRESSED_RGBA 0x84EE
|
||||
#define GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
|
||||
#define GL_COMPRESSED_RGBA_ARB 0x84EE
|
||||
#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
|
||||
#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
|
||||
#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
|
||||
#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
|
||||
#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
|
||||
#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
|
||||
#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
|
||||
#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
|
||||
#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
|
||||
#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
|
||||
#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
|
||||
#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
|
||||
#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
|
||||
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
|
||||
#define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C
|
||||
#define GL_COMPRESSED_RGB_ARB 0x84ED
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
||||
#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
||||
#define GL_COMPRESSED_RGB_ARB 0x84ED
|
||||
#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E
|
||||
#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F
|
||||
#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
||||
|
|
@ -395,6 +408,20 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||
#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
|
||||
#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE
|
||||
#define GL_COMPRESSED_SRGB 0x8C48
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC 0x9279
|
||||
#define GL_COMPRESSED_SRGB8_ETC2 0x9275
|
||||
#define GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2 0x9277
|
||||
|
|
@ -1067,6 +1094,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||
#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872
|
||||
#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD
|
||||
#define GL_MAX_TEXTURE_MAX_ANISOTROPY 0x84FF
|
||||
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF
|
||||
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||
#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
|
||||
#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70
|
||||
|
|
@ -1113,7 +1141,10 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||
#define GL_MIPMAP 0x8293
|
||||
#define GL_MIRRORED_REPEAT 0x8370
|
||||
#define GL_MIRRORED_REPEAT_ARB 0x8370
|
||||
#define GL_MIRROR_CLAMP_EXT 0x8742
|
||||
#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912
|
||||
#define GL_MIRROR_CLAMP_TO_EDGE 0x8743
|
||||
#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743
|
||||
#define GL_MULTISAMPLE 0x809D
|
||||
#define GL_MULTISAMPLE_ARB 0x809D
|
||||
#define GL_MULTISAMPLE_BIT_ARB 0x20000000
|
||||
|
|
@ -1749,6 +1780,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro
|
|||
#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY 0x84FE
|
||||
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
|
||||
#define GL_TEXTURE_MAX_LEVEL 0x813D
|
||||
#define GL_TEXTURE_MAX_LOD 0x813B
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
|
|
@ -2159,6 +2191,20 @@ typedef int64_t khronos_int64_t;
|
|||
typedef uint64_t khronos_uint64_t;
|
||||
#define KHRONOS_SUPPORT_INT64 1
|
||||
#define KHRONOS_SUPPORT_FLOAT 1
|
||||
/*
|
||||
* To support platform where unsigned long cannot be used interchangeably with
|
||||
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
|
||||
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
|
||||
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
|
||||
* unsigned long long or similar (this results in different C++ name mangling).
|
||||
* To avoid changes for existing platforms, we restrict usage of intptr_t to
|
||||
* platforms where the size of a pointer is larger than the size of long.
|
||||
*/
|
||||
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
|
||||
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
|
||||
#define KHRONOS_USE_INTPTR_T
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#elif defined(__VMS ) || defined(__sgi)
|
||||
|
||||
|
|
@ -2241,14 +2287,21 @@ typedef unsigned short int khronos_uint16_t;
|
|||
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||
* to be the only LLP64 architecture in current use.
|
||||
*/
|
||||
#ifdef _WIN64
|
||||
#ifdef KHRONOS_USE_INTPTR_T
|
||||
typedef intptr_t khronos_intptr_t;
|
||||
typedef uintptr_t khronos_uintptr_t;
|
||||
#elif defined(_WIN64)
|
||||
typedef signed long long int khronos_intptr_t;
|
||||
typedef unsigned long long int khronos_uintptr_t;
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_intptr_t;
|
||||
typedef unsigned long int khronos_uintptr_t;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
typedef signed long long int khronos_ssize_t;
|
||||
typedef unsigned long long int khronos_usize_t;
|
||||
#else
|
||||
typedef signed long int khronos_ssize_t;
|
||||
typedef unsigned long int khronos_usize_t;
|
||||
#endif
|
||||
|
|
@ -2294,113 +2347,70 @@ typedef enum {
|
|||
} khronos_boolean_enum_t;
|
||||
|
||||
#endif /* __khrplatform_h_ */
|
||||
|
||||
typedef unsigned int GLenum;
|
||||
|
||||
typedef unsigned char GLboolean;
|
||||
|
||||
typedef unsigned int GLbitfield;
|
||||
|
||||
typedef void GLvoid;
|
||||
|
||||
typedef khronos_int8_t GLbyte;
|
||||
|
||||
typedef khronos_uint8_t GLubyte;
|
||||
|
||||
typedef khronos_int16_t GLshort;
|
||||
|
||||
typedef khronos_uint16_t GLushort;
|
||||
|
||||
typedef int GLint;
|
||||
|
||||
typedef unsigned int GLuint;
|
||||
|
||||
typedef khronos_int32_t GLclampx;
|
||||
|
||||
typedef int GLsizei;
|
||||
|
||||
typedef khronos_float_t GLfloat;
|
||||
|
||||
typedef khronos_float_t GLclampf;
|
||||
|
||||
typedef double GLdouble;
|
||||
|
||||
typedef double GLclampd;
|
||||
|
||||
typedef void *GLeglClientBufferEXT;
|
||||
|
||||
typedef void *GLeglImageOES;
|
||||
|
||||
typedef char GLchar;
|
||||
|
||||
typedef char GLcharARB;
|
||||
|
||||
#ifdef __APPLE__
|
||||
typedef void *GLhandleARB;
|
||||
#else
|
||||
typedef unsigned int GLhandleARB;
|
||||
#endif
|
||||
|
||||
typedef khronos_uint16_t GLhalf;
|
||||
|
||||
typedef khronos_uint16_t GLhalfARB;
|
||||
|
||||
typedef khronos_int32_t GLfixed;
|
||||
|
||||
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
|
||||
typedef khronos_intptr_t GLintptr;
|
||||
#else
|
||||
typedef khronos_intptr_t GLintptr;
|
||||
#endif
|
||||
|
||||
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
|
||||
typedef khronos_intptr_t GLintptrARB;
|
||||
#else
|
||||
typedef khronos_intptr_t GLintptrARB;
|
||||
#endif
|
||||
|
||||
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
|
||||
typedef khronos_ssize_t GLsizeiptr;
|
||||
#else
|
||||
typedef khronos_ssize_t GLsizeiptr;
|
||||
#endif
|
||||
|
||||
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060)
|
||||
typedef khronos_ssize_t GLsizeiptrARB;
|
||||
#else
|
||||
typedef khronos_ssize_t GLsizeiptrARB;
|
||||
#endif
|
||||
|
||||
typedef khronos_int64_t GLint64;
|
||||
|
||||
typedef khronos_int64_t GLint64EXT;
|
||||
|
||||
typedef khronos_uint64_t GLuint64;
|
||||
|
||||
typedef khronos_uint64_t GLuint64EXT;
|
||||
|
||||
typedef struct __GLsync *GLsync;
|
||||
|
||||
struct _cl_context;
|
||||
|
||||
struct _cl_event;
|
||||
|
||||
typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
|
||||
|
||||
typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
|
||||
|
||||
typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
|
||||
|
||||
typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
|
||||
|
||||
typedef unsigned short GLhalfNV;
|
||||
|
||||
typedef GLintptr GLvdpauSurfaceNV;
|
||||
|
||||
typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void);
|
||||
|
||||
|
||||
|
||||
#define GL_VERSION_1_0 1
|
||||
GLAD_API_CALL int GLAD_GL_VERSION_1_0;
|
||||
#define GL_VERSION_1_1 1
|
||||
|
|
@ -2593,8 +2603,6 @@ GLAD_API_CALL int GLAD_GL_ARB_texture_border_clamp;
|
|||
GLAD_API_CALL int GLAD_GL_ARB_texture_buffer_object_rgb32;
|
||||
#define GL_ARB_texture_compression 1
|
||||
GLAD_API_CALL int GLAD_GL_ARB_texture_compression;
|
||||
#define GL_EXT_texture_compression_s3tc 1
|
||||
GLAD_API_CALL int GLAD_GL_EXT_texture_compression_s3tc;
|
||||
#define GL_ARB_texture_cube_map 1
|
||||
GLAD_API_CALL int GLAD_GL_ARB_texture_cube_map;
|
||||
#define GL_ARB_texture_cube_map_array 1
|
||||
|
|
@ -2641,6 +2649,8 @@ GLAD_API_CALL int GLAD_GL_ARB_vertex_buffer_object;
|
|||
GLAD_API_CALL int GLAD_GL_ARB_vertex_program;
|
||||
#define GL_ARB_vertex_shader 1
|
||||
GLAD_API_CALL int GLAD_GL_ARB_vertex_shader;
|
||||
#define GL_EXT_draw_instanced 1
|
||||
GLAD_API_CALL int GLAD_GL_EXT_draw_instanced;
|
||||
#define GL_EXT_fog_coord 1
|
||||
GLAD_API_CALL int GLAD_GL_EXT_fog_coord;
|
||||
#define GL_EXT_framebuffer_blit 1
|
||||
|
|
@ -2651,6 +2661,16 @@ GLAD_API_CALL int GLAD_GL_EXT_framebuffer_multisample;
|
|||
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_object;
|
||||
#define GL_EXT_framebuffer_sRGB 1
|
||||
GLAD_API_CALL int GLAD_GL_EXT_framebuffer_sRGB;
|
||||
#define GL_EXT_texture_compression_s3tc 1
|
||||
GLAD_API_CALL int GLAD_GL_EXT_texture_compression_s3tc;
|
||||
#define GL_EXT_texture_filter_anisotropic 1
|
||||
GLAD_API_CALL int GLAD_GL_EXT_texture_filter_anisotropic;
|
||||
#define GL_EXT_texture_mirror_clamp 1
|
||||
GLAD_API_CALL int GLAD_GL_EXT_texture_mirror_clamp;
|
||||
#define GL_KHR_texture_compression_astc_hdr 1
|
||||
GLAD_API_CALL int GLAD_GL_KHR_texture_compression_astc_hdr;
|
||||
#define GL_KHR_texture_compression_astc_ldr 1
|
||||
GLAD_API_CALL int GLAD_GL_KHR_texture_compression_astc_ldr;
|
||||
#define GL_OES_compressed_paletted_texture 1
|
||||
GLAD_API_CALL int GLAD_GL_OES_compressed_paletted_texture;
|
||||
#define GL_OES_fixed_point 1
|
||||
|
|
@ -2848,6 +2868,7 @@ typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINDIRECTPROC)(GLenum mode, const void
|
|||
typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDARBPROC)(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDEXTPROC)(GLenum mode, GLint start, GLsizei count, GLsizei primcount);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERPROC)(GLenum buf);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSARBPROC)(GLsizei n, const GLenum * bufs);
|
||||
|
|
@ -2859,6 +2880,7 @@ typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDARBPROC)(GLenum mode, GLsi
|
|||
typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDEXTPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei primcount);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex);
|
||||
typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKPROC)(GLenum mode, GLuint id);
|
||||
|
|
@ -4045,6 +4067,8 @@ GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB;
|
|||
#define glDrawArraysInstancedARB glad_glDrawArraysInstancedARB
|
||||
GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance;
|
||||
#define glDrawArraysInstancedBaseInstance glad_glDrawArraysInstancedBaseInstance
|
||||
GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT;
|
||||
#define glDrawArraysInstancedEXT glad_glDrawArraysInstancedEXT
|
||||
GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer;
|
||||
#define glDrawBuffer glad_glDrawBuffer
|
||||
GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers;
|
||||
|
|
@ -4067,6 +4091,8 @@ GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstan
|
|||
#define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex
|
||||
GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance;
|
||||
#define glDrawElementsInstancedBaseVertexBaseInstance glad_glDrawElementsInstancedBaseVertexBaseInstance
|
||||
GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT;
|
||||
#define glDrawElementsInstancedEXT glad_glDrawElementsInstancedEXT
|
||||
GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements;
|
||||
#define glDrawRangeElements glad_glDrawRangeElements
|
||||
GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex;
|
||||
|
|
@ -5682,12 +5708,6 @@ GLAD_API_CALL int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr);
|
|||
GLAD_API_CALL int gladLoadGL( GLADloadfunc load);
|
||||
|
||||
|
||||
#ifdef GLAD_GL
|
||||
|
||||
GLAD_API_CALL int gladLoaderLoadGL(void);
|
||||
GLAD_API_CALL void gladLoaderUnloadGL(void);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
@ -5813,7 +5833,6 @@ int GLAD_GL_ARB_tessellation_shader = 0;
|
|||
int GLAD_GL_ARB_texture_border_clamp = 0;
|
||||
int GLAD_GL_ARB_texture_buffer_object_rgb32 = 0;
|
||||
int GLAD_GL_ARB_texture_compression = 0;
|
||||
int GLAD_GL_EXT_texture_compression_s3tc = 0;
|
||||
int GLAD_GL_ARB_texture_cube_map = 0;
|
||||
int GLAD_GL_ARB_texture_cube_map_array = 0;
|
||||
int GLAD_GL_ARB_texture_env_add = 0;
|
||||
|
|
@ -5837,11 +5856,17 @@ int GLAD_GL_ARB_vertex_attrib_binding = 0;
|
|||
int GLAD_GL_ARB_vertex_buffer_object = 0;
|
||||
int GLAD_GL_ARB_vertex_program = 0;
|
||||
int GLAD_GL_ARB_vertex_shader = 0;
|
||||
int GLAD_GL_EXT_draw_instanced = 0;
|
||||
int GLAD_GL_EXT_fog_coord = 0;
|
||||
int GLAD_GL_EXT_framebuffer_blit = 0;
|
||||
int GLAD_GL_EXT_framebuffer_multisample = 0;
|
||||
int GLAD_GL_EXT_framebuffer_object = 0;
|
||||
int GLAD_GL_EXT_framebuffer_sRGB = 0;
|
||||
int GLAD_GL_EXT_texture_compression_s3tc = 0;
|
||||
int GLAD_GL_EXT_texture_filter_anisotropic = 0;
|
||||
int GLAD_GL_EXT_texture_mirror_clamp = 0;
|
||||
int GLAD_GL_KHR_texture_compression_astc_hdr = 0;
|
||||
int GLAD_GL_KHR_texture_compression_astc_ldr = 0;
|
||||
int GLAD_GL_OES_compressed_paletted_texture = 0;
|
||||
int GLAD_GL_OES_fixed_point = 0;
|
||||
|
||||
|
|
@ -6038,6 +6063,7 @@ PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect = NULL;
|
|||
PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced = NULL;
|
||||
PFNGLDRAWARRAYSINSTANCEDARBPROC glad_glDrawArraysInstancedARB = NULL;
|
||||
PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance = NULL;
|
||||
PFNGLDRAWARRAYSINSTANCEDEXTPROC glad_glDrawArraysInstancedEXT = NULL;
|
||||
PFNGLDRAWBUFFERPROC glad_glDrawBuffer = NULL;
|
||||
PFNGLDRAWBUFFERSPROC glad_glDrawBuffers = NULL;
|
||||
PFNGLDRAWBUFFERSARBPROC glad_glDrawBuffersARB = NULL;
|
||||
|
|
@ -6049,6 +6075,7 @@ PFNGLDRAWELEMENTSINSTANCEDARBPROC glad_glDrawElementsInstancedARB = NULL;
|
|||
PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance = NULL;
|
||||
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex = NULL;
|
||||
PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance = NULL;
|
||||
PFNGLDRAWELEMENTSINSTANCEDEXTPROC glad_glDrawElementsInstancedEXT = NULL;
|
||||
PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements = NULL;
|
||||
PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex = NULL;
|
||||
PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback = NULL;
|
||||
|
|
@ -8122,6 +8149,11 @@ static void glad_gl_load_GL_ARB_vertex_shader( GLADuserptrloadfunc load, void* u
|
|||
glad_glVertexAttrib4usvARB = (PFNGLVERTEXATTRIB4USVARBPROC) load(userptr, "glVertexAttrib4usvARB");
|
||||
glad_glVertexAttribPointerARB = (PFNGLVERTEXATTRIBPOINTERARBPROC) load(userptr, "glVertexAttribPointerARB");
|
||||
}
|
||||
static void glad_gl_load_GL_EXT_draw_instanced( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_GL_EXT_draw_instanced) return;
|
||||
glad_glDrawArraysInstancedEXT = (PFNGLDRAWARRAYSINSTANCEDEXTPROC) load(userptr, "glDrawArraysInstancedEXT");
|
||||
glad_glDrawElementsInstancedEXT = (PFNGLDRAWELEMENTSINSTANCEDEXTPROC) load(userptr, "glDrawElementsInstancedEXT");
|
||||
}
|
||||
static void glad_gl_load_GL_EXT_fog_coord( GLADuserptrloadfunc load, void* userptr) {
|
||||
if(!GLAD_GL_EXT_fog_coord) return;
|
||||
glad_glFogCoordPointerEXT = (PFNGLFOGCOORDPOINTEREXTPROC) load(userptr, "glFogCoordPointerEXT");
|
||||
|
|
@ -8451,8 +8483,7 @@ static int glad_gl_find_extensions_gl( int version) {
|
|||
GLAD_GL_ARB_texture_border_clamp = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_border_clamp");
|
||||
GLAD_GL_ARB_texture_buffer_object_rgb32 = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_buffer_object_rgb32");
|
||||
GLAD_GL_ARB_texture_compression = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_compression");
|
||||
GLAD_GL_EXT_texture_compression_s3tc = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_compression_s3tc");
|
||||
GLAD_GL_ARB_texture_cube_map = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_cube_map");
|
||||
GLAD_GL_ARB_texture_cube_map = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_cube_map");
|
||||
GLAD_GL_ARB_texture_cube_map_array = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_cube_map_array");
|
||||
GLAD_GL_ARB_texture_env_add = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_env_add");
|
||||
GLAD_GL_ARB_texture_filter_anisotropic = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_texture_filter_anisotropic");
|
||||
|
|
@ -8475,11 +8506,17 @@ static int glad_gl_find_extensions_gl( int version) {
|
|||
GLAD_GL_ARB_vertex_buffer_object = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_vertex_buffer_object");
|
||||
GLAD_GL_ARB_vertex_program = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_vertex_program");
|
||||
GLAD_GL_ARB_vertex_shader = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_ARB_vertex_shader");
|
||||
GLAD_GL_EXT_draw_instanced = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_draw_instanced");
|
||||
GLAD_GL_EXT_fog_coord = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_fog_coord");
|
||||
GLAD_GL_EXT_framebuffer_blit = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_blit");
|
||||
GLAD_GL_EXT_framebuffer_multisample = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_multisample");
|
||||
GLAD_GL_EXT_framebuffer_object = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_object");
|
||||
GLAD_GL_EXT_framebuffer_sRGB = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_framebuffer_sRGB");
|
||||
GLAD_GL_EXT_texture_compression_s3tc = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_compression_s3tc");
|
||||
GLAD_GL_EXT_texture_filter_anisotropic = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_filter_anisotropic");
|
||||
GLAD_GL_EXT_texture_mirror_clamp = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_EXT_texture_mirror_clamp");
|
||||
GLAD_GL_KHR_texture_compression_astc_hdr = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_KHR_texture_compression_astc_hdr");
|
||||
GLAD_GL_KHR_texture_compression_astc_ldr = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_KHR_texture_compression_astc_ldr");
|
||||
GLAD_GL_OES_compressed_paletted_texture = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_OES_compressed_paletted_texture");
|
||||
GLAD_GL_OES_fixed_point = glad_gl_has_extension(version, exts, num_exts_i, exts_i, "GL_OES_fixed_point");
|
||||
|
||||
|
|
@ -8615,6 +8652,7 @@ int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) {
|
|||
glad_gl_load_GL_ARB_vertex_buffer_object(load, userptr);
|
||||
glad_gl_load_GL_ARB_vertex_program(load, userptr);
|
||||
glad_gl_load_GL_ARB_vertex_shader(load, userptr);
|
||||
glad_gl_load_GL_EXT_draw_instanced(load, userptr);
|
||||
glad_gl_load_GL_EXT_fog_coord(load, userptr);
|
||||
glad_gl_load_GL_EXT_framebuffer_blit(load, userptr);
|
||||
glad_gl_load_GL_EXT_framebuffer_multisample(load, userptr);
|
||||
|
|
@ -8632,6 +8670,10 @@ int gladLoadGL( GLADloadfunc load) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
818
src/external/rl_gputex.h
vendored
Normal file
818
src/external/rl_gputex.h
vendored
Normal file
|
|
@ -0,0 +1,818 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* rl_gputex - GPU compressed textures loading and saving
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Load GPU compressed image data from image files provided as memory data arrays,
|
||||
* data is loaded compressed, ready to be loaded into GPU.
|
||||
*
|
||||
* Note that some file formats (DDS, PVR, KTX) also support uncompressed data storage.
|
||||
* In those cases data is loaded uncompressed and format is returned.
|
||||
*
|
||||
* TODO:
|
||||
* - Implement raylib function: rlGetGlTextureFormats(), required by rl_save_ktx_to_memory()
|
||||
* - Review rl_load_ktx_from_memory() to support KTX v2.2 specs
|
||||
*
|
||||
* CONFIGURATION:
|
||||
*
|
||||
* #define RL_GPUTEX_SUPPORT_DDS
|
||||
* #define RL_GPUTEX_SUPPORT_PKM
|
||||
* #define RL_GPUTEX_SUPPORT_KTX
|
||||
* #define RL_GPUTEX_SUPPORT_PVR
|
||||
* #define RL_GPUTEX_SUPPORT_ASTC
|
||||
* Define desired file formats to be supported
|
||||
*
|
||||
*
|
||||
* LICENSE: zlib/libpng
|
||||
*
|
||||
* Copyright (c) 2013-2022 Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef RL_GPUTEX_H
|
||||
#define RL_GPUTEX_H
|
||||
|
||||
#ifndef RLAPI
|
||||
#define RLAPI // Functions defined as 'extern' by default (implicit specifiers)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(__cplusplus)
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
// Load image data from memory data files
|
||||
RLAPI void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
|
||||
RLAPI void *rl_load_pkm_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
|
||||
RLAPI void *rl_load_ktx_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
|
||||
RLAPI void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
|
||||
RLAPI void *rl_load_astc_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips);
|
||||
|
||||
RLAPI int rl_save_ktx_to_memory(const char *fileName, void *data, int width, int height, int format, int mipmaps); // Save image data as KTX file
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RL_GPUTEX_H
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
*
|
||||
* RL_GPUTEX IMPLEMENTATION
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(RL_GPUTEX_IMPLEMENTATION)
|
||||
|
||||
// Simple log system to avoid RPNG_LOG() calls if required
|
||||
// NOTE: Avoiding those calls, also avoids const strings memory usage
|
||||
#define RL_GPUTEX_SHOW_LOG_INFO
|
||||
#if defined(RL_GPUTEX_SHOW_LOG_INFO) && !defined(LOG)
|
||||
#define LOG(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define LOG(...)
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
// Get pixel data size in bytes for certain pixel format
|
||||
static int get_pixel_data_size(int width, int height, int format);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(RL_GPUTEX_SUPPORT_DDS)
|
||||
// Loading DDS from memory image data (compressed or uncompressed)
|
||||
void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
|
||||
{
|
||||
void *image_data = NULL; // Image data pointer
|
||||
int image_pixel_size = 0; // Image pixel size
|
||||
|
||||
unsigned char *file_data_ptr = (unsigned char *)file_data;
|
||||
|
||||
// Required extension:
|
||||
// GL_EXT_texture_compression_s3tc
|
||||
|
||||
// Supported tokens (defined by extensions)
|
||||
// GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
||||
// GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
||||
// GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
||||
// GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
||||
|
||||
#define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
|
||||
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
|
||||
#define FOURCC_DXT5 0x35545844 // Equivalent to "DXT5" in ASCII
|
||||
|
||||
// DDS Pixel Format
|
||||
typedef struct {
|
||||
unsigned int size;
|
||||
unsigned int flags;
|
||||
unsigned int fourcc;
|
||||
unsigned int rgb_bit_count;
|
||||
unsigned int r_bit_mask;
|
||||
unsigned int g_bit_mask;
|
||||
unsigned int b_bit_mask;
|
||||
unsigned int a_bit_mask;
|
||||
} dds_pixel_format;
|
||||
|
||||
// DDS Header (124 bytes)
|
||||
typedef struct {
|
||||
unsigned int size;
|
||||
unsigned int flags;
|
||||
unsigned int height;
|
||||
unsigned int width;
|
||||
unsigned int pitch_or_linear_size;
|
||||
unsigned int depth;
|
||||
unsigned int mipmap_count;
|
||||
unsigned int reserved1[11];
|
||||
dds_pixel_format ddspf;
|
||||
unsigned int caps;
|
||||
unsigned int caps2;
|
||||
unsigned int caps3;
|
||||
unsigned int caps4;
|
||||
unsigned int reserved2;
|
||||
} dds_header;
|
||||
|
||||
if (file_data_ptr != NULL)
|
||||
{
|
||||
// Verify the type of file
|
||||
unsigned char *dds_header_id = file_data_ptr;
|
||||
file_data_ptr += 4;
|
||||
|
||||
if ((dds_header_id[0] != 'D') || (dds_header_id[1] != 'D') || (dds_header_id[2] != 'S') || (dds_header_id[3] != ' '))
|
||||
{
|
||||
LOG("WARNING: IMAGE: DDS file data not valid");
|
||||
}
|
||||
else
|
||||
{
|
||||
dds_header *header = (dds_header *)file_data_ptr;
|
||||
|
||||
file_data_ptr += sizeof(dds_header); // Skip header
|
||||
|
||||
*width = header->width;
|
||||
*height = header->height;
|
||||
image_pixel_size = header->width*header->height;
|
||||
|
||||
if (header->mipmap_count == 0) *mips = 1; // Parameter not used
|
||||
else *mips = header->mipmap_count;
|
||||
|
||||
if (header->ddspf.rgb_bit_count == 16) // 16bit mode, no compressed
|
||||
{
|
||||
if (header->ddspf.flags == 0x40) // No alpha channel
|
||||
{
|
||||
int data_size = image_pixel_size*sizeof(unsigned short);
|
||||
image_data = RL_MALLOC(data_size);
|
||||
|
||||
memcpy(image_data, file_data_ptr, data_size);
|
||||
|
||||
*format = PIXELFORMAT_UNCOMPRESSED_R5G6B5;
|
||||
}
|
||||
else if (header->ddspf.flags == 0x41) // With alpha channel
|
||||
{
|
||||
if (header->ddspf.a_bit_mask == 0x8000) // 1bit alpha
|
||||
{
|
||||
int data_size = image_pixel_size*sizeof(unsigned short);
|
||||
image_data = RL_MALLOC(data_size);
|
||||
|
||||
memcpy(image_data, file_data_ptr, data_size);
|
||||
|
||||
unsigned char alpha = 0;
|
||||
|
||||
// NOTE: Data comes as A1R5G5B5, it must be reordered to R5G5B5A1
|
||||
for (int i = 0; i < image_pixel_size; i++)
|
||||
{
|
||||
alpha = ((unsigned short *)image_data)[i] >> 15;
|
||||
((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 1;
|
||||
((unsigned short *)image_data)[i] += alpha;
|
||||
}
|
||||
|
||||
*format = PIXELFORMAT_UNCOMPRESSED_R5G5B5A1;
|
||||
}
|
||||
else if (header->ddspf.a_bit_mask == 0xf000) // 4bit alpha
|
||||
{
|
||||
int data_size = image_pixel_size*sizeof(unsigned short);
|
||||
image_data = RL_MALLOC(data_size);
|
||||
|
||||
memcpy(image_data, file_data_ptr, data_size);
|
||||
|
||||
unsigned char alpha = 0;
|
||||
|
||||
// NOTE: Data comes as A4R4G4B4, it must be reordered R4G4B4A4
|
||||
for (int i = 0; i < image_pixel_size; i++)
|
||||
{
|
||||
alpha = ((unsigned short *)image_data)[i] >> 12;
|
||||
((unsigned short *)image_data)[i] = ((unsigned short *)image_data)[i] << 4;
|
||||
((unsigned short *)image_data)[i] += alpha;
|
||||
}
|
||||
|
||||
*format = PIXELFORMAT_UNCOMPRESSED_R4G4B4A4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (header->ddspf.flags == 0x40 && header->ddspf.rgb_bit_count == 24) // DDS_RGB, no compressed
|
||||
{
|
||||
int data_size = image_pixel_size*3*sizeof(unsigned char);
|
||||
image_data = RL_MALLOC(data_size);
|
||||
|
||||
memcpy(image_data, file_data_ptr, data_size);
|
||||
|
||||
*format = PIXELFORMAT_UNCOMPRESSED_R8G8B8;
|
||||
}
|
||||
else if (header->ddspf.flags == 0x41 && header->ddspf.rgb_bit_count == 32) // DDS_RGBA, no compressed
|
||||
{
|
||||
int data_size = image_pixel_size*4*sizeof(unsigned char);
|
||||
image_data = RL_MALLOC(data_size);
|
||||
|
||||
memcpy(image_data, file_data_ptr, data_size);
|
||||
|
||||
unsigned char blue = 0;
|
||||
|
||||
// NOTE: Data comes as A8R8G8B8, it must be reordered R8G8B8A8 (view next comment)
|
||||
// DirecX understand ARGB as a 32bit DWORD but the actual memory byte alignment is BGRA
|
||||
// So, we must realign B8G8R8A8 to R8G8B8A8
|
||||
for (int i = 0; i < image_pixel_size*4; i += 4)
|
||||
{
|
||||
blue = ((unsigned char *)image_data)[i];
|
||||
((unsigned char *)image_data)[i] = ((unsigned char *)image_data)[i + 2];
|
||||
((unsigned char *)image_data)[i + 2] = blue;
|
||||
}
|
||||
|
||||
*format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
|
||||
}
|
||||
else if (((header->ddspf.flags == 0x04) || (header->ddspf.flags == 0x05)) && (header->ddspf.fourcc > 0)) // Compressed
|
||||
{
|
||||
int data_size = 0;
|
||||
|
||||
// Calculate data size, including all mipmaps
|
||||
if (header->mipmap_count > 1) data_size = header->pitch_or_linear_size*2;
|
||||
else data_size = header->pitch_or_linear_size;
|
||||
|
||||
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
|
||||
|
||||
memcpy(image_data, file_data_ptr, data_size);
|
||||
|
||||
switch (header->ddspf.fourcc)
|
||||
{
|
||||
case FOURCC_DXT1:
|
||||
{
|
||||
if (header->ddspf.flags == 0x04) *format = PIXELFORMAT_COMPRESSED_DXT1_RGB;
|
||||
else *format = PIXELFORMAT_COMPRESSED_DXT1_RGBA;
|
||||
} break;
|
||||
case FOURCC_DXT3: *format = PIXELFORMAT_COMPRESSED_DXT3_RGBA; break;
|
||||
case FOURCC_DXT5: *format = PIXELFORMAT_COMPRESSED_DXT5_RGBA; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return image_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(RL_GPUTEX_SUPPORT_PKM)
|
||||
// Loading PKM image data (ETC1/ETC2 compression)
|
||||
// NOTE: KTX is the standard Khronos Group compression format (ETC1/ETC2, mipmaps)
|
||||
// PKM is a much simpler file format used mainly to contain a single ETC1/ETC2 compressed image (no mipmaps)
|
||||
void *rl_load_pkm_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
|
||||
{
|
||||
void *image_data = NULL; // Image data pointer
|
||||
|
||||
unsigned char *file_data_ptr = (unsigned char *)file_data;
|
||||
|
||||
// Required extensions:
|
||||
// GL_OES_compressed_ETC1_RGB8_texture (ETC1) (OpenGL ES 2.0)
|
||||
// GL_ARB_ES3_compatibility (ETC2/EAC) (OpenGL ES 3.0)
|
||||
|
||||
// Supported tokens (defined by extensions)
|
||||
// GL_ETC1_RGB8_OES 0x8D64
|
||||
// GL_COMPRESSED_RGB8_ETC2 0x9274
|
||||
// GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
|
||||
|
||||
// PKM file (ETC1) Header (16 bytes)
|
||||
typedef struct {
|
||||
char id[4]; // "PKM "
|
||||
char version[2]; // "10" or "20"
|
||||
unsigned short format; // Data format (big-endian) (Check list below)
|
||||
unsigned short width; // Texture width (big-endian) (orig_width rounded to multiple of 4)
|
||||
unsigned short height; // Texture height (big-endian) (orig_height rounded to multiple of 4)
|
||||
unsigned short orig_width; // Original width (big-endian)
|
||||
unsigned short orig_height; // Original height (big-endian)
|
||||
} pkm_header;
|
||||
|
||||
// Formats list
|
||||
// version 10: format: 0=ETC1_RGB, [1=ETC1_RGBA, 2=ETC1_RGB_MIP, 3=ETC1_RGBA_MIP] (not used)
|
||||
// version 20: format: 0=ETC1_RGB, 1=ETC2_RGB, 2=ETC2_RGBA_OLD, 3=ETC2_RGBA, 4=ETC2_RGBA1, 5=ETC2_R, 6=ETC2_RG, 7=ETC2_SIGNED_R, 8=ETC2_SIGNED_R
|
||||
|
||||
// NOTE: The extended width and height are the widths rounded up to a multiple of 4.
|
||||
// NOTE: ETC is always 4bit per pixel (64 bit for each 4x4 block of pixels)
|
||||
|
||||
if (file_data_ptr != NULL)
|
||||
{
|
||||
pkm_header *header = (pkm_header *)file_data_ptr;
|
||||
|
||||
if ((header->id[0] != 'P') || (header->id[1] != 'K') || (header->id[2] != 'M') || (header->id[3] != ' '))
|
||||
{
|
||||
LOG("WARNING: IMAGE: PKM file data not valid");
|
||||
}
|
||||
else
|
||||
{
|
||||
file_data_ptr += sizeof(pkm_header); // Skip header
|
||||
|
||||
// NOTE: format, width and height come as big-endian, data must be swapped to little-endian
|
||||
header->format = ((header->format & 0x00FF) << 8) | ((header->format & 0xFF00) >> 8);
|
||||
header->width = ((header->width & 0x00FF) << 8) | ((header->width & 0xFF00) >> 8);
|
||||
header->height = ((header->height & 0x00FF) << 8) | ((header->height & 0xFF00) >> 8);
|
||||
|
||||
*width = header->width;
|
||||
*height = header->height;
|
||||
*mips = 1;
|
||||
|
||||
int bpp = 4;
|
||||
if (header->format == 3) bpp = 8;
|
||||
|
||||
int data_size = (*width)*(*height)*bpp/8; // Total data size in bytes
|
||||
|
||||
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
|
||||
|
||||
memcpy(image_data, file_data_ptr, data_size);
|
||||
|
||||
if (header->format == 0) *format = PIXELFORMAT_COMPRESSED_ETC1_RGB;
|
||||
else if (header->format == 1) *format = PIXELFORMAT_COMPRESSED_ETC2_RGB;
|
||||
else if (header->format == 3) *format = PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA;
|
||||
}
|
||||
}
|
||||
|
||||
return image_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(RL_GPUTEX_SUPPORT_KTX)
|
||||
// Load KTX compressed image data (ETC1/ETC2 compression)
|
||||
// TODO: Review KTX loading, many things changed!
|
||||
void *rl_load_ktx_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
|
||||
{
|
||||
void *image_data = NULL; // Image data pointer
|
||||
|
||||
unsigned char *file_data_ptr = (unsigned char *)file_data;
|
||||
|
||||
// Required extensions:
|
||||
// GL_OES_compressed_ETC1_RGB8_texture (ETC1)
|
||||
// GL_ARB_ES3_compatibility (ETC2/EAC)
|
||||
|
||||
// Supported tokens (defined by extensions)
|
||||
// GL_ETC1_RGB8_OES 0x8D64
|
||||
// GL_COMPRESSED_RGB8_ETC2 0x9274
|
||||
// GL_COMPRESSED_RGBA8_ETC2_EAC 0x9278
|
||||
|
||||
// KTX file Header (64 bytes)
|
||||
// v1.1 - https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
|
||||
// v2.0 - http://github.khronos.org/KTX-Specification/
|
||||
|
||||
// KTX 1.1 Header
|
||||
// TODO: Support KTX 2.2 specs!
|
||||
typedef struct {
|
||||
char id[12]; // Identifier: "«KTX 11»\r\n\x1A\n"
|
||||
unsigned int endianness; // Little endian: 0x01 0x02 0x03 0x04
|
||||
unsigned int gl_type; // For compressed textures, glType must equal 0
|
||||
unsigned int gl_type_size; // For compressed texture data, usually 1
|
||||
unsigned int gl_format; // For compressed textures is 0
|
||||
unsigned int gl_internal_format; // Compressed internal format
|
||||
unsigned int gl_base_internal_format; // Same as glFormat (RGB, RGBA, ALPHA...)
|
||||
unsigned int width; // Texture image width in pixels
|
||||
unsigned int height; // Texture image height in pixels
|
||||
unsigned int depth; // For 2D textures is 0
|
||||
unsigned int elements; // Number of array elements, usually 0
|
||||
unsigned int faces; // Cubemap faces, for no-cubemap = 1
|
||||
unsigned int mipmap_levels; // Non-mipmapped textures = 1
|
||||
unsigned int key_value_data_size; // Used to encode any arbitrary data...
|
||||
} ktx_header;
|
||||
|
||||
// NOTE: Before start of every mipmap data block, we have: unsigned int data_size
|
||||
|
||||
if (file_data_ptr != NULL)
|
||||
{
|
||||
ktx_header *header = (ktx_header *)file_data_ptr;
|
||||
|
||||
if ((header->id[1] != 'K') || (header->id[2] != 'T') || (header->id[3] != 'X') ||
|
||||
(header->id[4] != ' ') || (header->id[5] != '1') || (header->id[6] != '1'))
|
||||
{
|
||||
LOG("WARNING: IMAGE: KTX file data not valid");
|
||||
}
|
||||
else
|
||||
{
|
||||
file_data_ptr += sizeof(ktx_header); // Move file data pointer
|
||||
|
||||
*width = header->width;
|
||||
*height = header->height;
|
||||
*mips = header->mipmap_levels;
|
||||
|
||||
file_data_ptr += header->key_value_data_size; // Skip value data size
|
||||
|
||||
int data_size = ((int *)file_data_ptr)[0];
|
||||
file_data_ptr += sizeof(int);
|
||||
|
||||
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
|
||||
|
||||
memcpy(image_data, file_data_ptr, data_size);
|
||||
|
||||
if (header->gl_internal_format == 0x8D64) *format = PIXELFORMAT_COMPRESSED_ETC1_RGB;
|
||||
else if (header->gl_internal_format == 0x9274) *format = PIXELFORMAT_COMPRESSED_ETC2_RGB;
|
||||
else if (header->gl_internal_format == 0x9278) *format = PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA;
|
||||
|
||||
// TODO: Support uncompressed data formats? Right now it returns format = 0!
|
||||
}
|
||||
}
|
||||
|
||||
return image_data;
|
||||
}
|
||||
|
||||
// Save image data as KTX file
|
||||
// NOTE: By default KTX 1.1 spec is used, 2.0 is still on draft (01Oct2018)
|
||||
// TODO: Review KTX saving, many things changed!
|
||||
int rl_save_ktx(const char *file_name, void *data, int width, int height, int format, int mipmaps)
|
||||
{
|
||||
// KTX file Header (64 bytes)
|
||||
// v1.1 - https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
|
||||
// v2.0 - http://github.khronos.org/KTX-Specification/ - Final specs by 2021-04-18
|
||||
typedef struct {
|
||||
char id[12]; // Identifier: "«KTX 11»\r\n\x1A\n" // KTX 2.0: "«KTX 22»\r\n\x1A\n"
|
||||
unsigned int endianness; // Little endian: 0x01 0x02 0x03 0x04
|
||||
unsigned int gl_type; // For compressed textures, glType must equal 0
|
||||
unsigned int gl_type_size; // For compressed texture data, usually 1
|
||||
unsigned int gl_format; // For compressed textures is 0
|
||||
unsigned int gl_internal_format; // Compressed internal format
|
||||
unsigned int gl_base_internal_format; // Same as glFormat (RGB, RGBA, ALPHA...) // KTX 2.0: UInt32 vkFormat
|
||||
unsigned int width; // Texture image width in pixels
|
||||
unsigned int height; // Texture image height in pixels
|
||||
unsigned int depth; // For 2D textures is 0
|
||||
unsigned int elements; // Number of array elements, usually 0
|
||||
unsigned int faces; // Cubemap faces, for no-cubemap = 1
|
||||
unsigned int mipmap_levels; // Non-mipmapped textures = 1
|
||||
unsigned int key_value_data_size; // Used to encode any arbitrary data... // KTX 2.0: UInt32 levelOrder - ordering of the mipmap levels, usually 0
|
||||
// KTX 2.0: UInt32 supercompressionScheme - 0 (None), 1 (Crunch CRN), 2 (Zlib DEFLATE)...
|
||||
// KTX 2.0 defines additional header elements...
|
||||
} ktx_header;
|
||||
|
||||
// Calculate file data_size required
|
||||
int data_size = sizeof(ktx_header);
|
||||
|
||||
for (int i = 0, width = width, height = height; i < mipmaps; i++)
|
||||
{
|
||||
data_size += get_pixel_data_size(width, height, format);
|
||||
width /= 2; height /= 2;
|
||||
}
|
||||
|
||||
unsigned char *file_data = RL_CALLOC(data_size, 1);
|
||||
unsigned char *file_data_ptr = file_data;
|
||||
|
||||
ktx_header header = { 0 };
|
||||
|
||||
// KTX identifier (v1.1)
|
||||
//unsigned char id[12] = { '«', 'K', 'T', 'X', ' ', '1', '1', '»', '\r', '\n', '\x1A', '\n' };
|
||||
//unsigned char id[12] = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
|
||||
|
||||
const char ktx_identifier[12] = { 0xAB, 'K', 'T', 'X', ' ', '1', '1', 0xBB, '\r', '\n', 0x1A, '\n' };
|
||||
|
||||
// Get the image header
|
||||
memcpy(header.id, ktx_identifier, 12); // KTX 1.1 signature
|
||||
header.endianness = 0;
|
||||
header.gl_type = 0; // Obtained from format
|
||||
header.gl_type_size = 1;
|
||||
header.gl_format = 0; // Obtained from format
|
||||
header.gl_internal_format = 0; // Obtained from format
|
||||
header.gl_base_internal_format = 0;
|
||||
header.width = width;
|
||||
header.height = height;
|
||||
header.depth = 0;
|
||||
header.elements = 0;
|
||||
header.faces = 1;
|
||||
header.mipmap_levels = mipmaps; // If it was 0, it means mipmaps should be generated on loading (not for compressed formats)
|
||||
header.key_value_data_size = 0; // No extra data after the header
|
||||
|
||||
rlGetGlTextureFormats(format, &header.gl_internal_format, &header.gl_format, &header.gl_type); // rlgl module function
|
||||
header.gl_base_internal_format = header.gl_format; // KTX 1.1 only
|
||||
|
||||
// NOTE: We can save into a .ktx all PixelFormats supported by raylib, including compressed formats like DXT, ETC or ASTC
|
||||
|
||||
if (header.gl_format == -1) LOG("WARNING: IMAGE: GL format not supported for KTX export (%i)", header.gl_format);
|
||||
else
|
||||
{
|
||||
memcpy(file_data_ptr, &header, sizeof(ktx_header));
|
||||
file_data_ptr += sizeof(ktx_header);
|
||||
|
||||
int temp_width = width;
|
||||
int temp_height = height;
|
||||
int data_offset = 0;
|
||||
|
||||
// Save all mipmaps data
|
||||
for (int i = 0; i < mipmaps; i++)
|
||||
{
|
||||
unsigned int data_size = get_pixel_data_size(temp_width, temp_height, format);
|
||||
|
||||
memcpy(file_data_ptr, &data_size, sizeof(unsigned int));
|
||||
memcpy(file_data_ptr + 4, (unsigned char *)data + data_offset, data_size);
|
||||
|
||||
temp_width /= 2;
|
||||
temp_height /= 2;
|
||||
data_offset += data_size;
|
||||
file_data_ptr += (4 + data_size);
|
||||
}
|
||||
}
|
||||
|
||||
// Save file data to file
|
||||
int success = false;
|
||||
FILE *file = fopen(file_name, "wb");
|
||||
|
||||
if (file != NULL)
|
||||
{
|
||||
unsigned int count = (unsigned int)fwrite(file_data, sizeof(unsigned char), data_size, file);
|
||||
|
||||
if (count == 0) LOG("WARNING: FILEIO: [%s] Failed to write file", file_name);
|
||||
else if (count != data_size) LOG("WARNING: FILEIO: [%s] File partially written", file_name);
|
||||
else LOG("INFO: FILEIO: [%s] File saved successfully", file_name);
|
||||
|
||||
int result = fclose(file);
|
||||
if (result == 0) success = true;
|
||||
}
|
||||
else LOG("WARNING: FILEIO: [%s] Failed to open file", file_name);
|
||||
|
||||
RL_FREE(file_data); // Free file data buffer
|
||||
|
||||
// If all data has been written correctly to file, success = 1
|
||||
return success;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(RL_GPUTEX_SUPPORT_PVR)
|
||||
// Loading PVR image data (uncompressed or PVRT compression)
|
||||
// NOTE: PVR v2 not supported, use PVR v3 instead
|
||||
void *rl_load_pvr_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
|
||||
{
|
||||
void *image_data = NULL; // Image data pointer
|
||||
|
||||
unsigned char *file_data_ptr = (unsigned char *)file_data;
|
||||
|
||||
// Required extension:
|
||||
// GL_IMG_texture_compression_pvrtc
|
||||
|
||||
// Supported tokens (defined by extensions)
|
||||
// GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG 0x8C00
|
||||
// GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG 0x8C02
|
||||
|
||||
#if 0 // Not used...
|
||||
// PVR file v2 Header (52 bytes)
|
||||
typedef struct {
|
||||
unsigned int headerLength;
|
||||
unsigned int height;
|
||||
unsigned int width;
|
||||
unsigned int numMipmaps;
|
||||
unsigned int flags;
|
||||
unsigned int dataLength;
|
||||
unsigned int bpp;
|
||||
unsigned int bitmaskRed;
|
||||
unsigned int bitmaskGreen;
|
||||
unsigned int bitmaskBlue;
|
||||
unsigned int bitmaskAlpha;
|
||||
unsigned int pvrTag;
|
||||
unsigned int numSurfs;
|
||||
} PVRHeaderV2;
|
||||
#endif
|
||||
|
||||
// PVR file v3 Header (52 bytes)
|
||||
// NOTE: After it could be metadata (15 bytes?)
|
||||
typedef struct {
|
||||
char id[4];
|
||||
unsigned int flags;
|
||||
unsigned char channels[4]; // pixelFormat high part
|
||||
unsigned char channel_depth[4]; // pixelFormat low part
|
||||
unsigned int color_space;
|
||||
unsigned int channel_type;
|
||||
unsigned int height;
|
||||
unsigned int width;
|
||||
unsigned int depth;
|
||||
unsigned int num_surfaces;
|
||||
unsigned int num_faces;
|
||||
unsigned int num_mipmaps;
|
||||
unsigned int metadata_size;
|
||||
} pvr_header;
|
||||
|
||||
#if 0 // Not used...
|
||||
// Metadata (usually 15 bytes)
|
||||
typedef struct {
|
||||
unsigned int devFOURCC;
|
||||
unsigned int key;
|
||||
unsigned int data_size; // Not used?
|
||||
unsigned char *data; // Not used?
|
||||
} PVRMetadata;
|
||||
#endif
|
||||
|
||||
if (file_data_ptr != NULL)
|
||||
{
|
||||
// Check PVR image version
|
||||
unsigned char pvr_version = file_data_ptr[0];
|
||||
|
||||
// Load different PVR data formats
|
||||
if (pvr_version == 0x50)
|
||||
{
|
||||
pvr_header *header = (pvr_header *)file_data_ptr;
|
||||
|
||||
if ((header->id[0] != 'P') || (header->id[1] != 'V') || (header->id[2] != 'R') || (header->id[3] != 3))
|
||||
{
|
||||
LOG("WARNING: IMAGE: PVR file data not valid");
|
||||
}
|
||||
else
|
||||
{
|
||||
file_data_ptr += sizeof(pvr_header); // Skip header
|
||||
|
||||
*width = header->width;
|
||||
*height = header->height;
|
||||
*mips = header->num_mipmaps;
|
||||
|
||||
// Check data format
|
||||
if (((header->channels[0] == 'l') && (header->channels[1] == 0)) && (header->channel_depth[0] == 8)) *format = PIXELFORMAT_UNCOMPRESSED_GRAYSCALE;
|
||||
else if (((header->channels[0] == 'l') && (header->channels[1] == 'a')) && ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8))) *format = PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA;
|
||||
else if ((header->channels[0] == 'r') && (header->channels[1] == 'g') && (header->channels[2] == 'b'))
|
||||
{
|
||||
if (header->channels[3] == 'a')
|
||||
{
|
||||
if ((header->channel_depth[0] == 5) && (header->channel_depth[1] == 5) && (header->channel_depth[2] == 5) && (header->channel_depth[3] == 1)) *format = PIXELFORMAT_UNCOMPRESSED_R5G5B5A1;
|
||||
else if ((header->channel_depth[0] == 4) && (header->channel_depth[1] == 4) && (header->channel_depth[2] == 4) && (header->channel_depth[3] == 4)) *format = PIXELFORMAT_UNCOMPRESSED_R4G4B4A4;
|
||||
else if ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8) && (header->channel_depth[2] == 8) && (header->channel_depth[3] == 8)) *format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8;
|
||||
}
|
||||
else if (header->channels[3] == 0)
|
||||
{
|
||||
if ((header->channel_depth[0] == 5) && (header->channel_depth[1] == 6) && (header->channel_depth[2] == 5)) *format = PIXELFORMAT_UNCOMPRESSED_R5G6B5;
|
||||
else if ((header->channel_depth[0] == 8) && (header->channel_depth[1] == 8) && (header->channel_depth[2] == 8)) *format = PIXELFORMAT_UNCOMPRESSED_R8G8B8;
|
||||
}
|
||||
}
|
||||
else if (header->channels[0] == 2) *format = PIXELFORMAT_COMPRESSED_PVRT_RGB;
|
||||
else if (header->channels[0] == 3) *format = PIXELFORMAT_COMPRESSED_PVRT_RGBA;
|
||||
|
||||
file_data_ptr += header->metadata_size; // Skip meta data header
|
||||
|
||||
// Calculate data size (depends on format)
|
||||
int bpp = 0;
|
||||
switch (*format)
|
||||
{
|
||||
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
|
||||
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
|
||||
case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
|
||||
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break;
|
||||
case PIXELFORMAT_COMPRESSED_PVRT_RGB:
|
||||
case PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
int data_size = (*width)*(*height)*bpp/8; // Total data size in bytes
|
||||
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
|
||||
|
||||
memcpy(image_data, file_data_ptr, data_size);
|
||||
}
|
||||
}
|
||||
else if (pvr_version == 52) LOG("INFO: IMAGE: PVRv2 format not supported, update your files to PVRv3");
|
||||
}
|
||||
|
||||
return image_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(RL_GPUTEX_SUPPORT_ASTC)
|
||||
// Load ASTC compressed image data (ASTC compression)
|
||||
void *rl_load_astc_from_memory(const unsigned char *file_data, unsigned int file_size, int *width, int *height, int *format, int *mips)
|
||||
{
|
||||
void *image_data = NULL; // Image data pointer
|
||||
|
||||
unsigned char *file_data_ptr = (unsigned char *)file_data;
|
||||
|
||||
// Required extensions:
|
||||
// GL_KHR_texture_compression_astc_hdr
|
||||
// GL_KHR_texture_compression_astc_ldr
|
||||
|
||||
// Supported tokens (defined by extensions)
|
||||
// GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93b0
|
||||
// GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93b7
|
||||
|
||||
// ASTC file Header (16 bytes)
|
||||
typedef struct {
|
||||
unsigned char id[4]; // Signature: 0x13 0xAB 0xA1 0x5C
|
||||
unsigned char blockX; // Block X dimensions
|
||||
unsigned char blockY; // Block Y dimensions
|
||||
unsigned char blockZ; // Block Z dimensions (1 for 2D images)
|
||||
unsigned char width[3]; // void *width in pixels (24bit value)
|
||||
unsigned char height[3]; // void *height in pixels (24bit value)
|
||||
unsigned char length[3]; // void *Z-size (1 for 2D images)
|
||||
} astc_header;
|
||||
|
||||
if (file_data_ptr != NULL)
|
||||
{
|
||||
astc_header *header = (astc_header *)file_data_ptr;
|
||||
|
||||
if ((header->id[3] != 0x5c) || (header->id[2] != 0xa1) || (header->id[1] != 0xab) || (header->id[0] != 0x13))
|
||||
{
|
||||
LOG("WARNING: IMAGE: ASTC file data not valid");
|
||||
}
|
||||
else
|
||||
{
|
||||
file_data_ptr += sizeof(astc_header); // Skip header
|
||||
|
||||
// NOTE: Assuming Little Endian (could it be wrong?)
|
||||
*width = 0x00000000 | ((int)header->width[2] << 16) | ((int)header->width[1] << 8) | ((int)header->width[0]);
|
||||
*height = 0x00000000 | ((int)header->height[2] << 16) | ((int)header->height[1] << 8) | ((int)header->height[0]);
|
||||
*mips = 1; // NOTE: ASTC format only contains one mipmap level
|
||||
|
||||
// NOTE: Each block is always stored in 128bit so we can calculate the bpp
|
||||
int bpp = 128/(header->blockX*header->blockY);
|
||||
|
||||
// NOTE: Currently we only support 2 blocks configurations: 4x4 and 8x8
|
||||
if ((bpp == 8) || (bpp == 2))
|
||||
{
|
||||
int data_size = (*width)*(*height)*bpp/8; // Data size in bytes
|
||||
|
||||
image_data = RL_MALLOC(data_size*sizeof(unsigned char));
|
||||
|
||||
memcpy(image_data, file_data_ptr, data_size);
|
||||
|
||||
if (bpp == 8) *format = PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA;
|
||||
else if (bpp == 2) *format = PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA;
|
||||
}
|
||||
else LOG("WARNING: IMAGE: ASTC block size configuration not supported");
|
||||
}
|
||||
}
|
||||
|
||||
return image_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// Get pixel data size in bytes for certain pixel format
|
||||
static int get_pixel_data_size(int width, int height, int format)
|
||||
{
|
||||
int data_size = 0; // Size in bytes
|
||||
int bpp = 0; // Bits per pixel
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: bpp = 8; break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA:
|
||||
case PIXELFORMAT_UNCOMPRESSED_R5G6B5:
|
||||
case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1:
|
||||
case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: bpp = 16; break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: bpp = 32; break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R8G8B8: bpp = 24; break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R32: bpp = 32; break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R32G32B32: bpp = 32*3; break;
|
||||
case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: bpp = 32*4; break;
|
||||
case PIXELFORMAT_COMPRESSED_DXT1_RGB:
|
||||
case PIXELFORMAT_COMPRESSED_DXT1_RGBA:
|
||||
case PIXELFORMAT_COMPRESSED_ETC1_RGB:
|
||||
case PIXELFORMAT_COMPRESSED_ETC2_RGB:
|
||||
case PIXELFORMAT_COMPRESSED_PVRT_RGB:
|
||||
case PIXELFORMAT_COMPRESSED_PVRT_RGBA: bpp = 4; break;
|
||||
case PIXELFORMAT_COMPRESSED_DXT3_RGBA:
|
||||
case PIXELFORMAT_COMPRESSED_DXT5_RGBA:
|
||||
case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA:
|
||||
case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: bpp = 8; break;
|
||||
case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: bpp = 2; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
data_size = width*height*bpp/8; // Total data size in bytes
|
||||
|
||||
// Most compressed formats works on 4x4 blocks,
|
||||
// if texture is smaller, minimum dataSize is 8 or 16
|
||||
if ((width < 4) && (height < 4))
|
||||
{
|
||||
if ((format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) && (format < PIXELFORMAT_COMPRESSED_DXT3_RGBA)) data_size = 8;
|
||||
else if ((format >= PIXELFORMAT_COMPRESSED_DXT3_RGBA) && (format < PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA)) data_size = 16;
|
||||
}
|
||||
|
||||
return data_size;
|
||||
}
|
||||
|
||||
#endif // RL_GPUTEX_IMPLEMENTATION
|
||||
428
src/external/stb_perlin.h
vendored
Normal file
428
src/external/stb_perlin.h
vendored
Normal file
|
|
@ -0,0 +1,428 @@
|
|||
// stb_perlin.h - v0.5 - perlin noise
|
||||
// public domain single-file C implementation by Sean Barrett
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
// See end of file.
|
||||
//
|
||||
//
|
||||
// to create the implementation,
|
||||
// #define STB_PERLIN_IMPLEMENTATION
|
||||
// in *one* C/CPP file that includes this file.
|
||||
//
|
||||
//
|
||||
// Documentation:
|
||||
//
|
||||
// float stb_perlin_noise3( float x,
|
||||
// float y,
|
||||
// float z,
|
||||
// int x_wrap=0,
|
||||
// int y_wrap=0,
|
||||
// int z_wrap=0)
|
||||
//
|
||||
// This function computes a random value at the coordinate (x,y,z).
|
||||
// Adjacent random values are continuous but the noise fluctuates
|
||||
// its randomness with period 1, i.e. takes on wholly unrelated values
|
||||
// at integer points. Specifically, this implements Ken Perlin's
|
||||
// revised noise function from 2002.
|
||||
//
|
||||
// The "wrap" parameters can be used to create wraparound noise that
|
||||
// wraps at powers of two. The numbers MUST be powers of two. Specify
|
||||
// 0 to mean "don't care". (The noise always wraps every 256 due
|
||||
// details of the implementation, even if you ask for larger or no
|
||||
// wrapping.)
|
||||
//
|
||||
// float stb_perlin_noise3_seed( float x,
|
||||
// float y,
|
||||
// float z,
|
||||
// int x_wrap=0,
|
||||
// int y_wrap=0,
|
||||
// int z_wrap=0,
|
||||
// int seed)
|
||||
//
|
||||
// As above, but 'seed' selects from multiple different variations of the
|
||||
// noise function. The current implementation only uses the bottom 8 bits
|
||||
// of 'seed', but possibly in the future more bits will be used.
|
||||
//
|
||||
//
|
||||
// Fractal Noise:
|
||||
//
|
||||
// Three common fractal noise functions are included, which produce
|
||||
// a wide variety of nice effects depending on the parameters
|
||||
// provided. Note that each function will call stb_perlin_noise3
|
||||
// 'octaves' times, so this parameter will affect runtime.
|
||||
//
|
||||
// float stb_perlin_ridge_noise3(float x, float y, float z,
|
||||
// float lacunarity, float gain, float offset, int octaves)
|
||||
//
|
||||
// float stb_perlin_fbm_noise3(float x, float y, float z,
|
||||
// float lacunarity, float gain, int octaves)
|
||||
//
|
||||
// float stb_perlin_turbulence_noise3(float x, float y, float z,
|
||||
// float lacunarity, float gain, int octaves)
|
||||
//
|
||||
// Typical values to start playing with:
|
||||
// octaves = 6 -- number of "octaves" of noise3() to sum
|
||||
// lacunarity = ~ 2.0 -- spacing between successive octaves (use exactly 2.0 for wrapping output)
|
||||
// gain = 0.5 -- relative weighting applied to each successive octave
|
||||
// offset = 1.0? -- used to invert the ridges, may need to be larger, not sure
|
||||
//
|
||||
//
|
||||
// Contributors:
|
||||
// Jack Mott - additional noise functions
|
||||
// Jordan Peck - seeded noise
|
||||
//
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap);
|
||||
extern float stb_perlin_noise3_seed(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, int seed);
|
||||
extern float stb_perlin_ridge_noise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves);
|
||||
extern float stb_perlin_fbm_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
|
||||
extern float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves);
|
||||
extern float stb_perlin_noise3_wrap_nonpow2(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef STB_PERLIN_IMPLEMENTATION
|
||||
|
||||
#include <math.h> // fabs()
|
||||
|
||||
// not same permutation table as Perlin's reference to avoid copyright issues;
|
||||
// Perlin's table can be found at http://mrl.nyu.edu/~perlin/noise/
|
||||
static unsigned char stb__perlin_randtab[512] =
|
||||
{
|
||||
23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
|
||||
152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72,
|
||||
175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240,
|
||||
8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57,
|
||||
225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233,
|
||||
94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172,
|
||||
165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243,
|
||||
65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122,
|
||||
26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76,
|
||||
250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246,
|
||||
132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3,
|
||||
91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231,
|
||||
38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221,
|
||||
131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62,
|
||||
27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135,
|
||||
61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
|
||||
|
||||
// and a second copy so we don't need an extra mask or static initializer
|
||||
23, 125, 161, 52, 103, 117, 70, 37, 247, 101, 203, 169, 124, 126, 44, 123,
|
||||
152, 238, 145, 45, 171, 114, 253, 10, 192, 136, 4, 157, 249, 30, 35, 72,
|
||||
175, 63, 77, 90, 181, 16, 96, 111, 133, 104, 75, 162, 93, 56, 66, 240,
|
||||
8, 50, 84, 229, 49, 210, 173, 239, 141, 1, 87, 18, 2, 198, 143, 57,
|
||||
225, 160, 58, 217, 168, 206, 245, 204, 199, 6, 73, 60, 20, 230, 211, 233,
|
||||
94, 200, 88, 9, 74, 155, 33, 15, 219, 130, 226, 202, 83, 236, 42, 172,
|
||||
165, 218, 55, 222, 46, 107, 98, 154, 109, 67, 196, 178, 127, 158, 13, 243,
|
||||
65, 79, 166, 248, 25, 224, 115, 80, 68, 51, 184, 128, 232, 208, 151, 122,
|
||||
26, 212, 105, 43, 179, 213, 235, 148, 146, 89, 14, 195, 28, 78, 112, 76,
|
||||
250, 47, 24, 251, 140, 108, 186, 190, 228, 170, 183, 139, 39, 188, 244, 246,
|
||||
132, 48, 119, 144, 180, 138, 134, 193, 82, 182, 120, 121, 86, 220, 209, 3,
|
||||
91, 241, 149, 85, 205, 150, 113, 216, 31, 100, 41, 164, 177, 214, 153, 231,
|
||||
38, 71, 185, 174, 97, 201, 29, 95, 7, 92, 54, 254, 191, 118, 34, 221,
|
||||
131, 11, 163, 99, 234, 81, 227, 147, 156, 176, 17, 142, 69, 12, 110, 62,
|
||||
27, 255, 0, 194, 59, 116, 242, 252, 19, 21, 187, 53, 207, 129, 64, 135,
|
||||
61, 40, 167, 237, 102, 223, 106, 159, 197, 189, 215, 137, 36, 32, 22, 5,
|
||||
};
|
||||
|
||||
|
||||
// perlin's gradient has 12 cases so some get used 1/16th of the time
|
||||
// and some 2/16ths. We reduce bias by changing those fractions
|
||||
// to 5/64ths and 6/64ths
|
||||
|
||||
// this array is designed to match the previous implementation
|
||||
// of gradient hash: indices[stb__perlin_randtab[i]&63]
|
||||
static unsigned char stb__perlin_randtab_grad_idx[512] =
|
||||
{
|
||||
7, 9, 5, 0, 11, 1, 6, 9, 3, 9, 11, 1, 8, 10, 4, 7,
|
||||
8, 6, 1, 5, 3, 10, 9, 10, 0, 8, 4, 1, 5, 2, 7, 8,
|
||||
7, 11, 9, 10, 1, 0, 4, 7, 5, 0, 11, 6, 1, 4, 2, 8,
|
||||
8, 10, 4, 9, 9, 2, 5, 7, 9, 1, 7, 2, 2, 6, 11, 5,
|
||||
5, 4, 6, 9, 0, 1, 1, 0, 7, 6, 9, 8, 4, 10, 3, 1,
|
||||
2, 8, 8, 9, 10, 11, 5, 11, 11, 2, 6, 10, 3, 4, 2, 4,
|
||||
9, 10, 3, 2, 6, 3, 6, 10, 5, 3, 4, 10, 11, 2, 9, 11,
|
||||
1, 11, 10, 4, 9, 4, 11, 0, 4, 11, 4, 0, 0, 0, 7, 6,
|
||||
10, 4, 1, 3, 11, 5, 3, 4, 2, 9, 1, 3, 0, 1, 8, 0,
|
||||
6, 7, 8, 7, 0, 4, 6, 10, 8, 2, 3, 11, 11, 8, 0, 2,
|
||||
4, 8, 3, 0, 0, 10, 6, 1, 2, 2, 4, 5, 6, 0, 1, 3,
|
||||
11, 9, 5, 5, 9, 6, 9, 8, 3, 8, 1, 8, 9, 6, 9, 11,
|
||||
10, 7, 5, 6, 5, 9, 1, 3, 7, 0, 2, 10, 11, 2, 6, 1,
|
||||
3, 11, 7, 7, 2, 1, 7, 3, 0, 8, 1, 1, 5, 0, 6, 10,
|
||||
11, 11, 0, 2, 7, 0, 10, 8, 3, 5, 7, 1, 11, 1, 0, 7,
|
||||
9, 0, 11, 5, 10, 3, 2, 3, 5, 9, 7, 9, 8, 4, 6, 5,
|
||||
|
||||
// and a second copy so we don't need an extra mask or static initializer
|
||||
7, 9, 5, 0, 11, 1, 6, 9, 3, 9, 11, 1, 8, 10, 4, 7,
|
||||
8, 6, 1, 5, 3, 10, 9, 10, 0, 8, 4, 1, 5, 2, 7, 8,
|
||||
7, 11, 9, 10, 1, 0, 4, 7, 5, 0, 11, 6, 1, 4, 2, 8,
|
||||
8, 10, 4, 9, 9, 2, 5, 7, 9, 1, 7, 2, 2, 6, 11, 5,
|
||||
5, 4, 6, 9, 0, 1, 1, 0, 7, 6, 9, 8, 4, 10, 3, 1,
|
||||
2, 8, 8, 9, 10, 11, 5, 11, 11, 2, 6, 10, 3, 4, 2, 4,
|
||||
9, 10, 3, 2, 6, 3, 6, 10, 5, 3, 4, 10, 11, 2, 9, 11,
|
||||
1, 11, 10, 4, 9, 4, 11, 0, 4, 11, 4, 0, 0, 0, 7, 6,
|
||||
10, 4, 1, 3, 11, 5, 3, 4, 2, 9, 1, 3, 0, 1, 8, 0,
|
||||
6, 7, 8, 7, 0, 4, 6, 10, 8, 2, 3, 11, 11, 8, 0, 2,
|
||||
4, 8, 3, 0, 0, 10, 6, 1, 2, 2, 4, 5, 6, 0, 1, 3,
|
||||
11, 9, 5, 5, 9, 6, 9, 8, 3, 8, 1, 8, 9, 6, 9, 11,
|
||||
10, 7, 5, 6, 5, 9, 1, 3, 7, 0, 2, 10, 11, 2, 6, 1,
|
||||
3, 11, 7, 7, 2, 1, 7, 3, 0, 8, 1, 1, 5, 0, 6, 10,
|
||||
11, 11, 0, 2, 7, 0, 10, 8, 3, 5, 7, 1, 11, 1, 0, 7,
|
||||
9, 0, 11, 5, 10, 3, 2, 3, 5, 9, 7, 9, 8, 4, 6, 5,
|
||||
};
|
||||
|
||||
static float stb__perlin_lerp(float a, float b, float t)
|
||||
{
|
||||
return a + (b-a) * t;
|
||||
}
|
||||
|
||||
static int stb__perlin_fastfloor(float a)
|
||||
{
|
||||
int ai = (int) a;
|
||||
return (a < ai) ? ai-1 : ai;
|
||||
}
|
||||
|
||||
// different grad function from Perlin's, but easy to modify to match reference
|
||||
static float stb__perlin_grad(int grad_idx, float x, float y, float z)
|
||||
{
|
||||
static float basis[12][4] =
|
||||
{
|
||||
{ 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 },
|
||||
};
|
||||
|
||||
float *grad = basis[grad_idx];
|
||||
return grad[0]*x + grad[1]*y + grad[2]*z;
|
||||
}
|
||||
|
||||
float stb_perlin_noise3_internal(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed)
|
||||
{
|
||||
float u,v,w;
|
||||
float n000,n001,n010,n011,n100,n101,n110,n111;
|
||||
float n00,n01,n10,n11;
|
||||
float n0,n1;
|
||||
|
||||
unsigned int x_mask = (x_wrap-1) & 255;
|
||||
unsigned int y_mask = (y_wrap-1) & 255;
|
||||
unsigned int z_mask = (z_wrap-1) & 255;
|
||||
int px = stb__perlin_fastfloor(x);
|
||||
int py = stb__perlin_fastfloor(y);
|
||||
int pz = stb__perlin_fastfloor(z);
|
||||
int x0 = px & x_mask, x1 = (px+1) & x_mask;
|
||||
int y0 = py & y_mask, y1 = (py+1) & y_mask;
|
||||
int z0 = pz & z_mask, z1 = (pz+1) & z_mask;
|
||||
int r0,r1, r00,r01,r10,r11;
|
||||
|
||||
#define stb__perlin_ease(a) (((a*6-15)*a + 10) * a * a * a)
|
||||
|
||||
x -= px; u = stb__perlin_ease(x);
|
||||
y -= py; v = stb__perlin_ease(y);
|
||||
z -= pz; w = stb__perlin_ease(z);
|
||||
|
||||
r0 = stb__perlin_randtab[x0+seed];
|
||||
r1 = stb__perlin_randtab[x1+seed];
|
||||
|
||||
r00 = stb__perlin_randtab[r0+y0];
|
||||
r01 = stb__perlin_randtab[r0+y1];
|
||||
r10 = stb__perlin_randtab[r1+y0];
|
||||
r11 = stb__perlin_randtab[r1+y1];
|
||||
|
||||
n000 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z0], x , y , z );
|
||||
n001 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z1], x , y , z-1 );
|
||||
n010 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z0], x , y-1, z );
|
||||
n011 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z1], x , y-1, z-1 );
|
||||
n100 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z0], x-1, y , z );
|
||||
n101 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z1], x-1, y , z-1 );
|
||||
n110 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z0], x-1, y-1, z );
|
||||
n111 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z1], x-1, y-1, z-1 );
|
||||
|
||||
n00 = stb__perlin_lerp(n000,n001,w);
|
||||
n01 = stb__perlin_lerp(n010,n011,w);
|
||||
n10 = stb__perlin_lerp(n100,n101,w);
|
||||
n11 = stb__perlin_lerp(n110,n111,w);
|
||||
|
||||
n0 = stb__perlin_lerp(n00,n01,v);
|
||||
n1 = stb__perlin_lerp(n10,n11,v);
|
||||
|
||||
return stb__perlin_lerp(n0,n1,u);
|
||||
}
|
||||
|
||||
float stb_perlin_noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap)
|
||||
{
|
||||
return stb_perlin_noise3_internal(x,y,z,x_wrap,y_wrap,z_wrap,0);
|
||||
}
|
||||
|
||||
float stb_perlin_noise3_seed(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, int seed)
|
||||
{
|
||||
return stb_perlin_noise3_internal(x,y,z,x_wrap,y_wrap,z_wrap, (unsigned char) seed);
|
||||
}
|
||||
|
||||
float stb_perlin_ridge_noise3(float x, float y, float z, float lacunarity, float gain, float offset, int octaves)
|
||||
{
|
||||
int i;
|
||||
float frequency = 1.0f;
|
||||
float prev = 1.0f;
|
||||
float amplitude = 0.5f;
|
||||
float sum = 0.0f;
|
||||
|
||||
for (i = 0; i < octaves; i++) {
|
||||
float r = stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i);
|
||||
r = offset - (float) fabs(r);
|
||||
r = r*r;
|
||||
sum += r*amplitude*prev;
|
||||
prev = r;
|
||||
frequency *= lacunarity;
|
||||
amplitude *= gain;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
float stb_perlin_fbm_noise3(float x, float y, float z, float lacunarity, float gain, int octaves)
|
||||
{
|
||||
int i;
|
||||
float frequency = 1.0f;
|
||||
float amplitude = 1.0f;
|
||||
float sum = 0.0f;
|
||||
|
||||
for (i = 0; i < octaves; i++) {
|
||||
sum += stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i)*amplitude;
|
||||
frequency *= lacunarity;
|
||||
amplitude *= gain;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
float stb_perlin_turbulence_noise3(float x, float y, float z, float lacunarity, float gain, int octaves)
|
||||
{
|
||||
int i;
|
||||
float frequency = 1.0f;
|
||||
float amplitude = 1.0f;
|
||||
float sum = 0.0f;
|
||||
|
||||
for (i = 0; i < octaves; i++) {
|
||||
float r = stb_perlin_noise3_internal(x*frequency,y*frequency,z*frequency,0,0,0,(unsigned char)i)*amplitude;
|
||||
sum += (float) fabs(r);
|
||||
frequency *= lacunarity;
|
||||
amplitude *= gain;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
float stb_perlin_noise3_wrap_nonpow2(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap, unsigned char seed)
|
||||
{
|
||||
float u,v,w;
|
||||
float n000,n001,n010,n011,n100,n101,n110,n111;
|
||||
float n00,n01,n10,n11;
|
||||
float n0,n1;
|
||||
|
||||
int px = stb__perlin_fastfloor(x);
|
||||
int py = stb__perlin_fastfloor(y);
|
||||
int pz = stb__perlin_fastfloor(z);
|
||||
int x_wrap2 = (x_wrap ? x_wrap : 256);
|
||||
int y_wrap2 = (y_wrap ? y_wrap : 256);
|
||||
int z_wrap2 = (z_wrap ? z_wrap : 256);
|
||||
int x0 = px % x_wrap2, x1;
|
||||
int y0 = py % y_wrap2, y1;
|
||||
int z0 = pz % z_wrap2, z1;
|
||||
int r0,r1, r00,r01,r10,r11;
|
||||
|
||||
if (x0 < 0) x0 += x_wrap2;
|
||||
if (y0 < 0) y0 += y_wrap2;
|
||||
if (z0 < 0) z0 += z_wrap2;
|
||||
x1 = (x0+1) % x_wrap2;
|
||||
y1 = (y0+1) % y_wrap2;
|
||||
z1 = (z0+1) % z_wrap2;
|
||||
|
||||
#define stb__perlin_ease(a) (((a*6-15)*a + 10) * a * a * a)
|
||||
|
||||
x -= px; u = stb__perlin_ease(x);
|
||||
y -= py; v = stb__perlin_ease(y);
|
||||
z -= pz; w = stb__perlin_ease(z);
|
||||
|
||||
r0 = stb__perlin_randtab[x0];
|
||||
r0 = stb__perlin_randtab[r0+seed];
|
||||
r1 = stb__perlin_randtab[x1];
|
||||
r1 = stb__perlin_randtab[r1+seed];
|
||||
|
||||
r00 = stb__perlin_randtab[r0+y0];
|
||||
r01 = stb__perlin_randtab[r0+y1];
|
||||
r10 = stb__perlin_randtab[r1+y0];
|
||||
r11 = stb__perlin_randtab[r1+y1];
|
||||
|
||||
n000 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z0], x , y , z );
|
||||
n001 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r00+z1], x , y , z-1 );
|
||||
n010 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z0], x , y-1, z );
|
||||
n011 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r01+z1], x , y-1, z-1 );
|
||||
n100 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z0], x-1, y , z );
|
||||
n101 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r10+z1], x-1, y , z-1 );
|
||||
n110 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z0], x-1, y-1, z );
|
||||
n111 = stb__perlin_grad(stb__perlin_randtab_grad_idx[r11+z1], x-1, y-1, z-1 );
|
||||
|
||||
n00 = stb__perlin_lerp(n000,n001,w);
|
||||
n01 = stb__perlin_lerp(n010,n011,w);
|
||||
n10 = stb__perlin_lerp(n100,n101,w);
|
||||
n11 = stb__perlin_lerp(n110,n111,w);
|
||||
|
||||
n0 = stb__perlin_lerp(n00,n01,v);
|
||||
n1 = stb__perlin_lerp(n10,n11,v);
|
||||
|
||||
return stb__perlin_lerp(n0,n1,u);
|
||||
}
|
||||
#endif // STB_PERLIN_IMPLEMENTATION
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
18
src/raylib.h
18
src/raylib.h
|
|
@ -1241,6 +1241,7 @@ RLAPI Image GenImageGradientH(int width, int height, Color left, Color right);
|
|||
RLAPI Image GenImageGradientRadial(int width, int height, float density, Color inner, Color outer); // Generate image: radial gradient
|
||||
RLAPI Image GenImageChecked(int width, int height, int checksX, int checksY, Color col1, Color col2); // Generate image: checked
|
||||
RLAPI Image GenImageWhiteNoise(int width, int height, float factor); // Generate image: white noise
|
||||
RLAPI Image GenImagePerlinNoise(int width, int height, int offsetX, int offsetY, float scale); // Generate image: perlin noise
|
||||
RLAPI Image GenImageCellular(int width, int height, int tileSize); // Generate image: cellular algorithm, bigger tileSize means bigger cells
|
||||
|
||||
// Image manipulation functions
|
||||
|
|
@ -1286,6 +1287,8 @@ RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX,
|
|||
RLAPI void ImageDrawLineV(Image *dst, Vector2 start, Vector2 end, Color color); // Draw line within an image (Vector version)
|
||||
RLAPI void ImageDrawCircle(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle within an image
|
||||
RLAPI void ImageDrawCircleV(Image *dst, Vector2 center, int radius, Color color); // Draw circle within an image (Vector version)
|
||||
RLAPI void ImageDrawCircleLines(Image *dst, int centerX, int centerY, int radius, Color color); // Draw circle outline within an image
|
||||
RLAPI void ImageDrawCircleLinesV(Image *dst, Vector2 center, int radius, Color color); // Draw circle outline within an image (Vector version)
|
||||
RLAPI void ImageDrawRectangle(Image *dst, int posX, int posY, int width, int height, Color color); // Draw rectangle within an image
|
||||
RLAPI void ImageDrawRectangleV(Image *dst, Vector2 position, Vector2 size, Color color); // Draw rectangle within an image (Vector version)
|
||||
RLAPI void ImageDrawRectangleRec(Image *dst, Rectangle rec, Color color); // Draw rectangle within an image
|
||||
|
|
@ -1367,12 +1370,15 @@ RLAPI GlyphInfo GetGlyphInfo(Font font, int codepoint);
|
|||
RLAPI Rectangle GetGlyphAtlasRec(Font font, int codepoint); // Get glyph rectangle in font atlas for a codepoint (unicode character), fallback to '?' if not found
|
||||
|
||||
// Text codepoints management functions (unicode characters)
|
||||
RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
|
||||
RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory
|
||||
RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string
|
||||
RLAPI int GetCodepoint(const char *text, int *bytesProcessed); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI const char *CodepointToUTF8(int codepoint, int *byteSize); // Encode one codepoint into UTF-8 byte array (array length returned as parameter)
|
||||
RLAPI char *TextCodepointsToUTF8(const int *codepoints, int length); // Encode text as codepoints array into UTF-8 text string (WARNING: memory must be freed!)
|
||||
RLAPI char *LoadUTF8(const int *codepoints, int length); // Load UTF-8 text encoded from codepoints array
|
||||
RLAPI void UnloadUTF8(char *text); // Unload UTF-8 text encoded from codepoints array
|
||||
RLAPI int *LoadCodepoints(const char *text, int *count); // Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
|
||||
RLAPI void UnloadCodepoints(int *codepoints); // Unload codepoints data from memory
|
||||
RLAPI int GetCodepointCount(const char *text); // Get total number of codepoints in a UTF-8 encoded string
|
||||
RLAPI int GetCodepoint(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI int GetCodepointNext(const char *text, int *codepointSize); // Get next codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI int GetCodepointPrevious(const char *text, int *codepointSize); // Get previous codepoint in a UTF-8 encoded string, 0x3f('?') is returned on failure
|
||||
RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size); // Encode one codepoint into UTF-8 byte array (array length returned as parameter)
|
||||
|
||||
// Text strings management functions (no UTF-8 strings, only byte chars)
|
||||
// NOTE: Some strings allocate memory internally for returned strings, just be careful!
|
||||
|
|
|
|||
176
src/rcore.c
176
src/rcore.c
|
|
@ -1971,7 +1971,7 @@ void EnableEventWaiting(void)
|
|||
}
|
||||
|
||||
// Disable waiting for events on EndDrawing(), automatic events polling
|
||||
RLAPI void DisableEventWaiting(void)
|
||||
void DisableEventWaiting(void)
|
||||
{
|
||||
CORE.Window.eventWaiting = false;
|
||||
}
|
||||
|
|
@ -2472,7 +2472,7 @@ Shader LoadShader(const char *vsFileName, const char *fsFileName)
|
|||
}
|
||||
|
||||
// Load shader from code strings and bind default locations
|
||||
RLAPI Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
|
||||
Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode)
|
||||
{
|
||||
Shader shader = { 0 };
|
||||
shader.locs = (int *)RL_CALLOC(RL_MAX_SHADER_LOCATIONS, sizeof(int));
|
||||
|
|
@ -3872,22 +3872,7 @@ Vector2 GetTouchPosition(int index)
|
|||
// https://docs.microsoft.com/en-us/windows/win32/wintouch/getting-started-with-multi-touch-messages
|
||||
if (index == 0) position = GetMousePosition();
|
||||
#endif
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
if (index < MAX_TOUCH_POINTS) position = CORE.Input.Touch.position[index];
|
||||
else TRACELOG(LOG_WARNING, "INPUT: Required touch point out of range (Max touch points: %i)", MAX_TOUCH_POINTS);
|
||||
|
||||
if ((CORE.Window.screen.width > CORE.Window.display.width) || (CORE.Window.screen.height > CORE.Window.display.height))
|
||||
{
|
||||
position.x = position.x*((float)CORE.Window.screen.width/(float)(CORE.Window.display.width - CORE.Window.renderOffset.x)) - CORE.Window.renderOffset.x/2;
|
||||
position.y = position.y*((float)CORE.Window.screen.height/(float)(CORE.Window.display.height - CORE.Window.renderOffset.y)) - CORE.Window.renderOffset.y/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
position.x = position.x*((float)CORE.Window.render.width/(float)CORE.Window.display.width) - CORE.Window.renderOffset.x/2;
|
||||
position.y = position.y*((float)CORE.Window.render.height/(float)CORE.Window.display.height) - CORE.Window.renderOffset.y/2;
|
||||
}
|
||||
#endif
|
||||
#if defined(PLATFORM_WEB) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB) || defined(PLATFORM_RPI) || defined(PLATFORM_DRM)
|
||||
if (index < MAX_TOUCH_POINTS) position = CORE.Input.Touch.position[index];
|
||||
else TRACELOG(LOG_WARNING, "INPUT: Required touch point out of range (Max touch points: %i)", MAX_TOUCH_POINTS);
|
||||
#endif
|
||||
|
|
@ -4038,9 +4023,9 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
glfwWindowHint(GLFW_SAMPLES, 4); // Tries to enable multisampling x4 (MSAA), default is 0
|
||||
}
|
||||
|
||||
// NOTE: When asking for an OpenGL context version, most drivers provide highest supported version
|
||||
// with forward compatibility to older OpenGL versions.
|
||||
// For example, if using OpenGL 1.1, driver can provide a 4.3 context forward compatible.
|
||||
// NOTE: When asking for an OpenGL context version, most drivers provide the highest supported version
|
||||
// with backward compatibility to older OpenGL versions.
|
||||
// For example, if using OpenGL 1.1, driver can provide a 4.3 backwards compatible context.
|
||||
|
||||
// Check selection OpenGL version
|
||||
if (rlGetVersion() == RL_OPENGL_21)
|
||||
|
|
@ -5414,7 +5399,7 @@ static void ScanDirectoryFiles(const char *basePath, FilePathList *files, const
|
|||
// Scan all files and directories recursively from a base path
|
||||
static void ScanDirectoryFilesRecursively(const char *basePath, FilePathList *files, const char *filter)
|
||||
{
|
||||
static char path[MAX_FILEPATH_LENGTH] = { 0 };
|
||||
char path[MAX_FILEPATH_LENGTH] = { 0 };
|
||||
memset(path, 0, MAX_FILEPATH_LENGTH);
|
||||
|
||||
struct dirent *dp = NULL;
|
||||
|
|
@ -5752,7 +5737,14 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
// Reset screen scaling to full display size
|
||||
EGLint displayFormat = 0;
|
||||
eglGetConfigAttrib(CORE.Window.device, CORE.Window.config, EGL_NATIVE_VISUAL_ID, &displayFormat);
|
||||
ANativeWindow_setBuffersGeometry(app->window, CORE.Window.render.width, CORE.Window.render.height, displayFormat);
|
||||
|
||||
// Adding renderOffset here feels rather hackish, but the viewport scaling is wrong after the
|
||||
// context rebinding if the screen is scaled unless offsets are added. There's probably a more
|
||||
// appropriate way to fix this
|
||||
ANativeWindow_setBuffersGeometry(app->window,
|
||||
CORE.Window.render.width + CORE.Window.renderOffset.x,
|
||||
CORE.Window.render.height + CORE.Window.renderOffset.y,
|
||||
displayFormat);
|
||||
|
||||
// Recreate display surface and re-attach OpenGL context
|
||||
CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, app->window, NULL);
|
||||
|
|
@ -5841,6 +5833,32 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
|||
}
|
||||
}
|
||||
|
||||
static GamepadButton AndroidTranslateGamepadButton(int button)
|
||||
{
|
||||
switch (button)
|
||||
{
|
||||
case AKEYCODE_BUTTON_A: return GAMEPAD_BUTTON_RIGHT_FACE_DOWN;
|
||||
case AKEYCODE_BUTTON_B: return GAMEPAD_BUTTON_RIGHT_FACE_RIGHT;
|
||||
case AKEYCODE_BUTTON_X: return GAMEPAD_BUTTON_RIGHT_FACE_LEFT;
|
||||
case AKEYCODE_BUTTON_Y: return GAMEPAD_BUTTON_RIGHT_FACE_UP;
|
||||
case AKEYCODE_BUTTON_L1: return GAMEPAD_BUTTON_LEFT_TRIGGER_1;
|
||||
case AKEYCODE_BUTTON_R1: return GAMEPAD_BUTTON_RIGHT_TRIGGER_1;
|
||||
case AKEYCODE_BUTTON_L2: return GAMEPAD_BUTTON_LEFT_TRIGGER_2;
|
||||
case AKEYCODE_BUTTON_R2: return GAMEPAD_BUTTON_RIGHT_TRIGGER_2;
|
||||
case AKEYCODE_BUTTON_THUMBL: return GAMEPAD_BUTTON_LEFT_THUMB;
|
||||
case AKEYCODE_BUTTON_THUMBR: return GAMEPAD_BUTTON_RIGHT_THUMB;
|
||||
case AKEYCODE_BUTTON_START: return GAMEPAD_BUTTON_MIDDLE_RIGHT;
|
||||
case AKEYCODE_BUTTON_SELECT: return GAMEPAD_BUTTON_MIDDLE_LEFT;
|
||||
case AKEYCODE_BUTTON_MODE: return GAMEPAD_BUTTON_MIDDLE;
|
||||
// On some (most?) gamepads dpad events are reported as axis motion instead
|
||||
case AKEYCODE_DPAD_DOWN: return GAMEPAD_BUTTON_LEFT_FACE_DOWN;
|
||||
case AKEYCODE_DPAD_RIGHT: return GAMEPAD_BUTTON_LEFT_FACE_RIGHT;
|
||||
case AKEYCODE_DPAD_LEFT: return GAMEPAD_BUTTON_LEFT_FACE_LEFT;
|
||||
case AKEYCODE_DPAD_UP: return GAMEPAD_BUTTON_LEFT_FACE_UP;
|
||||
default: return GAMEPAD_BUTTON_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
// ANDROID: Get input events
|
||||
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
||||
{
|
||||
|
|
@ -5856,26 +5874,59 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||
if (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) ||
|
||||
((source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD))
|
||||
{
|
||||
// Get first touch position
|
||||
CORE.Input.Touch.position[0].x = AMotionEvent_getX(event, 0);
|
||||
CORE.Input.Touch.position[0].y = AMotionEvent_getY(event, 0);
|
||||
// For now we'll assume a single gamepad which we "detect" on its input event
|
||||
CORE.Input.Gamepad.ready[0] = true;
|
||||
|
||||
// Get second touch position
|
||||
CORE.Input.Touch.position[1].x = AMotionEvent_getX(event, 1);
|
||||
CORE.Input.Touch.position[1].y = AMotionEvent_getY(event, 1);
|
||||
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_X] = AMotionEvent_getAxisValue(
|
||||
event, AMOTION_EVENT_AXIS_X, 0);
|
||||
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_Y] = AMotionEvent_getAxisValue(
|
||||
event, AMOTION_EVENT_AXIS_Y, 0);
|
||||
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_X] = AMotionEvent_getAxisValue(
|
||||
event, AMOTION_EVENT_AXIS_Z, 0);
|
||||
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_Y] = AMotionEvent_getAxisValue(
|
||||
event, AMOTION_EVENT_AXIS_RZ, 0);
|
||||
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_LEFT_TRIGGER] = AMotionEvent_getAxisValue(
|
||||
event, AMOTION_EVENT_AXIS_BRAKE, 0) * 2.0f - 1.0f;
|
||||
CORE.Input.Gamepad.axisState[0][GAMEPAD_AXIS_RIGHT_TRIGGER] = AMotionEvent_getAxisValue(
|
||||
event, AMOTION_EVENT_AXIS_GAS, 0) * 2.0f - 1.0f;
|
||||
|
||||
int32_t keycode = AKeyEvent_getKeyCode(event);
|
||||
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
|
||||
// dpad is reported as an axis on android
|
||||
float dpadX = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_X, 0);
|
||||
float dpadY = AMotionEvent_getAxisValue(event, AMOTION_EVENT_AXIS_HAT_Y, 0);
|
||||
|
||||
if (dpadX == 1.0f)
|
||||
{
|
||||
CORE.Input.Keyboard.currentKeyState[keycode] = 1; // Key down
|
||||
|
||||
CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = keycode;
|
||||
CORE.Input.Keyboard.keyPressedQueueCount++;
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_RIGHT] = 1;
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_LEFT] = 0;
|
||||
}
|
||||
else if (dpadX == -1.0f)
|
||||
{
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_RIGHT] = 0;
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_LEFT] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_RIGHT] = 0;
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_LEFT] = 0;
|
||||
}
|
||||
else CORE.Input.Keyboard.currentKeyState[keycode] = 0; // Key up
|
||||
|
||||
// Stop processing gamepad buttons
|
||||
return 1;
|
||||
if (dpadY == 1.0f)
|
||||
{
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_DOWN] = 1;
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_UP] = 0;
|
||||
}
|
||||
else if (dpadY == -1.0f)
|
||||
{
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_DOWN] = 0;
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_UP] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_DOWN] = 0;
|
||||
CORE.Input.Gamepad.currentButtonState[0][GAMEPAD_BUTTON_LEFT_FACE_UP] = 0;
|
||||
}
|
||||
|
||||
return 1; // Handled gamepad axis motion
|
||||
}
|
||||
}
|
||||
else if (type == AINPUT_EVENT_TYPE_KEY)
|
||||
|
|
@ -5883,6 +5934,25 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||
int32_t keycode = AKeyEvent_getKeyCode(event);
|
||||
//int32_t AKeyEvent_getMetaState(event);
|
||||
|
||||
// Handle gamepad button presses and releases
|
||||
if (((source & AINPUT_SOURCE_JOYSTICK) == AINPUT_SOURCE_JOYSTICK) ||
|
||||
((source & AINPUT_SOURCE_GAMEPAD) == AINPUT_SOURCE_GAMEPAD))
|
||||
{
|
||||
// For now we'll assume a single gamepad which we "detect" on its input event
|
||||
CORE.Input.Gamepad.ready[0] = true;
|
||||
|
||||
GamepadButton button = AndroidTranslateGamepadButton(keycode);
|
||||
if (button == GAMEPAD_BUTTON_UNKNOWN)
|
||||
return 1;
|
||||
|
||||
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
|
||||
{
|
||||
CORE.Input.Gamepad.currentButtonState[0][button] = 1;
|
||||
}
|
||||
else CORE.Input.Gamepad.currentButtonState[0][button] = 0; // Key up
|
||||
return 1; // Handled gamepad button
|
||||
}
|
||||
|
||||
// Save current button and its state
|
||||
// NOTE: Android key action is 0 for down and 1 for up
|
||||
if (AKeyEvent_getAction(event) == AKEY_EVENT_ACTION_DOWN)
|
||||
|
|
@ -5928,17 +5998,16 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||
// Register touch points position
|
||||
CORE.Input.Touch.position[i] = (Vector2){ AMotionEvent_getX(event, i), AMotionEvent_getY(event, i) };
|
||||
|
||||
// Normalize CORE.Input.Touch.position[x] for screenWidth and screenHeight
|
||||
CORE.Input.Touch.position[i].x /= (float)GetScreenWidth();
|
||||
CORE.Input.Touch.position[i].y /= (float)GetScreenHeight();
|
||||
// Normalize CORE.Input.Touch.position[i] for CORE.Window.screen.width and CORE.Window.screen.height
|
||||
float widthRatio = (float)(CORE.Window.screen.width + CORE.Window.renderOffset.x) / (float)CORE.Window.display.width;
|
||||
float heightRatio = (float)(CORE.Window.screen.height + CORE.Window.renderOffset.y) / (float)CORE.Window.display.height;
|
||||
CORE.Input.Touch.position[i].x = CORE.Input.Touch.position[i].x * widthRatio - (float)CORE.Window.renderOffset.x / 2;
|
||||
CORE.Input.Touch.position[i].y = CORE.Input.Touch.position[i].y * heightRatio - (float)CORE.Window.renderOffset.y / 2;
|
||||
}
|
||||
|
||||
int32_t action = AMotionEvent_getAction(event);
|
||||
unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
|
||||
|
||||
if (flags == AMOTION_EVENT_ACTION_DOWN || flags == AMOTION_EVENT_ACTION_MOVE) CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 1;
|
||||
else if (flags == AMOTION_EVENT_ACTION_UP) CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 0;
|
||||
|
||||
#if defined(SUPPORT_GESTURES_SYSTEM) // PLATFORM_ANDROID
|
||||
GestureEvent gestureEvent = { 0 };
|
||||
|
||||
|
|
@ -5960,6 +6029,25 @@ static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
|||
ProcessGestureEvent(gestureEvent);
|
||||
#endif
|
||||
|
||||
int32_t pointerIndex = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
||||
|
||||
if (flags == AMOTION_EVENT_ACTION_POINTER_UP || flags == AMOTION_EVENT_ACTION_UP)
|
||||
{
|
||||
// One of the touchpoints is released, remove it from touch point arrays
|
||||
for (int i = pointerIndex; (i < CORE.Input.Touch.pointCount-1) && (i < MAX_TOUCH_POINTS); i++)
|
||||
{
|
||||
CORE.Input.Touch.pointId[i] = CORE.Input.Touch.pointId[i+1];
|
||||
CORE.Input.Touch.position[i] = CORE.Input.Touch.position[i+1];
|
||||
}
|
||||
CORE.Input.Touch.pointCount--;
|
||||
}
|
||||
|
||||
// When all touchpoints are tapped and released really quickly, this event is generated
|
||||
if (flags == AMOTION_EVENT_ACTION_CANCEL) CORE.Input.Touch.pointCount = 0;
|
||||
|
||||
if (CORE.Input.Touch.pointCount > 0) CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 1;
|
||||
else CORE.Input.Touch.currentTouchState[MOUSE_BUTTON_LEFT] = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
230
src/rlgl.h
230
src/rlgl.h
|
|
@ -741,16 +741,11 @@ RLAPI void rlLoadDrawQuad(void); // Load and draw a quad
|
|||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33)
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/gl3.h> // OpenGL 3 library for OSX
|
||||
#include <OpenGL/gl3ext.h> // OpenGL 3 extensions library for OSX
|
||||
#else
|
||||
#define GLAD_MALLOC RL_MALLOC
|
||||
#define GLAD_FREE RL_FREE
|
||||
#define GLAD_MALLOC RL_MALLOC
|
||||
#define GLAD_FREE RL_FREE
|
||||
|
||||
#define GLAD_GL_IMPLEMENTATION
|
||||
#include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers
|
||||
#endif
|
||||
#define GLAD_GL_IMPLEMENTATION
|
||||
#include "external/glad.h" // GLAD extensions loading library, includes OpenGL headers
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
|
|
@ -995,14 +990,12 @@ static void rlUnloadShaderDefault(void); // Unload default shader
|
|||
static char *rlGetCompressedFormatName(int format); // Get compressed format official GL identifier name
|
||||
#endif // RLGL_SHOW_GL_DETAILS_INFO
|
||||
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
static int rlGenTextureMipmapsData(unsigned char *data, int baseWidth, int baseHeight); // Generate mipmaps data on CPU side
|
||||
static unsigned char *rlGenNextMipmapData(unsigned char *srcData, int srcWidth, int srcHeight); // Generate next mipmap level on CPU side
|
||||
#endif
|
||||
|
||||
static int rlGetPixelDataSize(int width, int height, int format); // Get pixel data size in bytes (image or texture)
|
||||
|
||||
// Auxiliar matrix math functions
|
||||
static Matrix rlMatrixIdentity(void); // Get identity matrix
|
||||
static Matrix rlMatrixMultiply(Matrix left, Matrix right); // Multiply two matrices
|
||||
static Matrix rlMatrixIdentity(void); // Get identity matrix
|
||||
static Matrix rlMatrixMultiply(Matrix left, Matrix right); // Multiply two matrices
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Matrix operations
|
||||
|
|
@ -2001,10 +1994,8 @@ void rlLoadExtensions(void *loader)
|
|||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_33) // Also defined for GRAPHICS_API_OPENGL_21
|
||||
// NOTE: glad is generated and contains only required OpenGL 3.3 Core extensions (and lower versions)
|
||||
#if !defined(__APPLE__)
|
||||
if (gladLoadGL((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
|
||||
else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
|
||||
#endif
|
||||
if (gladLoadGL((GLADloadfunc)loader) == 0) TRACELOG(RL_LOG_WARNING, "GLAD: Cannot load OpenGL extensions");
|
||||
else TRACELOG(RL_LOG_INFO, "GLAD: OpenGL extensions loaded successfully");
|
||||
|
||||
// Get number of supported extensions
|
||||
GLint numExt = 0;
|
||||
|
|
@ -2018,6 +2009,18 @@ void rlLoadExtensions(void *loader)
|
|||
for (int i = 0; i < numExt; i++) TRACELOG(RL_LOG_INFO, " %s", glGetStringi(GL_EXTENSIONS, i));
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_21)
|
||||
// Register supported extensions flags
|
||||
// Optional OpenGL 2.1 extensions
|
||||
RLGL.ExtSupported.vao = GLAD_GL_ARB_vertex_array_object;
|
||||
RLGL.ExtSupported.instancing = (GLAD_GL_EXT_draw_instanced && GLAD_GL_ARB_instanced_arrays);
|
||||
RLGL.ExtSupported.texNPOT = GLAD_GL_ARB_texture_non_power_of_two;
|
||||
RLGL.ExtSupported.texFloat32 = GLAD_GL_ARB_texture_float;
|
||||
RLGL.ExtSupported.texDepth = GLAD_GL_ARB_depth_texture;
|
||||
RLGL.ExtSupported.maxDepthBits = 32;
|
||||
RLGL.ExtSupported.texAnisoFilter = GLAD_GL_EXT_texture_filter_anisotropic;
|
||||
RLGL.ExtSupported.texMirrorClamp = GLAD_GL_EXT_texture_mirror_clamp;
|
||||
#else
|
||||
// Register supported extensions flags
|
||||
// OpenGL 3.3 extensions supported by default (core)
|
||||
RLGL.ExtSupported.vao = true;
|
||||
|
|
@ -2028,18 +2031,17 @@ void rlLoadExtensions(void *loader)
|
|||
RLGL.ExtSupported.maxDepthBits = 32;
|
||||
RLGL.ExtSupported.texAnisoFilter = true;
|
||||
RLGL.ExtSupported.texMirrorClamp = true;
|
||||
#endif
|
||||
|
||||
// Optional OpenGL 3.3 extensions
|
||||
RLGL.ExtSupported.texCompASTC = GLAD_GL_KHR_texture_compression_astc_hdr && GLAD_GL_KHR_texture_compression_astc_ldr;
|
||||
RLGL.ExtSupported.texCompDXT = GLAD_GL_EXT_texture_compression_s3tc; // Texture compression: DXT
|
||||
RLGL.ExtSupported.texCompETC2 = GLAD_GL_ARB_ES3_compatibility; // Texture compression: ETC2/EAC
|
||||
#if defined(GRAPHICS_API_OPENGL_43)
|
||||
RLGL.ExtSupported.computeShader = GLAD_GL_ARB_compute_shader;
|
||||
RLGL.ExtSupported.ssbo = GLAD_GL_ARB_shader_storage_buffer_object;
|
||||
#endif
|
||||
#if defined(__APPLE__)
|
||||
// Apple provides its own extension macros
|
||||
RLGL.ExtSupported.texCompDXT = GL_EXT_texture_compression_s3tc;
|
||||
#else
|
||||
// NOTE: With GLAD, we can check if an extension is supported using the GLAD_GL_xxx booleans
|
||||
RLGL.ExtSupported.texCompDXT = GLAD_GL_EXT_texture_compression_s3tc; // Texture compression: DXT
|
||||
RLGL.ExtSupported.texCompETC2 = GLAD_GL_ARB_ES3_compatibility; // Texture compression: ETC2/EAC
|
||||
#endif
|
||||
|
||||
#endif // GRAPHICS_API_OPENGL_33
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
|
|
@ -2205,12 +2207,10 @@ void rlLoadExtensions(void *loader)
|
|||
#else // RLGL_SHOW_GL_DETAILS_INFO
|
||||
|
||||
// Show some basic info about GL supported features
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
if (RLGL.ExtSupported.vao) TRACELOG(RL_LOG_INFO, "GL: VAO extension detected, VAO functions loaded successfully");
|
||||
else TRACELOG(RL_LOG_WARNING, "GL: VAO extension not found, VAO not supported");
|
||||
if (RLGL.ExtSupported.texNPOT) TRACELOG(RL_LOG_INFO, "GL: NPOT textures extension detected, full NPOT textures supported");
|
||||
else TRACELOG(RL_LOG_WARNING, "GL: NPOT textures extension not found, limited NPOT support (no-mipmaps, no-repeat)");
|
||||
#endif
|
||||
if (RLGL.ExtSupported.texCompDXT) TRACELOG(RL_LOG_INFO, "GL: DXT compressed textures supported");
|
||||
if (RLGL.ExtSupported.texCompETC1) TRACELOG(RL_LOG_INFO, "GL: ETC1 compressed textures supported");
|
||||
if (RLGL.ExtSupported.texCompETC2) TRACELOG(RL_LOG_INFO, "GL: ETC2/EAC compressed textures supported");
|
||||
|
|
@ -2231,11 +2231,7 @@ int rlGetVersion(void)
|
|||
glVersion = RL_OPENGL_11;
|
||||
#endif
|
||||
#if defined(GRAPHICS_API_OPENGL_21)
|
||||
#if defined(__APPLE__)
|
||||
glVersion = RL_OPENGL_33; // NOTE: Force OpenGL 3.3 on OSX
|
||||
#else
|
||||
glVersion = RL_OPENGL_21;
|
||||
#endif
|
||||
glVersion = RL_OPENGL_21;
|
||||
#elif defined(GRAPHICS_API_OPENGL_33)
|
||||
glVersion = RL_OPENGL_33;
|
||||
#endif
|
||||
|
|
@ -3086,6 +3082,7 @@ void rlUnloadTexture(unsigned int id)
|
|||
}
|
||||
|
||||
// Generate mipmap data for selected texture
|
||||
// NOTE: Only supports GPU mipmap generation
|
||||
void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int *mipmaps)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, id);
|
||||
|
|
@ -3096,45 +3093,6 @@ void rlGenTextureMipmaps(unsigned int id, int width, int height, int format, int
|
|||
if (((width > 0) && ((width & (width - 1)) == 0)) &&
|
||||
((height > 0) && ((height & (height - 1)) == 0))) texIsPOT = true;
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
if (texIsPOT)
|
||||
{
|
||||
// WARNING: Manual mipmap generation only works for RGBA 32bit textures!
|
||||
if (format == RL_PIXELFORMAT_UNCOMPRESSED_R8G8B8A8)
|
||||
{
|
||||
// Retrieve texture data from VRAM
|
||||
void *texData = rlReadTexturePixels(id, width, height, format);
|
||||
|
||||
// NOTE: Texture data size is reallocated to fit mipmaps data
|
||||
// NOTE: CPU mipmap generation only supports RGBA 32bit data
|
||||
int mipmapCount = rlGenTextureMipmapsData(texData, width, height);
|
||||
|
||||
int size = width*height*4;
|
||||
int offset = size;
|
||||
|
||||
int mipWidth = width/2;
|
||||
int mipHeight = height/2;
|
||||
|
||||
// Load the mipmaps
|
||||
for (int level = 1; level < mipmapCount; level++)
|
||||
{
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA8, mipWidth, mipHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char *)texData + offset);
|
||||
|
||||
size = mipWidth*mipHeight*4;
|
||||
offset += size;
|
||||
|
||||
mipWidth /= 2;
|
||||
mipHeight /= 2;
|
||||
}
|
||||
|
||||
*mipmaps = mipmapCount + 1;
|
||||
RL_FREE(texData); // Once mipmaps have been generated and data has been uploaded to GPU VRAM, we can discard RAM data
|
||||
|
||||
TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Mipmaps generated manually on CPU side, total: %i", id, *mipmaps);
|
||||
}
|
||||
else TRACELOG(RL_LOG_WARNING, "TEXTURE: [ID %i] Failed to generate mipmaps for provided texture format", id);
|
||||
}
|
||||
#endif
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
if ((texIsPOT) || (RLGL.ExtSupported.texNPOT))
|
||||
{
|
||||
|
|
@ -4524,132 +4482,6 @@ static char *rlGetCompressedFormatName(int format)
|
|||
|
||||
#endif // GRAPHICS_API_OPENGL_33 || GRAPHICS_API_OPENGL_ES2
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
// Mipmaps data is generated after image data
|
||||
// NOTE: Only works with RGBA (4 bytes) data!
|
||||
static int rlGenTextureMipmapsData(unsigned char *data, int baseWidth, int baseHeight)
|
||||
{
|
||||
int mipmapCount = 1; // Required mipmap levels count (including base level)
|
||||
int width = baseWidth;
|
||||
int height = baseHeight;
|
||||
int size = baseWidth*baseHeight*4; // Size in bytes (will include mipmaps...), RGBA only
|
||||
|
||||
// Count mipmap levels required
|
||||
while ((width != 1) && (height != 1))
|
||||
{
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
|
||||
TRACELOGD("TEXTURE: Next mipmap size: %i x %i", width, height);
|
||||
|
||||
mipmapCount++;
|
||||
|
||||
size += (width*height*4); // Add mipmap size (in bytes)
|
||||
}
|
||||
|
||||
TRACELOGD("TEXTURE: Total mipmaps required: %i", mipmapCount);
|
||||
TRACELOGD("TEXTURE: Total size of data required: %i", size);
|
||||
|
||||
unsigned char *temp = RL_REALLOC(data, size);
|
||||
|
||||
if (temp != NULL) data = temp;
|
||||
else TRACELOG(RL_LOG_WARNING, "TEXTURE: Failed to re-allocate required mipmaps memory");
|
||||
|
||||
width = baseWidth;
|
||||
height = baseHeight;
|
||||
size = (width*height*4); // RGBA: 4 bytes
|
||||
|
||||
// Generate mipmaps
|
||||
// NOTE: Every mipmap data is stored after data (RGBA - 4 bytes)
|
||||
unsigned char *image = (unsigned char *)RL_MALLOC(width*height*4);
|
||||
unsigned char *mipmap = NULL;
|
||||
int offset = 0;
|
||||
|
||||
for (int i = 0; i < size; i += 4)
|
||||
{
|
||||
image[i] = data[i];
|
||||
image[i + 1] = data[i + 1];
|
||||
image[i + 2] = data[i + 2];
|
||||
image[i + 3] = data[i + 3];
|
||||
}
|
||||
|
||||
TRACELOGD("TEXTURE: Mipmap base size (%ix%i)", width, height);
|
||||
|
||||
for (int mip = 1; mip < mipmapCount; mip++)
|
||||
{
|
||||
mipmap = rlGenNextMipmapData(image, width, height);
|
||||
|
||||
offset += (width*height*4); // Size of last mipmap
|
||||
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
size = (width*height*4); // Mipmap size to store after offset
|
||||
|
||||
// Add mipmap to data
|
||||
for (int i = 0; i < size; i += 4)
|
||||
{
|
||||
data[offset + i] = mipmap[i];
|
||||
data[offset + i + 1] = mipmap[i + 1];
|
||||
data[offset + i + 2] = mipmap[i + 2];
|
||||
data[offset + i + 3] = mipmap[i + 3];
|
||||
}
|
||||
|
||||
RL_FREE(image);
|
||||
|
||||
image = mipmap;
|
||||
mipmap = NULL;
|
||||
}
|
||||
|
||||
RL_FREE(mipmap); // free mipmap data
|
||||
|
||||
return mipmapCount;
|
||||
}
|
||||
|
||||
// Manual mipmap generation (basic scaling algorithm)
|
||||
static unsigned char *rlGenNextMipmapData(unsigned char *srcData, int srcWidth, int srcHeight)
|
||||
{
|
||||
int x2 = 0;
|
||||
int y2 = 0;
|
||||
unsigned char prow[4] = { 0 };
|
||||
unsigned char pcol[4] = { 0 };
|
||||
|
||||
int width = srcWidth/2;
|
||||
int height = srcHeight/2;
|
||||
|
||||
unsigned char *mipmap = (unsigned char *)RL_MALLOC(width*height*4);
|
||||
|
||||
// Scaling algorithm works perfectly (box-filter)
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
y2 = 2*y;
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
x2 = 2*x;
|
||||
|
||||
prow[0] = (srcData[(y2*srcWidth + x2)*4 + 0] + srcData[(y2*srcWidth + x2 + 1)*4 + 0])/2;
|
||||
prow[1] = (srcData[(y2*srcWidth + x2)*4 + 1] + srcData[(y2*srcWidth + x2 + 1)*4 + 1])/2;
|
||||
prow[2] = (srcData[(y2*srcWidth + x2)*4 + 2] + srcData[(y2*srcWidth + x2 + 1)*4 + 2])/2;
|
||||
prow[3] = (srcData[(y2*srcWidth + x2)*4 + 3] + srcData[(y2*srcWidth + x2 + 1)*4 + 3])/2;
|
||||
|
||||
pcol[0] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 0] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 0])/2;
|
||||
pcol[1] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 1] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 1])/2;
|
||||
pcol[2] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 2] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 2])/2;
|
||||
pcol[3] = (srcData[((y2 + 1)*srcWidth + x2)*4 + 3] + srcData[((y2 + 1)*srcWidth + x2 + 1)*4 + 3])/2;
|
||||
|
||||
mipmap[(y*width + x)*4 + 0] = (prow[0] + pcol[0])/2;
|
||||
mipmap[(y*width + x)*4 + 1] = (prow[1] + pcol[1])/2;
|
||||
mipmap[(y*width + x)*4 + 2] = (prow[2] + pcol[2])/2;
|
||||
mipmap[(y*width + x)*4 + 3] = (prow[3] + pcol[3])/2;
|
||||
}
|
||||
}
|
||||
|
||||
TRACELOGD("TEXTURE: Mipmap generated successfully (%ix%i)", width, height);
|
||||
|
||||
return mipmap;
|
||||
}
|
||||
#endif // GRAPHICS_API_OPENGL_11
|
||||
|
||||
// Get pixel data size in bytes (image or texture)
|
||||
// NOTE: Size depends on pixel format
|
||||
static int rlGetPixelDataSize(int width, int height, int format)
|
||||
|
|
|
|||
219
src/rtext.c
219
src/rtext.c
|
|
@ -1043,7 +1043,7 @@ void DrawTextEx(Font font, const char *text, Vector2 position, float fontSize, f
|
|||
{
|
||||
// Get next codepoint from byte string and glyph index in font
|
||||
int codepointByteCount = 0;
|
||||
int codepoint = GetCodepoint(&text[i], &codepointByteCount);
|
||||
int codepoint = GetCodepointNext(&text[i], &codepointByteCount);
|
||||
int index = GetGlyphIndex(font, codepoint);
|
||||
|
||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
|
|
@ -1185,7 +1185,7 @@ Vector2 MeasureTextEx(Font font, const char *text, float fontSize, float spacing
|
|||
byteCounter++;
|
||||
|
||||
int next = 0;
|
||||
letter = GetCodepoint(&text[i], &next);
|
||||
letter = GetCodepointNext(&text[i], &next);
|
||||
index = GetGlyphIndex(font, letter);
|
||||
|
||||
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
|
|
@ -1627,7 +1627,7 @@ const char *TextToPascal(const char *text)
|
|||
// Encode text codepoint into UTF-8 text
|
||||
// REQUIRES: memcpy()
|
||||
// WARNING: Allocated memory must be manually freed
|
||||
char *TextCodepointsToUTF8(const int *codepoints, int length)
|
||||
char *LoadUTF8(const int *codepoints, int length)
|
||||
{
|
||||
// We allocate enough memory fo fit all possible codepoints
|
||||
// NOTE: 5 bytes for every codepoint should be enough
|
||||
|
|
@ -1650,9 +1650,68 @@ char *TextCodepointsToUTF8(const int *codepoints, int length)
|
|||
return text;
|
||||
}
|
||||
|
||||
// Unload UTF-8 text encoded from codepoints array
|
||||
void UnloadUTF8(char *text)
|
||||
{
|
||||
RL_FREE(text);
|
||||
}
|
||||
|
||||
// Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
|
||||
int *LoadCodepoints(const char *text, int *count)
|
||||
{
|
||||
int textLength = TextLength(text);
|
||||
|
||||
int codepointSize = 0;
|
||||
int codepointCount = 0;
|
||||
|
||||
// Allocate a big enough buffer to store as many codepoints as text bytes
|
||||
int *codepoints = RL_CALLOC(textLength, sizeof(int));
|
||||
|
||||
for (int i = 0; i < textLength; codepointCount++)
|
||||
{
|
||||
codepoints[codepointCount] = GetCodepointNext(text + i, &codepointSize);
|
||||
i += codepointSize;
|
||||
}
|
||||
|
||||
// Re-allocate buffer to the actual number of codepoints loaded
|
||||
void *temp = RL_REALLOC(codepoints, codepointCount*sizeof(int));
|
||||
if (temp != NULL) codepoints = temp;
|
||||
|
||||
*count = codepointCount;
|
||||
|
||||
return codepoints;
|
||||
}
|
||||
|
||||
// Unload codepoints data from memory
|
||||
void UnloadCodepoints(int *codepoints)
|
||||
{
|
||||
RL_FREE(codepoints);
|
||||
}
|
||||
|
||||
// Get total number of characters(codepoints) in a UTF-8 encoded text, until '\0' is found
|
||||
// NOTE: If an invalid UTF-8 sequence is encountered a '?'(0x3f) codepoint is counted instead
|
||||
int GetCodepointCount(const char *text)
|
||||
{
|
||||
unsigned int length = 0;
|
||||
char *ptr = (char *)&text[0];
|
||||
|
||||
while (*ptr != '\0')
|
||||
{
|
||||
int next = 0;
|
||||
int letter = GetCodepointNext(ptr, &next);
|
||||
|
||||
if (letter == 0x3f) ptr += 1;
|
||||
else ptr += next;
|
||||
|
||||
length++;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
// Encode codepoint into utf8 text (char array length returned as parameter)
|
||||
// NOTE: It uses a static array to store UTF-8 bytes
|
||||
RLAPI const char *CodepointToUTF8(int codepoint, int *byteSize)
|
||||
const char *CodepointToUTF8(int codepoint, int *utf8Size)
|
||||
{
|
||||
static char utf8[6] = { 0 };
|
||||
int size = 0; // Byte size of codepoint
|
||||
|
|
@ -1684,63 +1743,10 @@ RLAPI const char *CodepointToUTF8(int codepoint, int *byteSize)
|
|||
size = 4;
|
||||
}
|
||||
|
||||
*byteSize = size;
|
||||
*utf8Size = size;
|
||||
|
||||
return utf8;
|
||||
}
|
||||
|
||||
// Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
|
||||
int *LoadCodepoints(const char *text, int *count)
|
||||
{
|
||||
int textLength = TextLength(text);
|
||||
|
||||
int bytesProcessed = 0;
|
||||
int codepointCount = 0;
|
||||
|
||||
// Allocate a big enough buffer to store as many codepoints as text bytes
|
||||
int *codepoints = RL_CALLOC(textLength, sizeof(int));
|
||||
|
||||
for (int i = 0; i < textLength; codepointCount++)
|
||||
{
|
||||
codepoints[codepointCount] = GetCodepoint(text + i, &bytesProcessed);
|
||||
i += bytesProcessed;
|
||||
}
|
||||
|
||||
// Re-allocate buffer to the actual number of codepoints loaded
|
||||
void *temp = RL_REALLOC(codepoints, codepointCount*sizeof(int));
|
||||
if (temp != NULL) codepoints = temp;
|
||||
|
||||
*count = codepointCount;
|
||||
|
||||
return codepoints;
|
||||
}
|
||||
|
||||
// Unload codepoints data from memory
|
||||
void UnloadCodepoints(int *codepoints)
|
||||
{
|
||||
RL_FREE(codepoints);
|
||||
}
|
||||
|
||||
// Get total number of characters(codepoints) in a UTF-8 encoded text, until '\0' is found
|
||||
// NOTE: If an invalid UTF-8 sequence is encountered a '?'(0x3f) codepoint is counted instead
|
||||
int GetCodepointCount(const char *text)
|
||||
{
|
||||
unsigned int length = 0;
|
||||
char *ptr = (char *)&text[0];
|
||||
|
||||
while (*ptr != '\0')
|
||||
{
|
||||
int next = 0;
|
||||
int letter = GetCodepoint(ptr, &next);
|
||||
|
||||
if (letter == 0x3f) ptr += 1;
|
||||
else ptr += next;
|
||||
|
||||
length++;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
#endif // SUPPORT_TEXT_MANIPULATION
|
||||
|
||||
// Get next codepoint in a UTF-8 encoded text, scanning until '\0' is found
|
||||
|
|
@ -1748,7 +1754,7 @@ int GetCodepointCount(const char *text)
|
|||
// Total number of bytes processed are returned as a parameter
|
||||
// NOTE: The standard says U+FFFD should be returned in case of errors
|
||||
// but that character is not supported by the default font in raylib
|
||||
int GetCodepoint(const char *text, int *bytesProcessed)
|
||||
int GetCodepoint(const char *text, int *codepointSize)
|
||||
{
|
||||
/*
|
||||
UTF-8 specs from https://www.ietf.org/rfc/rfc3629.txt
|
||||
|
|
@ -1763,14 +1769,14 @@ int GetCodepoint(const char *text, int *bytesProcessed)
|
|||
*/
|
||||
// NOTE: on decode errors we return as soon as possible
|
||||
|
||||
int code = 0x3f; // Codepoint (defaults to '?')
|
||||
int codepoint = 0x3f; // Codepoint (defaults to '?')
|
||||
int octet = (unsigned char)(text[0]); // The first UTF8 octet
|
||||
*bytesProcessed = 1;
|
||||
*codepointSize = 1;
|
||||
|
||||
if (octet <= 0x7f)
|
||||
{
|
||||
// Only one octet (ASCII range x00-7F)
|
||||
code = text[0];
|
||||
codepoint = text[0];
|
||||
}
|
||||
else if ((octet & 0xe0) == 0xc0)
|
||||
{
|
||||
|
|
@ -1779,12 +1785,12 @@ int GetCodepoint(const char *text, int *bytesProcessed)
|
|||
// [0]xC2-DF [1]UTF8-tail(x80-BF)
|
||||
unsigned char octet1 = text[1];
|
||||
|
||||
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
|
||||
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *codepointSize = 2; return codepoint; } // Unexpected sequence
|
||||
|
||||
if ((octet >= 0xc2) && (octet <= 0xdf))
|
||||
{
|
||||
code = ((octet & 0x1f) << 6) | (octet1 & 0x3f);
|
||||
*bytesProcessed = 2;
|
||||
codepoint = ((octet & 0x1f) << 6) | (octet1 & 0x3f);
|
||||
*codepointSize = 2;
|
||||
}
|
||||
}
|
||||
else if ((octet & 0xf0) == 0xe0)
|
||||
|
|
@ -1793,11 +1799,11 @@ int GetCodepoint(const char *text, int *bytesProcessed)
|
|||
unsigned char octet1 = text[1];
|
||||
unsigned char octet2 = '\0';
|
||||
|
||||
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
|
||||
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *codepointSize = 2; return codepoint; } // Unexpected sequence
|
||||
|
||||
octet2 = text[2];
|
||||
|
||||
if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence
|
||||
if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *codepointSize = 3; return codepoint; } // Unexpected sequence
|
||||
|
||||
// [0]xE0 [1]xA0-BF [2]UTF8-tail(x80-BF)
|
||||
// [0]xE1-EC [1]UTF8-tail [2]UTF8-tail(x80-BF)
|
||||
|
|
@ -1805,50 +1811,105 @@ int GetCodepoint(const char *text, int *bytesProcessed)
|
|||
// [0]xEE-EF [1]UTF8-tail [2]UTF8-tail(x80-BF)
|
||||
|
||||
if (((octet == 0xe0) && !((octet1 >= 0xa0) && (octet1 <= 0xbf))) ||
|
||||
((octet == 0xed) && !((octet1 >= 0x80) && (octet1 <= 0x9f)))) { *bytesProcessed = 2; return code; }
|
||||
((octet == 0xed) && !((octet1 >= 0x80) && (octet1 <= 0x9f)))) { *codepointSize = 2; return codepoint; }
|
||||
|
||||
if ((octet >= 0xe0) && (octet <= 0xef))
|
||||
{
|
||||
code = ((octet & 0xf) << 12) | ((octet1 & 0x3f) << 6) | (octet2 & 0x3f);
|
||||
*bytesProcessed = 3;
|
||||
codepoint = ((octet & 0xf) << 12) | ((octet1 & 0x3f) << 6) | (octet2 & 0x3f);
|
||||
*codepointSize = 3;
|
||||
}
|
||||
}
|
||||
else if ((octet & 0xf8) == 0xf0)
|
||||
{
|
||||
// Four octets
|
||||
if (octet > 0xf4) return code;
|
||||
if (octet > 0xf4) return codepoint;
|
||||
|
||||
unsigned char octet1 = text[1];
|
||||
unsigned char octet2 = '\0';
|
||||
unsigned char octet3 = '\0';
|
||||
|
||||
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *bytesProcessed = 2; return code; } // Unexpected sequence
|
||||
if ((octet1 == '\0') || ((octet1 >> 6) != 2)) { *codepointSize = 2; return codepoint; } // Unexpected sequence
|
||||
|
||||
octet2 = text[2];
|
||||
|
||||
if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *bytesProcessed = 3; return code; } // Unexpected sequence
|
||||
if ((octet2 == '\0') || ((octet2 >> 6) != 2)) { *codepointSize = 3; return codepoint; } // Unexpected sequence
|
||||
|
||||
octet3 = text[3];
|
||||
|
||||
if ((octet3 == '\0') || ((octet3 >> 6) != 2)) { *bytesProcessed = 4; return code; } // Unexpected sequence
|
||||
if ((octet3 == '\0') || ((octet3 >> 6) != 2)) { *codepointSize = 4; return codepoint; } // Unexpected sequence
|
||||
|
||||
// [0]xF0 [1]x90-BF [2]UTF8-tail [3]UTF8-tail
|
||||
// [0]xF1-F3 [1]UTF8-tail [2]UTF8-tail [3]UTF8-tail
|
||||
// [0]xF4 [1]x80-8F [2]UTF8-tail [3]UTF8-tail
|
||||
|
||||
if (((octet == 0xf0) && !((octet1 >= 0x90) && (octet1 <= 0xbf))) ||
|
||||
((octet == 0xf4) && !((octet1 >= 0x80) && (octet1 <= 0x8f)))) { *bytesProcessed = 2; return code; } // Unexpected sequence
|
||||
((octet == 0xf4) && !((octet1 >= 0x80) && (octet1 <= 0x8f)))) { *codepointSize = 2; return codepoint; } // Unexpected sequence
|
||||
|
||||
if (octet >= 0xf0)
|
||||
{
|
||||
code = ((octet & 0x7) << 18) | ((octet1 & 0x3f) << 12) | ((octet2 & 0x3f) << 6) | (octet3 & 0x3f);
|
||||
*bytesProcessed = 4;
|
||||
codepoint = ((octet & 0x7) << 18) | ((octet1 & 0x3f) << 12) | ((octet2 & 0x3f) << 6) | (octet3 & 0x3f);
|
||||
*codepointSize = 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (code > 0x10ffff) code = 0x3f; // Codepoints after U+10ffff are invalid
|
||||
if (codepoint > 0x10ffff) codepoint = 0x3f; // Codepoints after U+10ffff are invalid
|
||||
|
||||
return code;
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
// Get next codepoint in a byte sequence and bytes processed
|
||||
int GetCodepointNext(const char *text, int *codepointSize)
|
||||
{
|
||||
const char *ptr = text;
|
||||
int codepoint = 0x3f; // Codepoint (defaults to '?')
|
||||
*codepointSize = 0;
|
||||
|
||||
// Get current codepoint and bytes processed
|
||||
if (0xf0 == (0xf8 & ptr[0]))
|
||||
{
|
||||
// 4 byte UTF-8 codepoint
|
||||
codepoint = ((0x07 & ptr[0]) << 18) | ((0x3f & ptr[1]) << 12) | ((0x3f & ptr[2]) << 6) | (0x3f & ptr[3]);
|
||||
*codepointSize = 4;
|
||||
}
|
||||
else if (0xe0 == (0xf0 & ptr[0]))
|
||||
{
|
||||
// 3 byte UTF-8 codepoint */
|
||||
codepoint = ((0x0f & ptr[0]) << 12) | ((0x3f & ptr[1]) << 6) | (0x3f & ptr[2]);
|
||||
*codepointSize = 3;
|
||||
}
|
||||
else if (0xc0 == (0xe0 & ptr[0]))
|
||||
{
|
||||
// 2 byte UTF-8 codepoint
|
||||
codepoint = ((0x1f & ptr[0]) << 6) | (0x3f & ptr[1]);
|
||||
*codepointSize = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 1 byte UTF-8 codepoint
|
||||
codepoint = ptr[0];
|
||||
*codepointSize = 1;
|
||||
}
|
||||
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
// Get previous codepoint in a byte sequence and bytes processed
|
||||
int GetCodepointPrevious(const char *text, int *codepointSize)
|
||||
{
|
||||
const char *ptr = text;
|
||||
int codepoint = 0x3f; // Codepoint (defaults to '?')
|
||||
int cpSize = 0;
|
||||
*codepointSize = 0;
|
||||
|
||||
// Move to previous codepoint
|
||||
do ptr--;
|
||||
while (((0x80 & ptr[0]) != 0) && ((0xc0 & ptr[0]) == 0x80));
|
||||
|
||||
codepoint = GetCodepointNext(ptr, &cpSize);
|
||||
|
||||
if (codepoint != 0) *codepointSize = cpSize;
|
||||
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
|||
1041
src/rtextures.c
1041
src/rtextures.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user