main
Dominik Madarász 2024-08-12 17:10:31 +02:00
parent 9d39fbe363
commit a37e7970c1
20 changed files with 161 additions and 636 deletions

View File

@ -111,7 +111,7 @@ void DrawModel(mesh_t *m) {
static mat44 VP; multiply44x2(VP, camera_get_active()->proj, camera_get_active()->view); static mat44 VP; multiply44x2(VP, camera_get_active()->proj, camera_get_active()->view);
static const char *vs = static const char *vs =
"#version 130\n" "//version 130\n"
"//" FILELINE "\n" "//" FILELINE "\n"
"uniform mat4 M,VP;\n" "uniform mat4 M,VP;\n"
"in vec3 att_position;\n" "in vec3 att_position;\n"
@ -122,7 +122,7 @@ void DrawModel(mesh_t *m) {
" gl_Position = M * VP * vec4( att_position, 1.0 );\n" " gl_Position = M * VP * vec4( att_position, 1.0 );\n"
"}\n"; "}\n";
static const char *fs = static const char *fs =
"#version 130\n" "//version 130\n"
"//" FILELINE "\n" "//" FILELINE "\n"
"in vec3 v_normal;\n" "in vec3 v_normal;\n"
"out vec4 fragcolor;\n" "out vec4 fragcolor;\n"

View File

@ -1,4 +1,4 @@
#version 330 core //version 330 core
struct Light struct Light
{ {

View File

@ -1,4 +1,4 @@
#version 330 core //version 330 core
layout(location = 0) in vec3 in_pos; layout(location = 0) in vec3 in_pos;
layout(location = 1) in vec2 in_texcoord; layout(location = 1) in vec2 in_texcoord;

View File

@ -1,4 +1,3 @@
#version 400
const float PI = 3.1415926536; const float PI = 3.1415926536;
in vec2 uv; in vec2 uv;

View File

@ -1,6 +1,6 @@
// uniform mat4 view = mat4(1.0); // uniform mat4 view = mat4(1.0);
uniform vec3 lightPos = vec3(1.0); uniform vec3 lightPos; /// set:1,1,1
uniform float doTexture = 1.; uniform float doTexture; /// set:1
#ifdef VSMCUBE #ifdef VSMCUBE
uniform samplerCube shadowMap; // VSMCUBE uniform samplerCube shadowMap; // VSMCUBE
#else #else
@ -16,7 +16,7 @@ struct light {
}; };
light light0 = light( light light0 = light(
lightPos, vec3(1,1,1), // lightPos
vec4(1,1,1,1), // diffuse vec4(1,1,1,1), // diffuse
vec4(1,1,1,1), // specular vec4(1,1,1,1), // specular
1.0, 0.0, 0.0 // attenuation (const, linear, quad) 1.0, 0.0, 0.0 // attenuation (const, linear, quad)

View File

@ -1,6 +1,6 @@
// uniform mat4 view = mat4(1.0); // uniform mat4 view = mat4(1.0);
uniform vec3 lightPos = vec3(1.0); uniform vec3 lightPos; /// set:1,1,1
uniform float doTexture = 0.; uniform float doTexture; /// set:0
uniform sampler2D shadowMap; uniform sampler2D shadowMap;

View File

@ -1,26 +1,27 @@
#version 400 //version 400
uniform mat4 model, view; uniform mat4 model, view;
uniform sampler2D u_texture2d; uniform sampler2D u_texture2d;
uniform vec3 u_coefficients_sh[9]; uniform vec3 u_coefficients_sh[9];
uniform bool u_textured = true; uniform bool u_textured; /// set:1
uniform bool u_lit = false; uniform bool u_lit; /// set:0
uniform bool u_matcaps = false; uniform bool u_matcaps; /// set:0
uniform vec4 u_diffuse = vec4(1.0,1.0,1.0,1.0); uniform vec4 u_diffuse; /// set:1,1,1,1
// lightmapping // lightmapping
uniform sampler2D u_lightmap; uniform sampler2D u_lightmap;
uniform bool u_texlit; uniform bool u_texlit;
uniform bool u_texmod = true; uniform bool u_texmod; /// set:1
uniform float u_litboost = 1.0; uniform float u_litboost; /// set:1
in vec3 v_position; in vec3 v_position;
in vec3 v_position_ws; in vec3 v_position_ws;
#ifdef RIM #ifdef RIM
uniform mat4 M; // RIM uniform mat4 M; // RIM
uniform vec3 u_rimcolor = vec3(0.05,0.05,0.05); uniform vec3 u_rimcolor; /// set:0.05,0.05,0.05
uniform vec3 u_rimrange = vec3(0.11,0.98,0.5); uniform vec3 u_rimrange; /// set:0.11,0.98,0.5
uniform vec3 u_rimpivot = vec3(0,0,0); uniform vec3 u_rimpivot; /// set:0,0,0
uniform bool u_rimambient = true; uniform bool u_rimambient; /// set:1
#endif #endif
in vec3 v_normal, v_normal_ws; in vec3 v_normal, v_normal_ws;
in vec2 v_texcoord, v_texcoord2; in vec2 v_texcoord, v_texcoord2;
@ -109,7 +110,7 @@ vec3 shading_phong(light_t l) {
#endif #endif
#ifdef SHADING_PBR #ifdef SHADING_PBR
uniform vec2 resolution = vec2(640.0,480.0); // debug options below use this (USE_MAP_DEBUGGING, USE_AMBIENT_DEBUGGING) uniform vec2 resolution; /// set:640,480 // debug options below use this (USE_MAP_DEBUGGING, USE_AMBIENT_DEBUGGING)
#define USE_BRUTEFORCE_IRRADIANCE false // Samples irradiance from tex_skysphere when enabled. #define USE_BRUTEFORCE_IRRADIANCE false // Samples irradiance from tex_skysphere when enabled.
#define USE_WRAPAROUND_SPECULAR true // Makes silhouettes more reflective to avoid black pixels. #define USE_WRAPAROUND_SPECULAR true // Makes silhouettes more reflective to avoid black pixels.
@ -117,8 +118,8 @@ uniform vec2 resolution = vec2(640.0,480.0); // debug options below use this
#define USE_NORMAL_VARIATION_TO_ROUGHNESS true // Increases roughness if normal map has variation and was minified. #define USE_NORMAL_VARIATION_TO_ROUGHNESS true // Increases roughness if normal map has variation and was minified.
#define USE_MAP_DEBUGGING false // Shows all ColorMaps as horizontal bars #define USE_MAP_DEBUGGING false // Shows all ColorMaps as horizontal bars
#define USE_AMBIENT_DEBUGGING false // Splits the screen in two and shows image-based specular (left), full shading (middle), diffuse shading (right). #define USE_AMBIENT_DEBUGGING false // Splits the screen in two and shows image-based specular (left), full shading (middle), diffuse shading (right).
#define BOOST_LIGHTING 1.00f // Multiplies analytic light's color with this constant because otherwise they look really pathetic. #define BOOST_LIGHTING 2.00f // Multiplies analytic light's color with this constant because otherwise they look really pathetic.
#define BOOST_SPECULAR 1.00f #define BOOST_SPECULAR 1.50f
#define BOOST_NOISE 2.50f #define BOOST_NOISE 2.50f
struct ColorMap struct ColorMap
@ -140,9 +141,9 @@ uniform ColorMap map_emissive; uniform sampler2D map_emissive_tex;
#define sample_colormap(ColorMap_, uv_) \ #define sample_colormap(ColorMap_, uv_) \
(ColorMap_.has_tex ? texture( ColorMap_##_tex, uv_ ) : ColorMap_.color) (ColorMap_.has_tex ? texture( ColorMap_##_tex, uv_ ) : ColorMap_.color)
uniform float skysphere_rotation=0; uniform float skysphere_rotation; /// set:0
uniform float skysphere_mip_count; uniform float skysphere_mip_count;
uniform float exposure=1; uniform float exposure; /// set:1
uniform uint frame_count; uniform uint frame_count;
uniform float specular_shininess; uniform float specular_shininess;
@ -282,15 +283,15 @@ vec3 sample_irradiance_slow( vec3 normal, vec3 vertex_tangent )
vec3 sample_irradiance_fast( vec3 normal, vec3 vertex_tangent ) vec3 sample_irradiance_fast( vec3 normal, vec3 vertex_tangent )
{ {
// Sample the irradiance map if it exists, otherwise fall back to blurred reflection map. // Sample the irradiance map if it exists, otherwise fall back to blurred reflection map.
if ( has_tex_skysphere ) if ( has_tex_skyenv )
{ {
vec2 polar = sphere_to_polar( normal ); vec2 polar = sphere_to_polar( normal );
return pow(textureLod( tex_skysphere, polar, 0.80 * skysphere_mip_count ), vec4(1.0/2.2)).rgb * exposure; return textureLod( tex_skyenv, polar, 0.0 ).rgb * exposure;
} }
else else
{ {
vec2 polar = sphere_to_polar( normal ); vec2 polar = sphere_to_polar( normal );
return pow(textureLod( tex_skyenv, polar, 0.0 ), vec4(1.0/2.2)).rgb * exposure; return textureLod( tex_skysphere, polar, 0.80 * skysphere_mip_count ).rgb * exposure;
} }
} }
@ -319,7 +320,7 @@ vec3 specular_ibl( vec3 V, vec3 N, float roughness, vec3 fresnel )
float mip = 0.9 * skysphere_mip_count * pow(roughness, 0.25 * BOOST_SPECULAR); float mip = 0.9 * skysphere_mip_count * pow(roughness, 0.25 * BOOST_SPECULAR);
vec3 prefiltered = pow(textureLod( tex_skysphere, polar, mip ), vec4(1.0/2.2)).rgb * exposure; vec3 prefiltered = textureLod( tex_skysphere, polar, mip ).rgb * exposure;
float NdotV = dot( N, V ); float NdotV = dot( N, V );
@ -471,10 +472,9 @@ void main(void)
roughness = sample_colormap( map_roughness, v_texcoord ).x; roughness = sample_colormap( map_roughness, v_texcoord ).x;
} }
else if( map_roughness.has_tex ) { else if( map_roughness.has_tex ) {
if (!map_ao.has_tex) //< @r-lyeh, metalness B, roughness G, (@todo: self-shadowing occlusion R; for now, any of R/B are metallic)
ao = sample_colormap( map_roughness, v_texcoord ).r; metallic = sample_colormap( map_roughness, v_texcoord ).b;// + sample_colormap( map_roughness, v_texcoord ).r;
roughness = sample_colormap( map_roughness, v_texcoord ).g; roughness = sample_colormap( map_roughness, v_texcoord ).g;
metallic = sample_colormap( map_roughness, v_texcoord ).b;
} }
if ( map_ao.has_tex ) if ( map_ao.has_tex )
@ -506,13 +506,13 @@ void main(void)
vec3 c = vec3(1., 0., 0.); vec3 c = vec3(1., 0., 0.);
float x = gl_FragCoord.x / resolution.x; float x = gl_FragCoord.x / resolution.x;
float y = gl_FragCoord.y / resolution.y; float y = gl_FragCoord.y / resolution.y;
if ( x < (7.0/7.0) ) c = vec3(.5) + .5*v_normal_ws; if ( y < (7.0/7.0) ) c = vec3(.5) + .5*v_normal_ws;
if ( x < (6.0/7.0) ) c = vec3(.5) + .5*normalmap; if ( y < (6.0/7.0) ) c = vec3(.5) + .5*normalmap;
if ( x < (5.0/7.0) ) c = vec3(ao); if ( y < (5.0/7.0) ) c = vec3(ao);
if ( x < (4.0/7.0) ) c = vec3(emissive); if ( y < (4.0/7.0) ) c = vec3(emissive);
if ( x < (3.0/7.0) ) c = vec3(metallic); if ( y < (3.0/7.0) ) c = vec3(metallic);
if ( x < (2.0/7.0) ) c = vec3(roughness); if ( y < (2.0/7.0) ) c = vec3(roughness);
if ( x < (1.0/7.0) ) c = baseColor; if ( y < (1.0/7.0) ) c = baseColor;
fragcolor = vec4(c, 1.); fragcolor = vec4(c, 1.);
return; return;
} }

View File

@ -2,13 +2,13 @@ in vec2 uv;
in float color_index; in float color_index;
uniform sampler2D sampler_font; uniform sampler2D sampler_font;
uniform sampler1D sampler_colors; uniform sampler2D sampler_colors;
uniform float num_colors; uniform float num_colors;
out vec4 outColor; out vec4 outColor;
void main() { void main() {
vec4 col = texture(sampler_colors, (color_index+0.5)/num_colors); vec4 col = texture(sampler_colors, vec2((color_index+0.5)/num_colors, 0.));
float s = texture(sampler_font, uv).r; float s = texture(sampler_font, uv).r;
outColor = vec4(col.rgb, s*col.a); outColor = vec4(col.rgb, s*col.a);
} }

View File

@ -1,4 +1,4 @@
#version 130 //version 130
#define texture2D texture #define texture2D texture
uniform float iGlobalTime; // shader playback time (in seconds) uniform float iGlobalTime; // shader playback time (in seconds)
uniform float iGlobalDelta; // ?? uniform float iGlobalDelta; // ??

View File

@ -1,10 +1,10 @@
#version 400 //version 400
// original PBR shader by @seece (Public Domain). link: https://github.com/Gargaj/Foxotron/pull/12 // original PBR shader by @seece (Public Domain). link: https://github.com/Gargaj/Foxotron/pull/12
//#define textureQueryLod(t,c) vec2(0.0,0.0) // #version 400 required //#define textureQueryLod(t,c) vec2(0.0,0.0) // version 400 required
uniform vec2 resolution = vec2(640.0,480.0); // debug options below use this (USE_MAP_DEBUGGING, USE_AMBIENT_DEBUGGING) uniform vec2 resolution; /// set:640,480 // debug options below use this (USE_MAP_DEBUGGING, USE_AMBIENT_DEBUGGING)
#define USE_BRUTEFORCE_IRRADIANCE false // Samples irradiance from tex_skysphere when enabled. #define USE_BRUTEFORCE_IRRADIANCE false // Samples irradiance from tex_skysphere when enabled.
#define USE_WRAPAROUND_SPECULAR true // Makes silhouettes more reflective to avoid black pixels. #define USE_WRAPAROUND_SPECULAR true // Makes silhouettes more reflective to avoid black pixels.

View File

@ -1,4 +1,4 @@
#version 330 core //version 330 core
layout(location = 0) in vec3 in_pos; layout(location = 0) in vec3 in_pos;
layout(location = 1) in vec2 in_texcoord; layout(location = 1) in vec2 in_texcoord;

View File

@ -1 +1 @@
#version 150 //version 150

View File

@ -1,4 +1,4 @@
#version 330 core //version 330 core
layout (location = 0) in vec2 aPos; layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoord; layout (location = 1) in vec2 aTexCoord;

View File

@ -2,7 +2,7 @@
#define MAX_BONES 110 #define MAX_BONES 110
#endif #endif
uniform mat3x4 vsBoneMatrix[MAX_BONES]; uniform mat3x4 vsBoneMatrix[MAX_BONES];
uniform bool SKINNED = false; uniform bool SKINNED; /// set:0
uniform mat4 M; // RIM uniform mat4 M; // RIM
uniform mat4 VP; uniform mat4 VP;
uniform mat4 P; uniform mat4 P;
@ -44,7 +44,7 @@ sg_image blend_shapes = mesh->num_blend_shapes > 0 ? mesh->blend_shape_image : v
#endif #endif
uniform vec4 blend_weights[MAX_BLENDSHAPES]; // @todo: implement me uniform vec4 blend_weights[MAX_BLENDSHAPES]; // @todo: implement me
uniform float f_num_blend_shapes; // @todo: implement me uniform float f_num_blend_shapes; // @todo: implement me
uniform sampler2DArray blend_shapes; // @todo: implement me uniform MEDIUMP sampler2DArray blend_shapes; // @todo: implement me
in vec3 att_position; // @todo: reorder ass2iqe to emit p3 n3 u2 t3 b3 c4B i4 w4 instead in vec3 att_position; // @todo: reorder ass2iqe to emit p3 n3 u2 t3 b3 c4B i4 w4 instead

View File

@ -1,4 +1,4 @@
#version 130 //version 130
uniform vec2 iResolution; // viewport resolution (in pixels) uniform vec2 iResolution; // viewport resolution (in pixels)
out vec2 texCoord; out vec2 texCoord;

View File

@ -1,4 +1,4 @@
#version 130 //version 130
uniform vec2 iResolution; // viewport resolution (in pixels) uniform vec2 iResolution; // viewport resolution (in pixels)
out vec2 texCoord; out vec2 texCoord;

View File

@ -88,6 +88,10 @@
#ifndef V4K_H #ifndef V4K_H
#define V4K_H #define V4K_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -186,4 +190,10 @@ extern "C" {
#endif #endif
#endif #endif
#if defined __TINYC__ && defined __linux
#ifndef __builtin_alloca
#define __builtin_alloca alloca
#endif
#endif
#endif // V4K_H #endif // V4K_H

View File

@ -18,7 +18,6 @@
#define BASE64_C // base64.c #define BASE64_C // base64.c
#define COMPRESS_C // compress.c #define COMPRESS_C // compress.c
#define ENET_IMPLEMENTATION // enet #define ENET_IMPLEMENTATION // enet
#define GJK_C // gjk
#define _GLFW_IMPLEMENTATION // glfw337 #define _GLFW_IMPLEMENTATION // glfw337
#define GLFW_INCLUDE_NONE // glfw337 #define GLFW_INCLUDE_NONE // glfw337
#define HTTPS_IMPLEMENTATION // https #define HTTPS_IMPLEMENTATION // https
@ -127,8 +126,13 @@ errno_t fopen_s(
#undef cast #undef cast
#undef G #undef G
//--- //---
#if !is(ems)
#ifdef I
#undef I // complex.h
#endif
#define LUAFFI_C #define LUAFFI_C
{{FILE:3rd_luaffi.h}} {{FILE:3rd_luaffi.h}}
#endif
//--- //---
{{FILE:3rd_stb_image.h}} {{FILE:3rd_stb_image.h}}
{{FILE:3rd_stb_image_write.h}} {{FILE:3rd_stb_image_write.h}}
@ -151,7 +155,6 @@ static char *ui_filter = 0;
//#pragma comment(lib, "3rd/3rd_assimp/x64/assimp") //#pragma comment(lib, "3rd/3rd_assimp/x64/assimp")
#endif #endif
{{FILE:3rd_json5.h}} {{FILE:3rd_json5.h}}
{{FILE:3rd_gjk.h}}
{{FILE:3rd_compress.h}} {{FILE:3rd_compress.h}}
{{FILE:3rd_archive.h}} {{FILE:3rd_archive.h}}
#if is(win32) #if is(win32)
@ -161,7 +164,9 @@ static char *ui_filter = 0;
{{FILE:3rd_plmpeg.h}} {{FILE:3rd_plmpeg.h}}
{{FILE:3rd_jo_mpeg.h}} {{FILE:3rd_jo_mpeg.h}}
//#define _RTL_RUN_ONCE _RTL_RUN_ONCE2 // __MINGW64__ //#define _RTL_RUN_ONCE _RTL_RUN_ONCE2 // __MINGW64__
#undef I #ifdef I
#undef I // complex.h
#endif
{{FILE:3rd_https.h}} {{FILE:3rd_https.h}}
#undef F2 #undef F2
#undef F3 #undef F3

View File

@ -3402,7 +3402,7 @@ int ui_unsigned2(const char *label, unsigned *v) {
ui_label_(label, NK_TEXT_LEFT); ui_label_(label, NK_TEXT_LEFT);
char *buffer = ui_num_signs ? char *buffer = ui_num_signs ?
--ui_num_signs, va("%+2u %+2u", v[0], v[1]) : --ui_num_signs, va("+%2u +%2u", v[0], v[1]) :
va("%2u, %2u", v[0], v[1]); va("%2u, %2u", v[0], v[1]);
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) { if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
@ -3421,7 +3421,7 @@ int ui_unsigned3(const char *label, unsigned *v) {
ui_label_(label, NK_TEXT_LEFT); ui_label_(label, NK_TEXT_LEFT);
char *buffer = ui_num_signs ? char *buffer = ui_num_signs ?
--ui_num_signs, va("%+2u %+2u %+2u", v[0], v[1], v[2]) : --ui_num_signs, va("+%2u +%2u +%2u", v[0], v[1], v[2]) :
va("%2u, %2u, %2u", v[0], v[1], v[2]); va("%2u, %2u, %2u", v[0], v[1], v[2]);
if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) { if (nk_combo_begin_label(ui_ctx, buffer, nk_vec2(200,200))) {
@ -4716,56 +4716,11 @@ int ui_audio() {
#line 0 #line 0
#line 1 "v4k_collide.c" #line 1 "v4k_collide.c"
/* poly */
poly poly_alloc(int cnt) {
poly p = {0};
p.cnt = cnt;
p.verts = REALLOC(p.verts, sizeof(p.verts[0]) * cnt); // array_resize(p.verts, cnt);
return p;
}
void poly_free(poly *p) {
REALLOC(p->verts, 0); // array_free(p->verts);
poly z = {0};
*p = z;
}
/* plane */ /* plane */
vec4 plane4(vec3 p, vec3 n) { vec4 plane4(vec3 p, vec3 n) {
return vec34(n, -dot3(n,p)); return vec34(n, -dot3(n,p));
} }
/* pyramid */
poly pyramid(vec3 from, vec3 to, float size) {
/* calculate axis */
vec3 up, right, forward = norm3( sub3(to, from) );
ortho3(&right, &up, forward);
/* calculate extend */
vec3 xext = scale3(right, size);
vec3 yext = scale3(up, size);
vec3 nxext = scale3(right, -size);
vec3 nyext = scale3(up, -size);
/* calculate base vertices */
poly p = {0};
p.verts = REALLOC(p.verts, sizeof(p.verts[0]) * (5+1)); p.cnt = 5; /*+1 for diamond case*/ // array_resize(p.verts, 5+1); p.cnt = 5;
p.verts[0] = add3(add3(from, xext), yext); /*a*/
p.verts[1] = add3(add3(from, xext), nyext); /*b*/
p.verts[2] = add3(add3(from, nxext), nyext); /*c*/
p.verts[3] = add3(add3(from, nxext), yext); /*d*/
p.verts[4] = to; /*r*/
return p;
}
/* pyramid */
poly diamond(vec3 from, vec3 to, float size) {
vec3 mid = add3(from, scale3(sub3(to, from), 0.5f));
poly p = pyramid(mid, to, size);
p.verts[5] = from; p.cnt = 6;
return p;
}
// --- // ---
static void transform_(vec3 *r, vec3 v, const float *r33, vec3 t3) { static void transform_(vec3 *r, vec3 v, const float *r33, vec3 t3) {
@ -5076,9 +5031,6 @@ hit *sphere_hit_capsule(sphere s, capsule c) {
return h; return h;
#endif #endif
} }
int sphere_test_poly(sphere s, poly p) {
return poly_test_sphere(p, s);
}
void aabb_rebalance_transform(aabb *b, aabb a, mat33 m, vec3 t) { void aabb_rebalance_transform(aabb *b, aabb a, mat33 m, vec3 t) {
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
i[&b->min.x] = i[&b->max.x] = i[&t.x]; i[&b->min.x] = i[&b->max.x] = i[&t.x];
@ -5219,9 +5171,6 @@ hit *aabb_hit_capsule(aabb a, capsule c) {
m->contact_point = ap; m->contact_point = ap;
return m; return m;
} }
int aabb_test_poly(aabb a, poly p) {
return poly_test_aabb(p, a);
}
float capsule_distance2_point(capsule c, vec3 p) { float capsule_distance2_point(capsule c, vec3 p) {
float d2 = line_distance2_point(line(c.a,c.b), p); float d2 = line_distance2_point(line(c.a,c.b), p);
return d2 - (c.r*c.r); return d2 - (c.r*c.r);
@ -5320,229 +5269,6 @@ hit *capsule_hit_aabb(capsule c, aabb a) {
m->contact_point = cp; m->contact_point = cp;
return m; return m;
} }
int capsule_test_poly(capsule c, poly p) {
return poly_test_capsule(p, c);
}
int line_support(vec3 *support, vec3 d, vec3 a, vec3 b) {
int i = 0;
float adot = dot3(a, d);
float bdot = dot3(b, d);
if (adot < bdot) {
*support = b;
i = 1;
} else *support = a;
return i;
}
int poly_support(vec3 *support, vec3 d, poly p) {
int imax = 0;
float dmax = dot3(*p.verts, d);
for (int i = 1; i < p.cnt; ++i) {
/* find vertex with max dot product in direction d */
float dot = dot3(p.verts[i], d);
if (dot < dmax) continue;
imax = i, dmax = dot;
} *support = p.verts[imax];
return imax;
}
int poly_hit_sphere(struct gjk_result *res,
poly p,
sphere s) {
/* initial guess */
vec3 d = {0};
gjk_support gs = {0};
gs.a = *p.verts;
gs.b = s.c;
d = sub3(gs.b, gs.a);
/* run gjk algorithm */
gjk_simplex gsx = {0};
while (gjk(&gsx, &gs, &d)) {
vec3 n = scale3(d, -1);
gs.aid = poly_support(&gs.a, n, p);
d = sub3(gs.b, gs.a);
}
/* check distance between closest points */
*res = gjk_analyze(&gsx);
return res->distance_squared <= s.r*s.r;
}
int poly_hit_sphere_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, sphere s) {
/* initial guess */
vec3 d = {0};
gjk_support gs = {0};
gs.a = *p.verts;
gs.b = s.c;
transformS(&gs.a, rot33, pos3);
d = sub3(gs.b, gs.a);
/* run gjk algorithm */
gjk_simplex gsx = {0};
while (gjk(&gsx, &gs, &d)) {
vec3 n = scale3(d, -1);
vec3 da; transformT(&da, n, rot33, pos3);
gs.aid = poly_support(&gs.a, da, p);
transformS(&gs.a, rot33, pos3);
d = sub3(gs.b, gs.a);
}
/* check distance between closest points */
*res = gjk_analyze(&gsx);
return res->distance_squared <= s.r*s.r;
}
int poly_test_sphere(poly p, sphere s) {
struct gjk_result res;
return poly_hit_sphere(&res, p, s);
}
int poly_test_sphere_transform(poly p, vec3 pos3, mat33 rot33, sphere s) {
struct gjk_result res;
return poly_hit_sphere_transform(&res, p, pos3, rot33, s);
}
int poly_hit_capsule(struct gjk_result *res, poly p, capsule c) {
/* initial guess */
vec3 d = {0};
gjk_support s = {0};
s.a = *p.verts;
s.b = c.a;
d = sub3(s.b, s.a);
/* run gjk algorithm */
gjk_simplex gsx = {0};
while (gjk(&gsx, &s, &d)) {
vec3 n = scale3(d, -1);
s.aid = poly_support(&s.a, n, p);
s.bid = line_support(&s.b, d, c.a, c.b);
d = sub3(s.b, s.a);
}
/* check distance between closest points */
assert(gsx.iter < gsx.max_iter);
*res = gjk_analyze(&gsx);
return res->distance_squared <= c.r*c.r;
}
int poly_test_capsule(poly p, capsule c) {
struct gjk_result res;
return poly_hit_capsule(&res, p, c);
}
int poly_hit_capsule_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, capsule c) {
/* initial guess */
vec3 d = {0};
gjk_support gs = {0};
gs.a = *p.verts;
gs.b = c.a;
transformS(&gs.a, rot33, pos3);
d = sub3(gs.b, gs.a);
/* run gjk algorithm */
gjk_simplex gsx = {0};
while (gjk(&gsx, &gs, &d)) {
vec3 n = scale3(d, -1);
vec3 da; transformT(&da, n, rot33, pos3);
gs.aid = poly_support(&gs.a, da, p);
gs.bid = line_support(&gs.b, d, c.a, c.b);
transformS(&gs.a, rot33, pos3);
d = sub3(gs.b, gs.a);
}
/* check distance between closest points */
*res = gjk_analyze(&gsx);
return res->distance_squared <= c.r*c.r;
}
int poly_test_capsule_transform(poly p, vec3 pos3, mat33 rot33, capsule c) {
struct gjk_result res;
return poly_hit_capsule_transform(&res, p, pos3, rot33, c);
}
int poly_hit_poly_transform(struct gjk_result *res,
poly a, vec3 at3, mat33 ar33,
poly b, vec3 bt3, mat33 br33) {
/* initial guess */
vec3 d = {0};
gjk_support gs = {0};
gs.a = *a.verts;
gs.b = *b.verts;
transformS(&gs.a, ar33, at3);
transformS(&gs.b, br33, bt3);
d = sub3(gs.b, gs.a);
/* run gjk algorithm */
gjk_simplex gsx = {0};
while (gjk(&gsx, &gs, &d)) {
/* transform direction */
vec3 n = scale3(d, -1);
vec3 da; transformT(&da, n, ar33, at3);
vec3 db; transformT(&db, d, br33, bt3);
/* run support function on tranformed directions */
gs.aid = poly_support(&gs.a, da, a);
gs.bid = poly_support(&gs.b, db, b);
/* calculate distance vector on transformed points */
transformS(&gs.a, ar33, at3);
transformS(&gs.b, br33, bt3);
d = sub3(gs.b, gs.a);
}
*res = gjk_analyze(&gsx);
return gsx.hit;
}
int poly_hit_poly(struct gjk_result *res,
poly a,
poly b) {
/* initial guess */
vec3 d = {0};
gjk_support gs = {0};
gs.a = *a.verts;
gs.b = *b.verts;
d = sub3(gs.b, gs.a);
/* run gjk algorithm */
gjk_simplex gsx = {0};
while (gjk(&gsx, &gs, &d)) {
vec3 n = scale3(d, -1);
gs.aid = poly_support(&gs.a, n, a);
gs.bid = poly_support(&gs.b, d, b);
d = sub3(gs.b, gs.a);
}
*res = gjk_analyze(&gsx);
return gsx.hit;
}
int poly_test_poly(poly a, poly b) {
struct gjk_result res;
return poly_hit_poly(&res, a, b);
}
int poly_test_poly_transform(poly a, vec3 apos3, mat33 arot33,
poly b, vec3 bpos3, mat33 brot33) {
struct gjk_result res;
return poly_hit_poly_transform(&res, a, apos3, arot33, b, bpos3, brot33);
}
int poly_hit_aabb(struct gjk_result *res, poly p, aabb a) {
vec3 box[8];
box[0] = vec3(a.min.x, a.min.y, a.min.z),
box[1] = vec3(a.min.x, a.min.y, a.max.z);
box[2] = vec3(a.min.x, a.max.y, a.min.z);
box[3] = vec3(a.min.x, a.max.y, a.max.z);
box[4] = vec3(a.max.x, a.min.y, a.min.z);
box[5] = vec3(a.max.x, a.min.y, a.max.z);
box[6] = vec3(a.max.x, a.max.y, a.min.z);
box[7] = vec3(a.max.x, a.max.y, a.max.z);
return poly_hit_poly(res, p, poly(&box[0], 8));
}
int poly_hit_aabb_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, aabb a) {
vec3 zero = {0};
vec3 id[3] = {{1,0,0},{0,1,0},{0,0,1}};
vec3 box[8];
box[0] = vec3(a.min.x, a.min.y, a.min.z),
box[1] = vec3(a.min.x, a.min.y, a.max.z);
box[2] = vec3(a.min.x, a.max.y, a.min.z);
box[3] = vec3(a.min.x, a.max.y, a.max.z);
box[4] = vec3(a.max.x, a.min.y, a.min.z);
box[5] = vec3(a.max.x, a.min.y, a.max.z);
box[6] = vec3(a.max.x, a.max.y, a.min.z);
box[7] = vec3(a.max.x, a.max.y, a.max.z);
return poly_hit_poly_transform(res, p, pos3, rot33, poly(&box[0], 8), zero, id[0].v3);
}
int poly_test_aabb(poly p, aabb a) {
struct gjk_result res;
return poly_hit_aabb(&res, p, a);
}
int poly_test_aabb_transform(poly p, vec3 apos3, mat33 arot33, aabb a) {
struct gjk_result res;
return poly_hit_aabb_transform(&res, p, apos3, arot33, a);
}
/* ============================================================================ /* ============================================================================
* *
@ -5629,7 +5355,7 @@ int frustum_test_aabb(frustum f, aabb a) {
return 1; return 1;
} }
void collide_demo() { // debug draw collisions // @fixme: fix leaks: poly_free() void collide_demo() { // debug draw collisions
// animation // animation
static float dx = 0, dy = 0; static float dx = 0, dy = 0;
@ -5977,169 +5703,6 @@ void collide_demo() { // debug draw collisions // @fixme: fix leaks: poly_free()
ddraw_capsule(vec3(x,y-1.0f,z), vec3(x,y+1.0f,z-1.0f), 0.2f); ddraw_capsule(vec3(x,y-1.0f,z), vec3(x,y+1.0f,z-1.0f), 0.2f);
ddraw_box(vec3(0,0,-8.0f), vec3(1,1,1)); ddraw_box(vec3(0,0,-8.0f), vec3(1,1,1));
} }
{
// poly(Pyramid)-Sphere (GJK) intersection*/
sphere s = sphere(vec3(-10+0.6f*sin(dx), 3.0f*cos(dy),-8), 1);
poly pyr = pyramid(vec3(-10.5f,-0.5f,-7.5f), vec3(-10.5f,1.0f,-7.5f), 1.0f);
gjk_result gjk;
if (poly_hit_sphere(&gjk, pyr, s))
ddraw_color(RED);
else ddraw_color(WHITE);
ddraw_sphere(s.c, 1);
ddraw_pyramid(vec3(-10.5f,-0.5f,-7.5f), 0.5f/*vec3(-10.5f,1.0f,-7.5f)*/, 1.0f);
poly_free(&pyr);
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
ddraw_line(gjk.p0, gjk.p1);
}
{
// poly(Diamond)-Sphere (GJK) intersection*/
sphere s = sphere(vec3(-20+0.6f*sin(dx), 3.0f*cos(dy),-8), 1);
poly dmd = diamond(vec3(-20.5f,-0.5f,-7.5f), vec3(-20.5f,1.0f,-7.5f), 0.5f);
gjk_result gjk;
if (poly_hit_sphere(&gjk, dmd, s))
ddraw_color(RED);
else ddraw_color(WHITE);
ddraw_sphere(s.c, 1);
ddraw_diamond(vec3(-20.5f,-0.5f,-7.5f), vec3(-20.5f,1.0f,-7.5f), 0.5f);
poly_free(&dmd);
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
ddraw_line(gjk.p0, gjk.p1);
}
{
// poly(Pyramid)-Capsule (GJK) intersection*/
const float x = 0.4f*sin(dx);
const float y = 3.0f*cos(dy);
const float z = -15;
capsule c = capsule(vec3(x,y-1.0f,z), vec3(x,y+1.0f,z), 0.2f);
poly pyr = pyramid(vec3(-0.5f,-0.5f,-15.5f), vec3(-0.5f,1.0f,-15.5f), 1.0f);
gjk_result gjk;
if (poly_hit_capsule(&gjk, pyr, c))
ddraw_color(RED);
else ddraw_color(WHITE);
ddraw_capsule(c.a, c.b, c.r);
ddraw_pyramid(vec3(-0.5f,-0.5f,-15.5f), 0.5f/*vec3(-0.5f,1.0f,-15.5f)*/, 1.0f);
poly_free(&pyr);
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
ddraw_line(gjk.p0, gjk.p1);
}
{
// poly(Diamond)-Capsule (GJK) intersection*/
const float x = -10 + 0.4f*sin(dx);
const float y = 3.0f*cos(dy);
const float z = -15;
capsule c = capsule(vec3(x,y-1.0f,z), vec3(x,y+1.0f,z), 0.2f);
poly dmd = diamond(vec3(-10.5f,-0.5f,-15.5f), vec3(-10.5f,1.0f,-15.5f), 0.5f);
gjk_result gjk;
if (poly_hit_capsule(&gjk, dmd, c))
ddraw_color(RED);
else ddraw_color(WHITE);
ddraw_capsule(c.a, c.b, c.r);
ddraw_diamond(vec3(-10.5f,-0.5f,-15.5f), vec3(-10.5f,1.0f,-15.5f), 0.5f);
poly_free(&dmd);
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
ddraw_line(gjk.p0, gjk.p1);
}
{
// poly(Diamond)-poly(Pyramid) (GJK) intersection*/
const float x = -20 + 0.4f*sin(dx);
const float y = 3.0f*cos(dy);
const float z = -15;
poly pyr = pyramid(vec3(x,y-0.5f,z), vec3(x,y+1,z), 0.8f);
poly dmd = diamond(vec3(-20.5f,-0.5f,-15.5f), vec3(-20.5f,1.0f,-15.5f), 0.5f);
gjk_result gjk;
if (poly_hit_poly(&gjk, dmd, pyr))
ddraw_color(RED);
else ddraw_color(WHITE);
ddraw_pyramid(vec3(x,y-0.5f,z), 1/*vec3(x,y+1,z)*/, 1/*0.8f*/);
ddraw_diamond(vec3(-20.5f,-0.5f,-15.5f), vec3(-20.5f,1.0f,-15.5f), 0.5f);
poly_free(&dmd);
poly_free(&pyr);
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
ddraw_line(gjk.p0, gjk.p1);
}
{
// poly(Pyramid)-poly(Diamond) (GJK) intersection*/
const float x = 10 + 0.4f*sin(dx);
const float y = 3.0f*cos(dy);
const float z = -15;
poly dmd = diamond(vec3(x,y-0.5f,z), vec3(x,y+1,z), 0.5f);
poly pyr = pyramid(vec3(10.5f,-0.5f,-15.5f), vec3(10.5f,1.0f,-15.5f), 1.0f);
gjk_result gjk;
if (poly_hit_poly(&gjk, dmd, pyr))
ddraw_color(RED);
else ddraw_color(WHITE);
ddraw_diamond(vec3(x,y-0.5f,z), vec3(x,y+1,z), 0.5f);
ddraw_pyramid(vec3(10.5f,-0.5f,-15.5f), 0.5f/*vec3(10.5f,1.0f,-15.5f)*/, 1.0f);
poly_free(&dmd);
poly_free(&pyr);
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
ddraw_line(gjk.p0, gjk.p1);
}
{
// poly(Diamond)-AABB (GJK) intersection*/
const float x = 20 + 0.4f*sin(dx);
const float y = 3.0f*cos(dy);
const float z = -15;
poly dmd = diamond(vec3(x,y-0.5f,z), vec3(x,y+1,z), 0.5f);
aabb a = aabb(vec3(19.5f,-0.5f,-14.5f), vec3(20.5f,0.5f,-15.5f));
gjk_result gjk;
if (poly_hit_aabb(&gjk, dmd, a))
ddraw_color(RED);
else ddraw_color(WHITE);
poly_free(&dmd);
ddraw_diamond(vec3(x,y-0.5f,z), vec3(x,y+1,z), 0.5f);
ddraw_box(vec3(20,0,-15), vec3(1,1,1));
ddraw_box(gjk.p0, vec3(0.05f, 0.05f, 0.05f));
ddraw_box(gjk.p1, vec3(0.05f, 0.05f, 0.05f));
ddraw_line(gjk.p0, gjk.p1);
}
} }
#line 0 #line 0
@ -7445,8 +7008,10 @@ void script_init() {
luaopen_string(L); luaopen_string(L);
luaopen_math(L); luaopen_math(L);
#if !is(ems)
// enable ffi (via luaffi) // enable ffi (via luaffi)
luaopen_ffi(L); luaopen_ffi(L);
#endif
// @fixme: workaround that prevents script binding on lua 5.4.3 on top of luajit 2.1.0-beta3 on linux. lua_setglobal() crashing when accessing null L->l_G // @fixme: workaround that prevents script binding on lua 5.4.3 on top of luajit 2.1.0-beta3 on linux. lua_setglobal() crashing when accessing null L->l_G
if(L->l_G) { if(L->l_G) {
@ -10295,8 +9860,8 @@ void font_color(const char *tag, uint32_t color) {
font_t *f = &fonts[i]; font_t *f = &fonts[i];
if( f->initialized ) { if( f->initialized ) {
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_1D, f->texture_colors); glBindTexture(GL_TEXTURE_2D, f->texture_colors);
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, FONT_MAX_COLORS, GL_RGBA, GL_UNSIGNED_BYTE, font_palette); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, FONT_MAX_COLORS, 1, GL_RGBA, GL_UNSIGNED_BYTE, font_palette);
} }
} }
} }
@ -10583,11 +10148,11 @@ void font_face_from_mem(const char *tag, const void *ttf_data, unsigned ttf_len,
// setup color texture // setup color texture
glGenTextures(1, &f->texture_colors); glGenTextures(1, &f->texture_colors);
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_1D, f->texture_colors); glBindTexture(GL_TEXTURE_2D, f->texture_colors);
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, FONT_MAX_COLORS, 0, GL_RGBA, GL_UNSIGNED_BYTE, font_palette); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, FONT_MAX_COLORS, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, font_palette);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
// upload constant uniforms // upload constant uniforms
glUseProgram(f->program); glUseProgram(f->program);
@ -10646,7 +10211,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, f->texture_offsets); glBindTexture(GL_TEXTURE_2D, f->texture_offsets);
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_1D, f->texture_colors); glBindTexture(GL_TEXTURE_2D, f->texture_colors);
// update bindings // update bindings
glBindVertexArray(f->vao); glBindVertexArray(f->vao);
@ -10679,7 +10244,7 @@ void font_draw_cmd(font_t *f, const float *glyph_data, int glyph_idx, float fact
glActiveTexture(GL_TEXTURE1); glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, last_texture1); glBindTexture(GL_TEXTURE_2D, last_texture1);
glActiveTexture(GL_TEXTURE2); glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_1D, last_texture2); glBindTexture(GL_TEXTURE_2D, last_texture2);
glBindVertexArray(last_vertex_array); glBindVertexArray(last_vertex_array);
} }
@ -13494,7 +13059,7 @@ int download_file( FILE *out, const char *url ) {
DWORD response_size = 0; DWORD response_size = 0;
if( out ) if( out )
for( HINTERNET session = InternetOpenA("v4k.download_file", PRE_CONFIG_INTERNET_ACCESS, NULL, INTERNET_INVALID_PORT_NUMBER, 0); session; InternetCloseHandle(session), session = 0 ) for( HINTERNET session = InternetOpenA("v4k.download_file", PRE_CONFIG_INTERNET_ACCESS, NULL, INTERNET_INVALID_PORT_NUMBER, 0); session; InternetCloseHandle(session), session = 0 ) // @fixme: download_file
for( HINTERNET request = InternetOpenUrlA(session, url, NULL, 0, INTERNET_FLAG_RELOAD, 0); request; InternetCloseHandle(request), request = 0 ) for( HINTERNET request = InternetOpenUrlA(session, url, NULL, 0, INTERNET_FLAG_RELOAD, 0); request; InternetCloseHandle(request), request = 0 )
for(; InternetReadFile(request, buffer, sizeof(buffer), &response_size) != FALSE && response_size > 0; ) { for(; InternetReadFile(request, buffer, sizeof(buffer), &response_size) != FALSE && response_size > 0; ) {
ok = (fwrite(buffer, response_size, 1, out) == 1); ok = (fwrite(buffer, response_size, 1, out) == 1);
@ -17379,6 +16944,7 @@ void renderstate_apply(const renderstate_t *state) {
glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_SMOOTH);
} }
#if !is(ems)
// Apply point size // Apply point size
if (state->point_size_enabled) { if (state->point_size_enabled) {
glEnable(GL_PROGRAM_POINT_SIZE); glEnable(GL_PROGRAM_POINT_SIZE);
@ -17389,6 +16955,7 @@ void renderstate_apply(const renderstate_t *state) {
// Apply polygon mode // Apply polygon mode
glPolygonMode(state->polygon_mode_face, state->polygon_mode_draw); glPolygonMode(state->polygon_mode_face, state->polygon_mode_draw);
#endif
// Apply scissor test // Apply scissor test
if (state->scissor_test_enabled) { if (state->scissor_test_enabled) {
@ -17445,13 +17012,22 @@ static inline
char *shader_preprocess(const char *src, const char *defines) { char *shader_preprocess(const char *src, const char *defines) {
if (!src) return NULL; if (!src) return NULL;
const char *glsl_version = va("#version %s", ifdef(ems, "300 es", "150")); const char *gles = "#version 300 es\n"
"#define textureQueryLod(t,uv) vec2(0.,0.)\n" // "#extension GL_EXT_texture_query_lod : enable\n"
"#define MEDIUMP mediump\n"
"precision MEDIUMP float;\n";
const char *desktop = strstr(src, "textureQueryLod") ? "#version 400\n#define MEDIUMP\n" : "#version 330\n#define MEDIUMP\n";
const char *glsl_version = ifdef(ems, gles, desktop);
// detect GLSL version if set // detect GLSL version if set
if (src[0] == '#' && src[1] == 'v') { if (src[0] == '#' && src[1] == 'v') {
#if 0
const char *end = strstri(src, "\n"); const char *end = strstri(src, "\n");
glsl_version = va("%.*s", (int)(end-src), src); glsl_version = va("%.*s", (int)(end-src), src);
src = end+1; src = end+1;
#else
PANIC("!ERROR: shader with #version specified on it. we do not support this anymore.");
#endif
} }
return va("%s\n%s\n%s", glsl_version, defines ? defines : "", src); return va("%s\n%s\n%s", glsl_version, defines ? defines : "", src);
@ -17472,16 +17048,6 @@ unsigned shader_geom(const char *gs, const char *vs, const char *fs, const char
vs = shader_preprocess(vs, glsl_defines); vs = shader_preprocess(vs, glsl_defines);
fs = shader_preprocess(fs, glsl_defines); fs = shader_preprocess(fs, glsl_defines);
#if is(ems)
{
char *vs_ = REALLOC( 0, strlen(vs) + 512 ); strcpy(vs_, vs);
char *fs_ = REALLOC( 0, strlen(fs) + 512 ); strcpy(fs_, fs);
char *gs_ = 0; if (gs) REALLOC( 0, strlen(gs) + 512 ); strcpy(gs_, gs);
strrepl(&fs_, "#version 300 es\n", "#version 300 es\nprecision mediump float;\n");
vs = vs_; fs = fs_; gs = gs_;
}
#endif
GLuint vert = shader_compile(GL_VERTEX_SHADER, vs); GLuint vert = shader_compile(GL_VERTEX_SHADER, vs);
GLuint frag = shader_compile(GL_FRAGMENT_SHADER, fs); GLuint frag = shader_compile(GL_FRAGMENT_SHADER, fs);
GLuint geom = 0; if (gs) geom = shader_compile(GL_GEOMETRY_SHADER, gs); GLuint geom = 0; if (gs) geom = shader_compile(GL_GEOMETRY_SHADER, gs);
@ -17892,7 +17458,6 @@ static inline void shader_cubemap_(int sampler, unsigned texture) {
static inline void shader_bool_(int uniform, bool x) { glUniform1i(uniform, x); } static inline void shader_bool_(int uniform, bool x) { glUniform1i(uniform, x); }
static inline void shader_uint_(int uniform, unsigned x ) { glUniform1ui(uniform, x); } static inline void shader_uint_(int uniform, unsigned x ) { glUniform1ui(uniform, x); }
static inline void shader_texture_unit_(int sampler, unsigned id, unsigned unit) { static inline void shader_texture_unit_(int sampler, unsigned id, unsigned unit) {
// @todo. if tex.h == 1 ? GL_TEXTURE_1D : GL_TEXTURE_2D
glUniform1i(sampler, unit); glUniform1i(sampler, unit);
glActiveTexture(GL_TEXTURE0 + unit); glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, id); glBindTexture(GL_TEXTURE_2D, id);
@ -17917,7 +17482,6 @@ void shader_bool(const char *uniform, bool x) { glUniform1i(shader_uniform(unifo
void shader_uint(const char *uniform, unsigned x ) { glUniform1ui(shader_uniform(uniform), x); } void shader_uint(const char *uniform, unsigned x ) { glUniform1ui(shader_uniform(uniform), x); }
void shader_texture(const char *sampler, texture_t t) { shader_texture_unit(sampler, t.id, texture_unit()); } void shader_texture(const char *sampler, texture_t t) { shader_texture_unit(sampler, t.id, texture_unit()); }
void shader_texture_unit(const char *sampler, unsigned id, unsigned unit) { void shader_texture_unit(const char *sampler, unsigned id, unsigned unit) {
// @todo. if tex.h == 1 ? GL_TEXTURE_1D : GL_TEXTURE_2D
glUniform1i(shader_uniform(sampler), unit); glUniform1i(shader_uniform(sampler), unit);
glActiveTexture(GL_TEXTURE0 + unit); glActiveTexture(GL_TEXTURE0 + unit);
glBindTexture(GL_TEXTURE_2D, id); glBindTexture(GL_TEXTURE_2D, id);
@ -19962,9 +19526,7 @@ void fx_enable(int pass, int enabled) {
postfx_enable(&fx, pass, enabled); postfx_enable(&fx, pass, enabled);
} }
void fx_enable_all(int enabled) { void fx_enable_all(int enabled) {
for( int i = 0; i < array_count(fx.pass); ++i ) { for( int i = 0; i < array_count(fx.pass); ++i ) fx_enable(i, enabled);
fx_enable(i, enabled);
}
} }
char *fx_name(int pass) { char *fx_name(int pass) {
return postfx_name(&fx, pass); return postfx_name(&fx, pass);
@ -22256,35 +21818,35 @@ void ddraw_cylinder(vec3 center, float height, int segments) {
ddraw_prism(center, 1, -height, vec3(0,1,0), segments); ddraw_prism(center, 1, -height, vec3(0,1,0), segments);
} }
void ddraw_diamond(vec3 from, vec3 to, float size) { void ddraw_diamond(vec3 from, vec3 to, float size) {
poly p = diamond(from, to, size); // poly p = diamond(from, to, size);
vec3 *dmd = p.verts; // vec3 *dmd = p.verts;
vec3 *a = dmd + 0; // vec3 *a = dmd + 0;
vec3 *b = dmd + 1; // vec3 *b = dmd + 1;
vec3 *c = dmd + 2; // vec3 *c = dmd + 2;
vec3 *d = dmd + 3; // vec3 *d = dmd + 3;
vec3 *t = dmd + 4; // vec3 *t = dmd + 4;
vec3 *f = dmd + 5; // vec3 *f = dmd + 5;
/* draw vertices */ // /* draw vertices */
ddraw_line(*a, *b); // ddraw_line(*a, *b);
ddraw_line(*b, *c); // ddraw_line(*b, *c);
ddraw_line(*c, *d); // ddraw_line(*c, *d);
ddraw_line(*d, *a); // ddraw_line(*d, *a);
/* draw roof */ // /* draw roof */
ddraw_line(*a, *t); // ddraw_line(*a, *t);
ddraw_line(*b, *t); // ddraw_line(*b, *t);
ddraw_line(*c, *t); // ddraw_line(*c, *t);
ddraw_line(*d, *t); // ddraw_line(*d, *t);
/* draw floor */ // /* draw floor */
ddraw_line(*a, *f); // ddraw_line(*a, *f);
ddraw_line(*b, *f); // ddraw_line(*b, *f);
ddraw_line(*c, *f); // ddraw_line(*c, *f);
ddraw_line(*d, *f); // ddraw_line(*d, *f);
poly_free(&p); // poly_free(&p);
} }
void ddraw_cone(vec3 center, vec3 top, float radius) { void ddraw_cone(vec3 center, vec3 top, float radius) {
vec3 diff3 = sub3(top, center); vec3 diff3 = sub3(top, center);
@ -25046,20 +24608,27 @@ static char **backtrace_symbols(void *const *sym,int num) { return 0; }
#endif #endif
char *callstack( int traces ) { char *callstack( int traces ) {
static __thread char *output = 0; #if is(tcc) && is(linux)
if(!output ) output = SYS_MEM_REALLOC( 0, 128 * (64+2) ); return "";
if( output ) output[0] = '\0'; #endif
char *ptr = output; #if is(ems) // there is a stack overflow failure somewhere in the impl below
static char empty[1]; return empty[0] = '\0', empty;
#endif
enum { skip = 1 }; /* exclude 1 trace from stack (this function) */ enum { skip = 1 }; /* exclude 1 trace from stack (this function) */
enum { maxtraces = 128 }; enum { maxtraces = 96 };
static __thread char *output = 0;
if(!output ) output = SYS_MEM_REALLOC( 0, maxtraces * (128+2) );
if( output ) output[0] = '\0';
char *ptr = output;
int inc = 1; int inc = 1;
if( traces < 0 ) traces = -traces, inc = -1; if( traces < 0 ) traces = -traces, inc = -1;
if( traces == 0 ) return ""; if( traces == 0 ) return "";
if( traces > maxtraces ) traces = maxtraces; if( traces > maxtraces ) traces = maxtraces;
void* stacks[maxtraces/* + 1*/]; // = { 0 }; void* stacks[maxtraces + 1]; stacks[maxtraces] = NULL; // = { 0 };
traces = backtrace( stacks, traces ); traces = backtrace( stacks, traces );
char **symbols = backtrace_symbols( stacks, traces ); // @todo: optimization: map(void*,char*) cache; and retrieve only symbols not in cache char **symbols = backtrace_symbols( stacks, traces ); // @todo: optimization: map(void*,char*) cache; and retrieve only symbols not in cache
@ -25091,10 +24660,11 @@ char *callstack( int traces ) {
ifdef(cpp, __cxa_demangle(info.dli_sname, NULL, 0, NULL), info.dli_sname); ifdef(cpp, __cxa_demangle(info.dli_sname, NULL, 0, NULL), info.dli_sname);
strcpy( demangled, dmgbuf ? dmgbuf : info.dli_sname ); strcpy( demangled, dmgbuf ? dmgbuf : info.dli_sname );
symbols[i] = demangled; symbols[i] = demangled;
if( dmgbuf ) free( (void*)dmgbuf ); ifdef(cpp, dmgbuf && free( (void*)dmgbuf ) );
} }
#endif #endif
ptr += sprintf(ptr, "%03d: %#016llx %s\n", ++L, (unsigned long long)(uintptr_t)stacks[i], symbols[i]); // format gymnastics because %p is not standard when printing pointers if( symbols[i] )
ptr += sprintf(ptr, "%03d: %p %s\n", ++L, (void*)(uintptr_t)stacks[i], symbols[i]); // format gymnastics because %p is not standard when printing pointers
} }
#if is(linux) || is(osx) #if is(linux) || is(osx)
@ -27004,21 +26574,21 @@ bool window_create_from_handle(void *handle, float scale, unsigned flags) {
if( flag("--fullscreen") ) scale = 100; if( flag("--fullscreen") ) scale = 100;
scale = (scale < 1 ? scale * 100 : scale); scale = (scale < 1 ? scale * 100 : scale);
bool FLAGS_FULLSCREEN = scale > 101; bool FLAGS_FULLSCREEN = scale > 100;
bool FLAGS_FULLSCREEN_BORDERLESS = scale == 101;
bool FLAGS_FULLSCREEN_DESKTOP = scale == 100; bool FLAGS_FULLSCREEN_DESKTOP = scale == 100;
bool FLAGS_WINDOWED = scale < 100 || FLAGS_FULLSCREEN_BORDERLESS; bool FLAGS_WINDOWED = scale < 100;
flags |= FLAGS_FULLSCREEN_BORDERLESS == 1 ? WINDOW_BORDERLESS : 0;
bool FLAGS_TRANSPARENT = flag("--transparent") || (flags & WINDOW_TRANSPARENT); bool FLAGS_TRANSPARENT = flag("--transparent") || (flags & WINDOW_TRANSPARENT);
if( FLAGS_TRANSPARENT ) FLAGS_FULLSCREEN = 0, FLAGS_FULLSCREEN_DESKTOP = 0, FLAGS_WINDOWED = 1; if( FLAGS_TRANSPARENT ) FLAGS_FULLSCREEN = 0, FLAGS_FULLSCREEN_DESKTOP = 0, FLAGS_WINDOWED = 1;
scale = (scale > 100 ? 100 : scale) / 100.f; scale = (scale > 100 ? 100 : scale) / 100.f;
int winWidth = window_canvas().w * scale; int winWidth = window_canvas().w * scale;
int winHeight = window_canvas().h * scale; int winHeight = window_canvas().h * scale;
/*
if (tests_captureframes()) { if (tests_captureframes()) {
winWidth = 1280; winWidth = 1280;
winHeight = 720; winHeight = 720;
} }
*/
window_hints(flags); window_hints(flags);
@ -28312,7 +27882,7 @@ void *obj_setmeta(void *o, const char *key, const char *value) {
void *ret = 0; void *ret = 0;
do_threadlock(oms_lock) { do_threadlock(oms_lock) {
if(!oms) map_init_int(oms); if(!oms) map_init_int(oms);
int *q = map_find_or_add(oms, intern(va("%llu-%s",obj_id((obj*)o),key)), 0); int *q = map_find_or_add(oms, intern(va("%p-%s",(void*)obj_id((obj*)o),key)), 0);
if(!*q && !value[0]) {} else *q = intern(value); if(!*q && !value[0]) {} else *q = intern(value);
quark(*q), ret = o; quark(*q), ret = o;
} }
@ -28322,7 +27892,7 @@ const char* obj_meta(const void *o, const char *key) {
const char *ret = 0; const char *ret = 0;
do_threadlock(oms_lock) { do_threadlock(oms_lock) {
if(!oms) map_init_int(oms); if(!oms) map_init_int(oms);
int *q = map_find_or_add(oms, intern(va("%llu-%s",obj_id((obj*)o),key)), 0); int *q = map_find_or_add(oms, intern(va("%p-%s",(void*)obj_id((obj*)o),key)), 0);
ret = quark(*q); ret = quark(*q);
} }
return ret; return ret;
@ -28428,10 +27998,10 @@ void test_obj_exact(void *o1, void *o2) {
bool obj_hexdump(const void *oo) { bool obj_hexdump(const void *oo) {
const obj *o = (const obj *)oo; const obj *o = (const obj *)oo;
int header = 1 * sizeof(obj); int header = 1 * sizeof(obj);
printf("; name[%s] type[%s] id[%d..%d] unused[%08x] sizeof[%02d] %llx\n", printf("; name[%s] type[%s] id[%d..%d] unused[%08x] sizeof[%02d] %p\n",
obj_name(o), obj_type(o), obj_name(o), obj_type(o),
(int)o->objid>>16, (int)o->objid&0xffff, (int)o->objunused, (int)o->objid>>16, (int)o->objid&0xffff, (int)o->objunused,
obj_sizeof(o), o->objheader); obj_sizeof(o), (void*)o->objheader);
return hexdump(obj_datac(o) - header, obj_size(o) + header), 1; return hexdump(obj_datac(o) - header, obj_size(o) + header), 1;
} }
int obj_print(const void *o) { int obj_print(const void *o) {
@ -28479,7 +28049,7 @@ const char *p2s(const char *type, void *p) {
else if( !strcmp(type, "unsigned") ) return itoa1(*(unsigned*)p); else if( !strcmp(type, "unsigned") ) return itoa1(*(unsigned*)p);
else if( !strcmp(type, "float") ) return ftoa1(*(float*)p); else if( !strcmp(type, "float") ) return ftoa1(*(float*)p);
else if( !strcmp(type, "double") ) return ftoa1(*(double*)p); else if( !strcmp(type, "double") ) return ftoa1(*(double*)p);
else if( !strcmp(type, "uintptr_t") ) return va("%08llx", *(uintptr_t*)p); else if( !strcmp(type, "uintptr_t") ) return va("%p", (void*)*(uintptr_t*)p);
else if( !strcmp(type, "vec2i") ) return itoa2(*(vec2i*)p); else if( !strcmp(type, "vec2i") ) return itoa2(*(vec2i*)p);
else if( !strcmp(type, "vec3i") ) return itoa3(*(vec3i*)p); else if( !strcmp(type, "vec3i") ) return itoa3(*(vec3i*)p);
else if( !strcmp(type, "vec2") ) return ftoa2(*(vec2*)p); else if( !strcmp(type, "vec2") ) return ftoa2(*(vec2*)p);
@ -30804,7 +30374,7 @@ void editor_frame( void (*game)(unsigned, float, double) ) {
UI_MENU_ITEM(ICON_SKIP, editor_send(window_has_pause() ? "frame" : "slomo")) \ UI_MENU_ITEM(ICON_SKIP, editor_send(window_has_pause() ? "frame" : "slomo")) \
UI_MENU_ITEM(ICON_MDI_STOP, editor_send("stop")) \ UI_MENU_ITEM(ICON_MDI_STOP, editor_send("stop")) \
UI_MENU_ITEM(ICON_MDI_EJECT, editor_send("eject")) \ UI_MENU_ITEM(ICON_MDI_EJECT, editor_send("eject")) \
UI_MENU_ITEM(STATS, stats_mode = (++stats_mode) % 3) \ UI_MENU_ITEM(STATS, stats_mode = (stats_mode+1) % 3) \
UI_MENU_ALIGN_RIGHT(32+32+32+32+32+32+32 + 32*2*is_borderless + 10, clicked_titlebar = time_ms()) \ UI_MENU_ALIGN_RIGHT(32+32+32+32+32+32+32 + 32*2*is_borderless + 10, clicked_titlebar = time_ms()) \
if(ingame) ui_disable(); \ if(ingame) ui_disable(); \
UI_MENU_ITEM(ICON_MD_FOLDER_SPECIAL, editor_send("browser")) \ UI_MENU_ITEM(ICON_MD_FOLDER_SPECIAL, editor_send("browser")) \

View File

@ -88,6 +88,10 @@
#ifndef V4K_H #ifndef V4K_H
#define V4K_H #define V4K_H
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -399,7 +403,7 @@ extern "C" {
static void fn(void) static void fn(void)
#elif defined __TINYC__ // tcc... #elif defined __TINYC__ // tcc...
#define AUTORUN_(fn) \ #define AUTORUN_(fn) \
__attribute__((constructor)) \ __attribute((constructor)) \
static void fn(void) static void fn(void)
#else // gcc,clang,clang-cl... #else // gcc,clang,clang-cl...
#define AUTORUN_(fn) \ #define AUTORUN_(fn) \
@ -907,7 +911,7 @@ API void (set_clear)(set* m);
// aliases: // aliases:
#ifndef map_init_int #ifndef map_init_int
#define map_init_int(m) map_init((m), less_int, hash_64) // hash_int #define map_init_int(m) map_init((m), less_int, hash_int) // hash_64
#define map_init_str(m) map_init((m), less_str, hash_str) #define map_init_str(m) map_init((m), less_str, hash_str)
#define map_init_ptr(m) map_init((m), less_ptr, hash_ptr) #define map_init_ptr(m) map_init((m), less_ptr, hash_ptr)
#endif #endif
@ -1756,44 +1760,6 @@ API int audio_queue( const void *samples, int num_samples, int flags );
// [src] https://gist.github.com/vurtun/95f088e4889da2474ad1ce82d7911fee // [src] https://gist.github.com/vurtun/95f088e4889da2474ad1ce82d7911fee
// - rlyeh, public domain. // - rlyeh, public domain.
#ifndef GJK_H
#define GJK_H
#define GJK_MAX_ITERATIONS 20
typedef struct gjk_support {
int aid, bid;
vec3 a;
vec3 b;
} gjk_support;
typedef struct gjk_vertex {
vec3 a;
vec3 b;
vec3 p;
int aid, bid;
} gjk_vertex;
typedef struct gjk_simplex {
int max_iter, iter;
int hit, cnt;
gjk_vertex v[4];
float bc[4], D;
} gjk_simplex;
typedef struct gjk_result {
int hit;
vec3 p0;
vec3 p1;
float distance_squared;
int iterations;
} gjk_result;
int gjk(gjk_simplex *s, const gjk_support *sup, vec3 *dv);
gjk_result gjk_analyze(const gjk_simplex *s);
gjk_result gjk_quad(float a_radius, float b_radius);
#endif
//typedef struct gjk_result gjk_result;
typedef struct line { vec3 a, b; } line; typedef struct line { vec3 a, b; } line;
typedef struct sphere { vec3 c; float r; } sphere; typedef struct sphere { vec3 c; float r; } sphere;
typedef struct aabb { vec3 min, max; } aabb; typedef struct aabb { vec3 min, max; } aabb;
@ -1801,7 +1767,6 @@ typedef struct plane { vec3 p, n;
typedef struct capsule { vec3 a, b; float r; } capsule; typedef struct capsule { vec3 a, b; float r; } capsule;
typedef struct ray { vec3 p, d; } ray; typedef struct ray { vec3 p, d; } ray;
typedef struct triangle { vec3 p0,p1,p2; } triangle; typedef struct triangle { vec3 p0,p1,p2; } triangle;
typedef struct poly { vec3* verts; int cnt; } poly;
typedef union frustum { struct { vec4 l, r, t, b, n, f; }; vec4 pl[6]; float v[24]; } frustum; typedef union frustum { struct { vec4 l, r, t, b, n, f; }; vec4 pl[6]; float v[24]; } frustum;
#define line(...) C_CAST(line, __VA_ARGS__) #define line(...) C_CAST(line, __VA_ARGS__)
@ -1811,7 +1776,6 @@ typedef union frustum { struct { vec4 l, r, t, b, n, f; }; vec4 pl[6]; float v
#define capsule(...) C_CAST(capsule, __VA_ARGS__) #define capsule(...) C_CAST(capsule, __VA_ARGS__)
#define ray(p,normdir) C_CAST(ray, p, normdir) #define ray(p,normdir) C_CAST(ray, p, normdir)
#define triangle(...) C_CAST(triangle, __VA_ARGS__) #define triangle(...) C_CAST(triangle, __VA_ARGS__)
#define poly(...) C_CAST(poly, __VA_ARGS__)
#define frustum(...) C_CAST(frustum, __VA_ARGS__) #define frustum(...) C_CAST(frustum, __VA_ARGS__)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -1852,7 +1816,6 @@ API hit* sphere_hit_capsule(sphere s, capsule c);
API hit* sphere_hit_sphere(sphere a, sphere b); API hit* sphere_hit_sphere(sphere a, sphere b);
API int sphere_test_aabb(sphere s, aabb a); API int sphere_test_aabb(sphere s, aabb a);
API int sphere_test_capsule(sphere s, capsule c); API int sphere_test_capsule(sphere s, capsule c);
API int sphere_test_poly(sphere s, poly p);
API int sphere_test_sphere(sphere a, sphere b); API int sphere_test_sphere(sphere a, sphere b);
/* aabb */ /* aabb */
API vec3 aabb_closest_point(aabb a, vec3 p); API vec3 aabb_closest_point(aabb a, vec3 p);
@ -1863,7 +1826,6 @@ API hit* aabb_hit_capsule(aabb a, capsule c);
API hit* aabb_hit_sphere(aabb a, sphere s); API hit* aabb_hit_sphere(aabb a, sphere s);
API int aabb_test_aabb(aabb a, aabb b); API int aabb_test_aabb(aabb a, aabb b);
API int aabb_test_capsule(aabb a, capsule c); API int aabb_test_capsule(aabb a, capsule c);
API int aabb_test_poly(aabb a, poly p);
API int aabb_test_sphere(aabb a, sphere s); API int aabb_test_sphere(aabb a, sphere s);
/* capsule */ /* capsule */
API float capsule_distance2_point(capsule c, vec3 p); API float capsule_distance2_point(capsule c, vec3 p);
@ -1873,28 +1835,7 @@ API hit* capsule_hit_capsule(capsule a, capsule b);
API hit* capsule_hit_sphere(capsule c, sphere s); API hit* capsule_hit_sphere(capsule c, sphere s);
API int capsule_test_aabb(capsule c, aabb a); API int capsule_test_aabb(capsule c, aabb a);
API int capsule_test_capsule(capsule a, capsule b); API int capsule_test_capsule(capsule a, capsule b);
API int capsule_test_poly(capsule c, poly p);
API int capsule_test_sphere(capsule c, sphere s); API int capsule_test_sphere(capsule c, sphere s);
/* poly: query */
API int poly_test_sphere(poly p, sphere s);
API int poly_test_aabb(poly p, aabb a);
API int poly_test_capsule(poly p, capsule c);
API int poly_test_poly(poly a, poly b);
/* poly: query transformed */
API int poly_test_sphere_transform(poly p, vec3 pos3, mat33 rot33, sphere s);
API int poly_test_aabb_transform(poly p, vec3 apos3, mat33 arot33, aabb a);
API int poly_test_capsule_transform(poly p, vec3 pos3, mat33 rot33, capsule c);
API int poly_test_poly_transform(poly a, vec3 apos3, mat33 arot33, poly b, vec3 bpos3, mat33 brot33);
/* poly: gjk result */
API int poly_hit_sphere(struct gjk_result *res, poly p, sphere s);
API int poly_hit_aabb(struct gjk_result *res, poly p, aabb a);
API int poly_hit_capsule(struct gjk_result *res, poly p, capsule c);
API int poly_hit_poly(struct gjk_result *res, poly a, poly b);
/* poly: gjk result transformed */
API int poly_hit_sphere_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, sphere s);
API int poly_hit_aabb_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, aabb a);
API int poly_hit_capsule_transform(struct gjk_result *res, poly p, vec3 pos3, mat33 rot33, capsule c);
API int poly_hit_poly_transform(struct gjk_result *res, poly a, vec3 at3, mat33 ar33, poly b, vec3 bt3, mat33 br33);
API vec4 plane4(vec3 p, vec3 n); API vec4 plane4(vec3 p, vec3 n);
@ -1902,12 +1843,6 @@ API frustum frustum_build(mat44 projview);
API int frustum_test_sphere(frustum f, sphere s); API int frustum_test_sphere(frustum f, sphere s);
API int frustum_test_aabb(frustum f, aabb a); API int frustum_test_aabb(frustum f, aabb a);
API poly poly_alloc(int cnt);
API void poly_free(poly *p);
API poly pyramid(vec3 from, vec3 to, float size); // poly_free() required
API poly diamond(vec3 from, vec3 to, float size); // poly_free() required
API void collide_demo(); // debug draw collisions API void collide_demo(); // debug draw collisions
#line 0 #line 0
@ -5060,4 +4995,10 @@ API int ui_engine();
#endif #endif
#endif #endif
#if defined __TINYC__ && defined __linux
#ifndef __builtin_alloca
#define __builtin_alloca alloca
#endif
#endif
#endif // V4K_H #endif // V4K_H