wip lightmapper + GUI improvements
parent
1e65c7cdcf
commit
ab06ce0192
8
MAKE.bat
8
MAKE.bat
|
@ -31,6 +31,7 @@ if "%1"=="help" (
|
||||||
echo %0 [test] ; check untracked allocators in V4K
|
echo %0 [test] ; check untracked allocators in V4K
|
||||||
echo %0 [todo] ; check for @fixme and @todo
|
echo %0 [todo] ; check for @fixme and @todo
|
||||||
echo %0 [v4web] ; sync v4 website
|
echo %0 [v4web] ; sync v4 website
|
||||||
|
echo %0 [swap] ; toggle #line directives on/off
|
||||||
echo %0 [split^|join] ; engine/v4k* ^>split^> engine/split/* or engine/split/* ^>join^> engine/v4k*
|
echo %0 [split^|join] ; engine/v4k* ^>split^> engine/split/* or engine/split/* ^>join^> engine/v4k*
|
||||||
echo %0 [lua] ; execute lua script with v4k
|
echo %0 [lua] ; execute lua script with v4k
|
||||||
echo %0 [amalgamation] ; combine engine/v4k* into a single-header file
|
echo %0 [amalgamation] ; combine engine/v4k* into a single-header file
|
||||||
|
@ -243,6 +244,13 @@ if "%1"=="join" (
|
||||||
call tools\join
|
call tools\join
|
||||||
exit /b
|
exit /b
|
||||||
)
|
)
|
||||||
|
if "%1"=="swap" (
|
||||||
|
echo Swapping #line on v4k.h
|
||||||
|
call tools\linswap engine\v4k.h
|
||||||
|
echo Swapping #line on v4k.c
|
||||||
|
call tools\linswap engine\v4k.c
|
||||||
|
exit /b
|
||||||
|
)
|
||||||
|
|
||||||
rem fuse binaries and zipfiles
|
rem fuse binaries and zipfiles
|
||||||
if "%1"=="fuse" (
|
if "%1"=="fuse" (
|
||||||
|
|
46
bind/v4k.lua
46
bind/v4k.lua
|
@ -1520,17 +1520,23 @@ ffi.cdef([[
|
||||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 fire;
|
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 fire;
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:vec4 pos;
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:vec4 pos;
|
||||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 sca;
|
//lcpp INF [0000] vec2: macro name but used as C declaration in:vec2 sca;
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:void (*drawrect)(void* userdata, const char *skin, vec4 rect);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:void (*drawrect)(void* userdata, const char *skin, const char *fallback, vec4 rect);
|
||||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:void (*getskinsize)(void* userdata, const char *skin, vec2 *size);
|
//lcpp INF [0000] vec2: macro name but used as C declaration in:void (*getskinsize)(void* userdata, const char *skin, const char *fallback, vec2 *size);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:void (*getscissorrect)(void* userdata, const char *skin, vec4 rect, vec4 *dims);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:void (*getscissorrect)(void* userdata, const char *skin, const char *fallback, vec4 rect, vec4 *dims);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:void (*getscissorrect)(void* userdata, const char *skin, vec4 rect, vec4 *dims);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:void (*getscissorrect)(void* userdata, const char *skin, const char *fallback, vec4 rect, vec4 *dims);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:bool (*ismouseinrect)(void* userdata, const char *skin, vec4 rect);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:bool (*ismouseinrect)(void* userdata, const char *skin, const char *fallback, vec4 rect);
|
||||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 gui_getskinsize(const char *skin);
|
//lcpp INF [0000] vec2: macro name but used as C declaration in:API vec2 gui_getskinsize(const char *skin, const char *fallback);
|
||||||
//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 gui_getskinsize(const char *skin);
|
//lcpp INF [0000] vec2: macro name but used as C declaration in:STATIC vec2 gui_getskinsize(const char *skin, const char *fallback);
|
||||||
//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 gui_getskinsize(const char *skin);
|
//lcpp INF [0000] vec2: macro name but used as C declaration in: vec2 gui_getskinsize(const char *skin, const char *fallback);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:API bool gui_ismouseinrect(const char *skin, vec4 rect);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:API bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC bool gui_ismouseinrect(const char *skin, vec4 rect);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in: bool gui_ismouseinrect(const char *skin, vec4 rect);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in: bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:API vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:API vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
|
//lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
|
//lcpp INF [0000] vec4: macro name but used as C declaration in: vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:API void gui_panel_id(int id, vec4 rect, const char *skin);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:API void gui_panel_id(int id, vec4 rect, const char *skin);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC void gui_panel_id(int id, vec4 rect, const char *skin);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in:STATIC void gui_panel_id(int id, vec4 rect, const char *skin);
|
||||||
//lcpp INF [0000] vec4: macro name but used as C declaration in: void gui_panel_id(int id, vec4 rect, const char *skin);
|
//lcpp INF [0000] vec4: macro name but used as C declaration in: void gui_panel_id(int id, vec4 rect, const char *skin);
|
||||||
|
@ -2991,6 +2997,9 @@ float speed;
|
||||||
anim_t* anims;
|
anim_t* anims;
|
||||||
} anims_t;
|
} anims_t;
|
||||||
anims_t animations(const char *pathfile, int flags);
|
anims_t animations(const char *pathfile, int flags);
|
||||||
|
typedef struct lightmap_t {
|
||||||
|
struct lm_context *ctx;
|
||||||
|
} lightmap_t;
|
||||||
typedef struct skybox_t {
|
typedef struct skybox_t {
|
||||||
handle program;
|
handle program;
|
||||||
mesh_t geometry;
|
mesh_t geometry;
|
||||||
|
@ -3315,7 +3324,7 @@ unsigned play;
|
||||||
bool paused;
|
bool paused;
|
||||||
struct atlas_t *a;
|
struct atlas_t *a;
|
||||||
} sprite_t;
|
} sprite_t;
|
||||||
enum { OBJTYPE_sprite_t = 10 }; typedef struct { unsigned static_assert_on_L__LINE__ : !!(10 <= 255); } static_assert_on_Lconcat(_L,3938)___COUNTER__; typedef struct { unsigned static_assert_on_L__LINE__ : !!(sizeof(sprite_t)); } static_assert_on_Lconcat(_L,3938)___COUNTER__;;
|
enum { OBJTYPE_sprite_t = 10 }; typedef struct { unsigned static_assert_on_L__LINE__ : !!(10 <= 255); } static_assert_on_Lconcat(_L,3945)___COUNTER__; typedef struct { unsigned static_assert_on_L__LINE__ : !!(sizeof(sprite_t)); } static_assert_on_Lconcat(_L,3945)___COUNTER__;;
|
||||||
void sprite_ctor(sprite_t *s);
|
void sprite_ctor(sprite_t *s);
|
||||||
void sprite_dtor(sprite_t *s);
|
void sprite_dtor(sprite_t *s);
|
||||||
void sprite_tick(sprite_t *s);
|
void sprite_tick(sprite_t *s);
|
||||||
|
@ -3325,17 +3334,18 @@ enum { OBJTYPE_sprite_t = 10 }; typedef struct { unsigned static_assert_on
|
||||||
void sprite_del(sprite_t *s);
|
void sprite_del(sprite_t *s);
|
||||||
void sprite_setanim(sprite_t *s, unsigned name);
|
void sprite_setanim(sprite_t *s, unsigned name);
|
||||||
typedef struct guiskin_t {
|
typedef struct guiskin_t {
|
||||||
void (*drawrect)(void* userdata, const char *skin, vec4 rect);
|
void (*drawrect)(void* userdata, const char *skin, const char *fallback, vec4 rect);
|
||||||
void (*getskinsize)(void* userdata, const char *skin, vec2 *size);
|
void (*getskinsize)(void* userdata, const char *skin, const char *fallback, vec2 *size);
|
||||||
void (*getscissorrect)(void* userdata, const char *skin, vec4 rect, vec4 *dims);
|
void (*getscissorrect)(void* userdata, const char *skin, const char *fallback, vec4 rect, vec4 *dims);
|
||||||
bool (*ismouseinrect)(void* userdata, const char *skin, vec4 rect);
|
bool (*ismouseinrect)(void* userdata, const char *skin, const char *fallback, vec4 rect);
|
||||||
void (*free)(void* userdata);
|
void (*free)(void* userdata);
|
||||||
void *userdata;
|
void *userdata;
|
||||||
} guiskin_t;
|
} guiskin_t;
|
||||||
void gui_pushskin(guiskin_t skin);
|
void gui_pushskin(guiskin_t skin);
|
||||||
void* gui_userdata();
|
void* gui_userdata();
|
||||||
vec2 gui_getskinsize(const char *skin);
|
vec2 gui_getskinsize(const char *skin, const char *fallback);
|
||||||
bool gui_ismouseinrect(const char *skin, vec4 rect);
|
bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
|
vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
void gui_panel_id(int id, vec4 rect, const char *skin);
|
void gui_panel_id(int id, vec4 rect, const char *skin);
|
||||||
void gui_rect_id(int id, vec4 rect, const char *skin);
|
void gui_rect_id(int id, vec4 rect, const char *skin);
|
||||||
void gui_label_id(int id, const char *text, vec4 rect);
|
void gui_label_id(int id, const char *text, vec4 rect);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -45,13 +45,13 @@ int main() {
|
||||||
gui_rect(vec4(40,240, 240, 20*skinned->scale), "vial");
|
gui_rect(vec4(40,240, 240, 20*skinned->scale), "vial");
|
||||||
gui_rect(vec4(40,240, 160, 14*skinned->scale), "mp");
|
gui_rect(vec4(40,240, 160, 14*skinned->scale), "mp");
|
||||||
|
|
||||||
vec2 badge_size = gui_getskinsize("badge");
|
vec2 badge_size = gui_getskinsize("badge", 0);
|
||||||
badge_size.x += 2; // padding
|
badge_size.x += 2; // padding
|
||||||
gui_rect(vec4(60+badge_size.x*0,320, 1, 1), "badge");
|
gui_rect(vec4(60+badge_size.x*0,320, 1, 1), "badge");
|
||||||
gui_rect(vec4(60+badge_size.x*1,320, 1, 1), "badge");
|
gui_rect(vec4(60+badge_size.x*1,320, 1, 1), "badge");
|
||||||
gui_rect(vec4(60+badge_size.x*2,320, 1, 1), "badge_empty");
|
gui_rect(vec4(60+badge_size.x*2,320, 1, 1), "badge_empty");
|
||||||
|
|
||||||
vec2 slider_size = gui_getskinsize("slider");
|
vec2 slider_size = gui_getskinsize("slider", 0);
|
||||||
gui_slider(vec4(60, 480, 80*skinned->scale, 1), 0, 0.0f, 15.0f, 1.0f, &testval);
|
gui_slider(vec4(60, 480, 80*skinned->scale, 1), 0, 0.0f, 15.0f, 1.0f, &testval);
|
||||||
gui_slider_label(va(FONT_H1 "%.02f", testval2), vec4(60, 480+slider_size.y+10, 120*skinned->scale, 1), 0, -5.0f, 20.0f, 0.0f, &testval2);
|
gui_slider_label(va(FONT_H1 "%.02f", testval2), vec4(60, 480+slider_size.y+10, 120*skinned->scale, 1), 0, -5.0f, 20.0f, 0.0f, &testval2);
|
||||||
gui_panel_end();
|
gui_panel_end();
|
||||||
|
|
|
@ -0,0 +1,407 @@
|
||||||
|
#include "v4k.h"
|
||||||
|
|
||||||
|
#define LIGHTMAPPER_IMPLEMENTATION
|
||||||
|
// #define LM_DEBUG_INTERPOLATION
|
||||||
|
#include "3rd_lightmapper.h"
|
||||||
|
|
||||||
|
#define scene_t scene_t2
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float p[3];
|
||||||
|
float t[2];
|
||||||
|
} vertex_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GLuint program;
|
||||||
|
GLint u_lightmap;
|
||||||
|
GLint u_projection;
|
||||||
|
GLint u_view;
|
||||||
|
|
||||||
|
GLuint lightmap;
|
||||||
|
int w, h;
|
||||||
|
|
||||||
|
GLuint vao, vbo, ibo;
|
||||||
|
vertex_t *vertices;
|
||||||
|
unsigned short *indices;
|
||||||
|
unsigned int vertexCount, indexCount;
|
||||||
|
} scene_t;
|
||||||
|
|
||||||
|
static int initScene(scene_t *scene);
|
||||||
|
static void drawScene(scene_t *scene, float *view, float *projection);
|
||||||
|
static void destroyScene(scene_t *scene);
|
||||||
|
|
||||||
|
static int bake(scene_t *scene)
|
||||||
|
{
|
||||||
|
lm_context *ctx = lmCreate(
|
||||||
|
64, // hemisphere resolution (power of two, max=512)
|
||||||
|
0.001f, 100.0f, // zNear, zFar of hemisphere cameras
|
||||||
|
1.0f, 1.0f, 1.0f, // background color (white for ambient occlusion)
|
||||||
|
2, 0.01f, // lightmap interpolation threshold (small differences are interpolated rather than sampled)
|
||||||
|
// check debug_interpolation.tga for an overview of sampled (red) vs interpolated (green) pixels.
|
||||||
|
0.0f); // modifier for camera-to-surface distance for hemisphere rendering.
|
||||||
|
// tweak this to trade-off between interpolated normals quality and other artifacts (see declaration).
|
||||||
|
|
||||||
|
if (!ctx)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: Could not initialize lightmapper.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w = scene->w, h = scene->h;
|
||||||
|
float *data = CALLOC(w * h * 4, sizeof(float));
|
||||||
|
for (int b = 0; b < 1; b++) {
|
||||||
|
memset(data, 0, w*h*4);
|
||||||
|
lmSetTargetLightmap(ctx, data, w, h, 4);
|
||||||
|
|
||||||
|
lmSetGeometry(ctx, NULL, // no transformation in this example
|
||||||
|
LM_FLOAT, (unsigned char*)scene->vertices + offsetof(vertex_t, p), sizeof(vertex_t),
|
||||||
|
LM_NONE , NULL , 0 , // no interpolated normals in this example
|
||||||
|
LM_FLOAT, (unsigned char*)scene->vertices + offsetof(vertex_t, t), sizeof(vertex_t),
|
||||||
|
scene->indexCount, LM_UNSIGNED_SHORT, scene->indices);
|
||||||
|
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
int vp[4];
|
||||||
|
float view[16], projection[16];
|
||||||
|
double lastUpdateTime = 0.0;
|
||||||
|
while (lmBegin(ctx, vp, view, projection))
|
||||||
|
{
|
||||||
|
// render to lightmapper framebuffer
|
||||||
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
|
drawScene(scene, view, projection);
|
||||||
|
|
||||||
|
// display progress every second (printf is expensive)
|
||||||
|
double time = time_ms() / 1000.0;
|
||||||
|
if (time - lastUpdateTime > 1.0)
|
||||||
|
{
|
||||||
|
lastUpdateTime = time;
|
||||||
|
printf("\r%6.2f%%", lmProgress(ctx) * 100.0f);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
lmEnd(ctx);
|
||||||
|
// window_swap();
|
||||||
|
}
|
||||||
|
printf("\rFinished baking %d triangles.\n", scene->indexCount / 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
lmDestroy(ctx);
|
||||||
|
|
||||||
|
// postprocess texture
|
||||||
|
float *temp = CALLOC(w * h * 4, sizeof(float));
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
lmImageDilate(data, temp, w, h, 4);
|
||||||
|
lmImageDilate(temp, data, w, h, 4);
|
||||||
|
}
|
||||||
|
lmImageSmooth(data, temp, w, h, 4);
|
||||||
|
lmImageDilate(temp, data, w, h, 4);
|
||||||
|
lmImagePower(data, w, h, 4, 1.0f / 2.2f, 0x7); // gamma correct color channels
|
||||||
|
FREE(temp);
|
||||||
|
|
||||||
|
// save result to a file
|
||||||
|
if (lmImageSaveTGAf("result.tga", data, w, h, 4, 1.0f))
|
||||||
|
printf("Saved result.tga\n");
|
||||||
|
|
||||||
|
// upload result
|
||||||
|
glBindTexture(GL_TEXTURE_2D, scene->lightmap);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_FLOAT, data);
|
||||||
|
FREE(data);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fpsCameraViewMatrix(float *view);
|
||||||
|
|
||||||
|
static void mainLoop(scene_t *scene)
|
||||||
|
{
|
||||||
|
glViewport(0, 0, window_width(), window_height());
|
||||||
|
|
||||||
|
// camera for glfw window
|
||||||
|
float view[16], projection[16];
|
||||||
|
fpsCameraViewMatrix(view);
|
||||||
|
perspective44(projection, 45.0f, window_aspect(), 0.01f, 100.0f);
|
||||||
|
|
||||||
|
// draw to screen with a blueish sky
|
||||||
|
glClearColor(0.6f, 0.8f, 1.0f, 1.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
drawScene(scene, view, projection);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
window_create(0.5, WINDOW_VSYNC_DISABLED);
|
||||||
|
|
||||||
|
scene_t scene = {0};
|
||||||
|
if (!initScene(&scene))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Could not initialize scene.\n");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
window_title("AO Baking demo");
|
||||||
|
|
||||||
|
while (window_swap())
|
||||||
|
{
|
||||||
|
mainLoop(&scene);
|
||||||
|
|
||||||
|
if( ui_panel("Lightmapper", PANEL_OPEN) ) {
|
||||||
|
ui_label2("Freecam", "Mouse + W/A/S/D/E/Q keys");
|
||||||
|
ui_label("Warning " ICON_MD_WARNING "@This will take a few seconds and bake a lightmap illuminated by: The mesh itself (initially black) + A white sky (1.0f, 1.0f, 1.0f)");
|
||||||
|
if( ui_button("Bake 1 light bounce") ) {
|
||||||
|
bake(&scene);
|
||||||
|
}
|
||||||
|
ui_panel_end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destroyScene(&scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
// helpers ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
static int loadSimpleObjFile(const char *filename, vertex_t **vertices, unsigned int *vertexCount, unsigned short **indices, unsigned int *indexCount);
|
||||||
|
|
||||||
|
static int initScene(scene_t *scene)
|
||||||
|
{
|
||||||
|
// load mesh
|
||||||
|
if (!loadSimpleObjFile("demos/art/meshes/gazebo.obj", &scene->vertices, &scene->vertexCount, &scene->indices, &scene->indexCount))
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error loading obj file\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &scene->vao);
|
||||||
|
glBindVertexArray(scene->vao);
|
||||||
|
|
||||||
|
glGenBuffers(1, &scene->vbo);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, scene->vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, scene->vertexCount * sizeof(vertex_t), scene->vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glGenBuffers(1, &scene->ibo);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, scene->ibo);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, scene->indexCount * sizeof(unsigned short), scene->indices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (void*)offsetof(vertex_t, p));
|
||||||
|
glEnableVertexAttribArray(1);
|
||||||
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (void*)offsetof(vertex_t, t));
|
||||||
|
|
||||||
|
// create lightmap texture
|
||||||
|
scene->w = 654;
|
||||||
|
scene->h = 654;
|
||||||
|
glGenTextures(1, &scene->lightmap);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, scene->lightmap);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
unsigned char emissive[] = { 0, 0, 0, 255 };
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, emissive);
|
||||||
|
|
||||||
|
// load shader
|
||||||
|
const char *vp =
|
||||||
|
"in vec3 a_position;\n"
|
||||||
|
"in vec2 a_texcoord;\n"
|
||||||
|
"uniform mat4 u_view;\n"
|
||||||
|
"uniform mat4 u_projection;\n"
|
||||||
|
"out vec2 v_texcoord;\n"
|
||||||
|
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
"gl_Position = u_projection * (u_view * vec4(a_position, 1.0));\n"
|
||||||
|
"v_texcoord = a_texcoord;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
const char *fp =
|
||||||
|
"in vec2 v_texcoord;\n"
|
||||||
|
"uniform sampler2D u_lightmap;\n"
|
||||||
|
"out vec4 o_color;\n"
|
||||||
|
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
"o_color = vec4(texture(u_lightmap, v_texcoord).rgb, gl_FrontFacing ? 1.0 : 0.0);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
scene->program = shader(vp, fp, "a_position,a_texcoord", "o_color", NULL);
|
||||||
|
if (!scene->program)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error loading shader\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
scene->u_view = glGetUniformLocation(scene->program, "u_view");
|
||||||
|
scene->u_projection = glGetUniformLocation(scene->program, "u_projection");
|
||||||
|
scene->u_lightmap = glGetUniformLocation(scene->program, "u_lightmap");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void drawScene(scene_t *scene, float *view, float *projection)
|
||||||
|
{
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
glUseProgram(scene->program);
|
||||||
|
glUniform1i(scene->u_lightmap, 0);
|
||||||
|
glUniformMatrix4fv(scene->u_projection, 1, GL_FALSE, projection);
|
||||||
|
glUniformMatrix4fv(scene->u_view, 1, GL_FALSE, view);
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, scene->lightmap);
|
||||||
|
|
||||||
|
glBindVertexArray(scene->vao);
|
||||||
|
glDrawElements(GL_TRIANGLES, scene->indexCount, GL_UNSIGNED_SHORT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroyScene(scene_t *scene)
|
||||||
|
{
|
||||||
|
FREE(scene->vertices);
|
||||||
|
FREE(scene->indices);
|
||||||
|
glDeleteVertexArrays(1, &scene->vao);
|
||||||
|
glDeleteBuffers(1, &scene->vbo);
|
||||||
|
glDeleteBuffers(1, &scene->ibo);
|
||||||
|
glDeleteTextures(1, &scene->lightmap);
|
||||||
|
glDeleteProgram(scene->program);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int loadSimpleObjFile(const char *filename, vertex_t **vertices, unsigned int *vertexCount, unsigned short **indices, unsigned int *indexCount)
|
||||||
|
{
|
||||||
|
FILE *file = fopen(filename, "rt");
|
||||||
|
if (!file)
|
||||||
|
return 0;
|
||||||
|
char line[1024];
|
||||||
|
|
||||||
|
// first pass
|
||||||
|
unsigned int np = 0, nn = 0, nt = 0, nf = 0;
|
||||||
|
while (!feof(file))
|
||||||
|
{
|
||||||
|
fgets(line, 1024, file);
|
||||||
|
if (line[0] == '#') continue;
|
||||||
|
if (line[0] == 'v')
|
||||||
|
{
|
||||||
|
if (line[1] == ' ') { np++; continue; }
|
||||||
|
if (line[1] == 'n') { nn++; continue; }
|
||||||
|
if (line[1] == 't') { nt++; continue; }
|
||||||
|
assert(!"unknown vertex attribute");
|
||||||
|
}
|
||||||
|
if (line[0] == 'f') { nf++; continue; }
|
||||||
|
assert(!"unknown identifier");
|
||||||
|
}
|
||||||
|
assert(np && np == nn && np == nt && nf); // only supports obj files without separately indexed vertex attributes
|
||||||
|
|
||||||
|
// allocate memory
|
||||||
|
*vertexCount = np;
|
||||||
|
*vertices = CALLOC(np, sizeof(vertex_t));
|
||||||
|
*indexCount = nf * 3;
|
||||||
|
*indices = CALLOC(nf * 3, sizeof(unsigned short));
|
||||||
|
|
||||||
|
// second pass
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
unsigned int cp = 0, cn = 0, ct = 0, cf = 0;
|
||||||
|
while (!feof(file))
|
||||||
|
{
|
||||||
|
fgets(line, 1024, file);
|
||||||
|
if (line[0] == '#') continue;
|
||||||
|
if (line[0] == 'v')
|
||||||
|
{
|
||||||
|
if (line[1] == ' ') { float *p = (*vertices)[cp++].p; char *e1, *e2; p[0] = (float)strtod(line + 2, &e1); p[1] = (float)strtod(e1, &e2); p[2] = (float)strtod(e2, 0); continue; }
|
||||||
|
if (line[1] == 'n') { /*float *n = (*vertices)[cn++].n; char *e1, *e2; n[0] = (float)strtod(line + 3, &e1); n[1] = (float)strtod(e1, &e2); n[2] = (float)strtod(e2, 0);*/ continue; } // no normals needed
|
||||||
|
if (line[1] == 't') { float *t = (*vertices)[ct++].t; char *e1; t[0] = (float)strtod(line + 3, &e1); t[1] = (float)strtod(e1, 0); continue; }
|
||||||
|
assert(!"unknown vertex attribute");
|
||||||
|
}
|
||||||
|
if (line[0] == 'f')
|
||||||
|
{
|
||||||
|
unsigned short *tri = (*indices) + cf;
|
||||||
|
cf += 3;
|
||||||
|
char *e1, *e2, *e3 = line + 1;
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
unsigned long pi = strtoul(e3 + 1, &e1, 10);
|
||||||
|
assert(e1[0] == '/');
|
||||||
|
unsigned long ti = strtoul(e1 + 1, &e2, 10);
|
||||||
|
assert(e2[0] == '/');
|
||||||
|
unsigned long ni = strtoul(e2 + 1, &e3, 10);
|
||||||
|
assert(pi == ti && pi == ni);
|
||||||
|
tri[i] = (unsigned short)(pi - 1);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert(!"unknown identifier");
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void fpsCameraViewMatrix(float *view)
|
||||||
|
{
|
||||||
|
// initial camera config
|
||||||
|
static float position[] = { 0.0f, 0.3f, 1.5f };
|
||||||
|
static float rotation[] = { 0.0f, 0.0f };
|
||||||
|
|
||||||
|
// mouse look
|
||||||
|
static double lastMouse[] = { 0.0, 0.0 };
|
||||||
|
double mouse_coord[2];
|
||||||
|
mouse_coord[0] = input(MOUSE_X);
|
||||||
|
mouse_coord[1] = input(MOUSE_Y);
|
||||||
|
if (input(MOUSE_L))
|
||||||
|
{
|
||||||
|
rotation[0] += (float)(mouse_coord[1] - lastMouse[1]) * -0.2f;
|
||||||
|
rotation[1] += (float)(mouse_coord[0] - lastMouse[0]) * -0.2f;
|
||||||
|
}
|
||||||
|
lastMouse[0] = mouse_coord[0];
|
||||||
|
lastMouse[1] = mouse_coord[1];
|
||||||
|
|
||||||
|
float rotationY[16], rotationX[16], rotationYX[16];
|
||||||
|
rotation44(rotationX, rotation[0], 1.0f, 0.0f, 0.0f);
|
||||||
|
rotation44(rotationY, rotation[1], 0.0f, 1.0f, 0.0f);
|
||||||
|
multiply44x2(rotationYX, rotationY, rotationX);
|
||||||
|
|
||||||
|
// keyboard movement (WSADEQ)
|
||||||
|
float speed = input(KEY_SHIFT) ? 0.1f : 0.01f;
|
||||||
|
vec3 movement = {0};
|
||||||
|
if (input(KEY_W)) movement.z -= speed;
|
||||||
|
if (input(KEY_S)) movement.z += speed;
|
||||||
|
if (input(KEY_A)) movement.x -= speed;
|
||||||
|
if (input(KEY_D)) movement.x += speed;
|
||||||
|
if (input(KEY_E)) movement.y -= speed;
|
||||||
|
if (input(KEY_Q)) movement.y += speed;
|
||||||
|
|
||||||
|
vec3 worldMovement = transform344(rotationYX, movement);
|
||||||
|
position[0] += worldMovement.x;
|
||||||
|
position[1] += worldMovement.y;
|
||||||
|
position[2] += worldMovement.z;
|
||||||
|
|
||||||
|
// construct view matrix
|
||||||
|
float inverseRotation[16], inverseTranslation[16];
|
||||||
|
transpose44(inverseRotation, rotationYX);
|
||||||
|
translation44(inverseTranslation, -position[0], -position[1], -position[2]);
|
||||||
|
multiply44x2(view, inverseRotation, inverseTranslation); // = inverse(translation(position) * rotationYX);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
76702 17.93% rendered hemicubes integrated to lightmap texels.
|
||||||
|
179388 41.94% interpolated lightmap texels.
|
||||||
|
171626 40.13% wasted lightmap texels.
|
||||||
|
|
||||||
|
29.95% of used texels were rendered.
|
||||||
|
#######################################################################
|
||||||
|
Finished baking 731 triangles.
|
||||||
|
Saved result.tga
|
||||||
|
|
||||||
|
vs
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
124 0.05% rendered hemicubes integrated to lightmap texels.
|
||||||
|
201 0.08% interpolated lightmap texels.
|
||||||
|
261947 99.88% wasted lightmap texels.
|
||||||
|
|
||||||
|
38.15% of used texels were rendered.
|
||||||
|
#######################################################################
|
||||||
|
Finished baking 731 triangles.
|
||||||
|
Saved result.tga
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
#include "v4k.h" // Minimal C sample
|
|
||||||
|
|
||||||
__thread int foo=0;
|
|
||||||
|
|
||||||
int worker(void *ud) {
|
|
||||||
printf("thread:%d\n", foo);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
foo=1;
|
|
||||||
printf("main:%d\n", foo);
|
|
||||||
thread_destroy(thread(worker, NULL));
|
|
||||||
return 0;
|
|
||||||
}
|
|
1852
engine/joint/v4k.h
1852
engine/joint/v4k.h
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -53,6 +53,7 @@
|
||||||
#define BQ_PLATFORM_IMPLEMENTATION // websocket
|
#define BQ_PLATFORM_IMPLEMENTATION // websocket
|
||||||
#define BQ_WEBSOCKET_IMPLEMENTATION // websocket
|
#define BQ_WEBSOCKET_IMPLEMENTATION // websocket
|
||||||
#define XML_C // xml
|
#define XML_C // xml
|
||||||
|
#define LIGHTMAPPER_IMPLEMENTATION // lightmapper
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define MA_NO_RUNTIME_LINKING // miniaudio osx
|
#define MA_NO_RUNTIME_LINKING // miniaudio osx
|
||||||
#define _GLFW_COCOA // glfw osx
|
#define _GLFW_COCOA // glfw osx
|
||||||
|
@ -217,4 +218,6 @@ static char *ui_filter = 0;
|
||||||
{{FILE:3rd_lite_sys.h}}
|
{{FILE:3rd_lite_sys.h}}
|
||||||
{{FILE:3rd_lite.h}}
|
{{FILE:3rd_lite.h}}
|
||||||
|
|
||||||
|
{{FILE:3rd_lightmapper.h}}
|
||||||
|
|
||||||
#endif // V4K_3RD
|
#endif // V4K_3RD
|
||||||
|
|
|
@ -118,17 +118,23 @@ void *gui_userdata() {
|
||||||
return last_skin->userdata;
|
return last_skin->userdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 gui_getskinsize(const char *skin) {
|
vec2 gui_getskinsize(const char *skin, const char *fallback) {
|
||||||
vec2 size={0};
|
vec2 size={0};
|
||||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &size);
|
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, fallback, &size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gui_ismouseinrect(const char *skin, vec4 rect) {
|
bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect) {
|
||||||
if (last_skin->ismouseinrect) return last_skin->ismouseinrect(last_skin->userdata, skin, rect);
|
if (last_skin->ismouseinrect) return last_skin->ismouseinrect(last_skin->userdata, skin, fallback, rect);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect) {
|
||||||
|
vec4 scissor = rect;
|
||||||
|
if (last_skin->getscissorrect) last_skin->getscissorrect(last_skin->userdata, skin, fallback, rect, &scissor);
|
||||||
|
return scissor;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
gui_state_t *gui_getstate(int id) {
|
gui_state_t *gui_getstate(int id) {
|
||||||
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
||||||
|
@ -138,8 +144,8 @@ gui_state_t *gui_getstate(int id) {
|
||||||
void gui_panel_id(int id, vec4 rect, const char *skin) {
|
void gui_panel_id(int id, vec4 rect, const char *skin) {
|
||||||
(void)id;
|
(void)id;
|
||||||
vec4 scissor={0, 0, window_width(), window_height()};
|
vec4 scissor={0, 0, window_width(), window_height()};
|
||||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, rect);
|
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, NULL, rect);
|
||||||
if (last_skin->getscissorrect) last_skin->getscissorrect(last_skin->userdata, skin, rect, &scissor);
|
scissor = gui_getscissorrect(skin, NULL, rect);
|
||||||
|
|
||||||
if (!array_count(scissor_rects))
|
if (!array_count(scissor_rects))
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
@ -164,7 +170,7 @@ bool gui_button_id(int id, vec4 r, const char *skin) {
|
||||||
|
|
||||||
skin=skin?skin:"button";
|
skin=skin?skin:"button";
|
||||||
char *btn = va("%s%s", skin, entry->held?"_press":entry->hover?"_hover":"");
|
char *btn = va("%s%s", skin, entry->held?"_press":entry->hover?"_hover":"");
|
||||||
if (gui_ismouseinrect(btn, r)) {
|
if (gui_ismouseinrect(btn, skin, r)) {
|
||||||
if (input_up(MOUSE_L) && entry->held) {
|
if (input_up(MOUSE_L) && entry->held) {
|
||||||
was_clicked=1;
|
was_clicked=1;
|
||||||
}
|
}
|
||||||
|
@ -174,24 +180,27 @@ bool gui_button_id(int id, vec4 r, const char *skin) {
|
||||||
entry->hover = true;
|
entry->hover = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (input_up(MOUSE_L) && entry->held) {
|
|
||||||
entry->held = false;
|
|
||||||
any_widget_used = false;
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
entry->hover = false;
|
entry->hover = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, btn, r);
|
if (input_up(MOUSE_L) && entry->held) {
|
||||||
|
entry->held = false;
|
||||||
|
any_widget_used = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, btn, skin, r);
|
||||||
|
|
||||||
return was_clicked;
|
return was_clicked;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin) {
|
bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin) {
|
||||||
|
gui_state_t *entry = gui_getstate(id);
|
||||||
bool state = gui_button_id(id, rect, skin);
|
bool state = gui_button_id(id, rect, skin);
|
||||||
vec2 buttonsize={0};
|
vec2 buttonsize={0};
|
||||||
skin=skin?skin:"button";
|
skin=skin?skin:"button";
|
||||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &buttonsize);
|
char *btn = va("%s%s", skin, entry->held?"_press":entry->hover?"_hover":"");
|
||||||
|
buttonsize = gui_getskinsize(btn, skin);
|
||||||
|
|
||||||
vec2 textsize = font_rect(text);
|
vec2 textsize = font_rect(text);
|
||||||
vec2 pos;
|
vec2 pos;
|
||||||
|
@ -224,7 +233,8 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl
|
||||||
|
|
||||||
skin = skin?skin:"slider";
|
skin = skin?skin:"slider";
|
||||||
char *cursorskin = va("%s_cursor%s", skin, entry->held?"_press":entry->hover?"_hover":"");
|
char *cursorskin = va("%s_cursor%s", skin, entry->held?"_press":entry->hover?"_hover":"");
|
||||||
if (gui_ismouseinrect(skin, rect) && !any_widget_used) {
|
char *fbcursor = va("%s_cursor", skin);
|
||||||
|
if (gui_ismouseinrect(skin, NULL, rect) && !any_widget_used) {
|
||||||
any_widget_used = entry->held = input_held(MOUSE_L);
|
any_widget_used = entry->held = input_held(MOUSE_L);
|
||||||
entry->hover = true;
|
entry->hover = true;
|
||||||
}
|
}
|
||||||
|
@ -237,13 +247,12 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl
|
||||||
}
|
}
|
||||||
|
|
||||||
float old_value = *value;
|
float old_value = *value;
|
||||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, rect);
|
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, NULL, rect);
|
||||||
|
|
||||||
vec2 slidersize={0}, cursorsize={0};
|
vec2 slidersize={0}, cursorsize={0};
|
||||||
vec4 usablerect=rect;
|
vec4 usablerect = gui_getscissorrect(skin, NULL, rect);
|
||||||
if (last_skin->getscissorrect) last_skin->getscissorrect(last_skin->userdata, skin, rect, &usablerect);
|
slidersize = gui_getskinsize(skin, NULL);
|
||||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &slidersize);
|
cursorsize = gui_getskinsize(cursorskin, fbcursor);
|
||||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, cursorskin, &cursorsize);
|
|
||||||
if (entry->held) {
|
if (entry->held) {
|
||||||
*value = posx2slider(usablerect, min, max, input(MOUSE_X), step);
|
*value = posx2slider(usablerect, min, max, input(MOUSE_X), step);
|
||||||
}
|
}
|
||||||
|
@ -254,7 +263,7 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl
|
||||||
cursorrect.y += cursorpos.y;
|
cursorrect.y += cursorpos.y;
|
||||||
cursorrect.z = cursorsize.x;
|
cursorrect.z = cursorsize.x;
|
||||||
cursorrect.w = cursorsize.y;
|
cursorrect.w = cursorsize.y;
|
||||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, cursorskin, cursorrect);
|
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, cursorskin, fbcursor, cursorrect);
|
||||||
|
|
||||||
return entry->held && (old_value!=*value);
|
return entry->held && (old_value!=*value);
|
||||||
}
|
}
|
||||||
|
@ -263,7 +272,7 @@ bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin,
|
||||||
bool state = gui_slider_id(id, rect, skin, min, max, step, value);
|
bool state = gui_slider_id(id, rect, skin, min, max, step, value);
|
||||||
vec2 slidersize={0};
|
vec2 slidersize={0};
|
||||||
skin=skin?skin:"slider";
|
skin=skin?skin:"slider";
|
||||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &slidersize);
|
slidersize = gui_getskinsize(skin, NULL);
|
||||||
|
|
||||||
vec2 textsize = font_rect(text);
|
vec2 textsize = font_rect(text);
|
||||||
vec2 pos;
|
vec2 pos;
|
||||||
|
@ -276,7 +285,7 @@ bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin,
|
||||||
|
|
||||||
void gui_rect_id(int id, vec4 r, const char *skin) {
|
void gui_rect_id(int id, vec4 r, const char *skin) {
|
||||||
(void)id;
|
(void)id;
|
||||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, r);
|
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, NULL, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gui_label_id(int id, const char *text, vec4 rect) {
|
void gui_label_id(int id, const char *text, vec4 rect) {
|
||||||
|
@ -300,7 +309,7 @@ atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) {
|
||||||
for (int i = 0; i < array_count(a->slices); i++)
|
for (int i = 0; i < array_count(a->slices); i++)
|
||||||
if (!strcmp(quark_string(&a->db, a->slices[i].name), name))
|
if (!strcmp(quark_string(&a->db, a->slices[i].name), name))
|
||||||
return &a->slice_frames[a->slices[i].frames[0]];
|
return &a->slice_frames[a->slices[i].frames[0]];
|
||||||
PRINTF("slice name: '%s' is missing in atlas!\n", name);
|
// PRINTF("slice name: '%s' is missing in atlas!\n", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,9 +320,10 @@ void skinned_draw_missing_rect(vec4 r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool skinned_ismouseinrect(void *userdata, const char *skin, vec4 r) {
|
bool skinned_ismouseinrect(void *userdata, const char *skin, const char *fallback, vec4 r) {
|
||||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||||
|
if (!f && fallback) f = skinned_getsliceframe(&a->atlas, fallback);
|
||||||
if (!f) return false;
|
if (!f) return false;
|
||||||
|
|
||||||
vec4 outer = f->bounds;
|
vec4 outer = f->bounds;
|
||||||
|
@ -396,18 +406,20 @@ void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_draw_rect(void* userdata, const char *skin, vec4 r) {
|
void skinned_draw_rect(void* userdata, const char *skin, const char *fallback, vec4 r) {
|
||||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||||
|
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||||
|
if (!f && fallback) f = skinned_getsliceframe(&a->atlas, fallback);
|
||||||
if (!f) skinned_draw_missing_rect(r);
|
if (!f) skinned_draw_missing_rect(r);
|
||||||
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void skinned_getskinsize(void *userdata, const char *skin, vec2 *size) {
|
void skinned_getskinsize(void *userdata, const char *skin, const char *fallback, vec2 *size) {
|
||||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||||
|
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||||
|
if (!f && fallback) f = skinned_getsliceframe(&a->atlas, fallback);
|
||||||
if (f) {
|
if (f) {
|
||||||
size->x = (f->bounds.z-f->bounds.x)*a->scale;
|
size->x = (f->bounds.z-f->bounds.x)*a->scale;
|
||||||
size->y = (f->bounds.w-f->bounds.y)*a->scale;
|
size->y = (f->bounds.w-f->bounds.y)*a->scale;
|
||||||
|
@ -415,9 +427,10 @@ void skinned_getskinsize(void *userdata, const char *skin, vec2 *size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_getscissorrect(void* userdata, const char *skin, vec4 rect, vec4 *dims) {
|
void skinned_getscissorrect(void* userdata, const char *skin, const char *fallback, vec4 rect, vec4 *dims) {
|
||||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||||
|
if (!f && fallback) f = skinned_getsliceframe(&a->atlas, fallback);
|
||||||
if (!f) return;
|
if (!f) return;
|
||||||
|
|
||||||
*dims = rect;
|
*dims = rect;
|
||||||
|
|
|
@ -2,18 +2,19 @@
|
||||||
// game ui
|
// game ui
|
||||||
|
|
||||||
typedef struct guiskin_t {
|
typedef struct guiskin_t {
|
||||||
void (*drawrect)(void* userdata, const char *skin, vec4 rect);
|
void (*drawrect)(void* userdata, const char *skin, const char *fallback, vec4 rect);
|
||||||
void (*getskinsize)(void* userdata, const char *skin, vec2 *size);
|
void (*getskinsize)(void* userdata, const char *skin, const char *fallback, vec2 *size);
|
||||||
void (*getscissorrect)(void* userdata, const char *skin, vec4 rect, vec4 *dims);
|
void (*getscissorrect)(void* userdata, const char *skin, const char *fallback, vec4 rect, vec4 *dims);
|
||||||
bool (*ismouseinrect)(void* userdata, const char *skin, vec4 rect);
|
bool (*ismouseinrect)(void* userdata, const char *skin, const char *fallback, vec4 rect);
|
||||||
void (*free)(void* userdata);
|
void (*free)(void* userdata);
|
||||||
void *userdata;
|
void *userdata;
|
||||||
} guiskin_t;
|
} guiskin_t;
|
||||||
|
|
||||||
API void gui_pushskin(guiskin_t skin);
|
API void gui_pushskin(guiskin_t skin);
|
||||||
API void* gui_userdata();
|
API void* gui_userdata();
|
||||||
API vec2 gui_getskinsize(const char *skin);
|
API vec2 gui_getskinsize(const char *skin, const char *fallback);
|
||||||
API bool gui_ismouseinrect(const char *skin, vec4 rect);
|
API bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
|
API vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
// --
|
// --
|
||||||
API void gui_panel_id(int id, vec4 rect, const char *skin);
|
API void gui_panel_id(int id, vec4 rect, const char *skin);
|
||||||
API void gui_rect_id(int id, vec4 rect, const char *skin);
|
API void gui_rect_id(int id, vec4 rect, const char *skin);
|
||||||
|
|
|
@ -577,6 +577,13 @@ typedef struct anims_t {
|
||||||
|
|
||||||
API anims_t animations(const char *pathfile, int flags);
|
API anims_t animations(const char *pathfile, int flags);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// lightmapping utils
|
||||||
|
|
||||||
|
typedef struct lightmap_t {
|
||||||
|
struct lm_context *ctx; // private
|
||||||
|
} lightmap_t;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// skyboxes
|
// skyboxes
|
||||||
|
|
||||||
|
|
1765
engine/v4k
1765
engine/v4k
File diff suppressed because it is too large
Load Diff
67
engine/v4k.c
67
engine/v4k.c
|
@ -11128,17 +11128,23 @@ void *gui_userdata() {
|
||||||
return last_skin->userdata;
|
return last_skin->userdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 gui_getskinsize(const char *skin) {
|
vec2 gui_getskinsize(const char *skin, const char *fallback) {
|
||||||
vec2 size={0};
|
vec2 size={0};
|
||||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &size);
|
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, fallback, &size);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gui_ismouseinrect(const char *skin, vec4 rect) {
|
bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect) {
|
||||||
if (last_skin->ismouseinrect) return last_skin->ismouseinrect(last_skin->userdata, skin, rect);
|
if (last_skin->ismouseinrect) return last_skin->ismouseinrect(last_skin->userdata, skin, fallback, rect);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect) {
|
||||||
|
vec4 scissor = rect;
|
||||||
|
if (last_skin->getscissorrect) last_skin->getscissorrect(last_skin->userdata, skin, fallback, rect, &scissor);
|
||||||
|
return scissor;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
gui_state_t *gui_getstate(int id) {
|
gui_state_t *gui_getstate(int id) {
|
||||||
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
if (!ctl_states) map_init(ctl_states, less_int, hash_int);
|
||||||
|
@ -11148,8 +11154,8 @@ gui_state_t *gui_getstate(int id) {
|
||||||
void gui_panel_id(int id, vec4 rect, const char *skin) {
|
void gui_panel_id(int id, vec4 rect, const char *skin) {
|
||||||
(void)id;
|
(void)id;
|
||||||
vec4 scissor={0, 0, window_width(), window_height()};
|
vec4 scissor={0, 0, window_width(), window_height()};
|
||||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, rect);
|
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, NULL, rect);
|
||||||
if (last_skin->getscissorrect) last_skin->getscissorrect(last_skin->userdata, skin, rect, &scissor);
|
scissor = gui_getscissorrect(skin, NULL, rect);
|
||||||
|
|
||||||
if (!array_count(scissor_rects))
|
if (!array_count(scissor_rects))
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
@ -11174,7 +11180,7 @@ bool gui_button_id(int id, vec4 r, const char *skin) {
|
||||||
|
|
||||||
skin=skin?skin:"button";
|
skin=skin?skin:"button";
|
||||||
char *btn = va("%s%s", skin, entry->held?"_press":entry->hover?"_hover":"");
|
char *btn = va("%s%s", skin, entry->held?"_press":entry->hover?"_hover":"");
|
||||||
if (gui_ismouseinrect(btn, r)) {
|
if (gui_ismouseinrect(btn, skin, r)) {
|
||||||
if (input_up(MOUSE_L) && entry->held) {
|
if (input_up(MOUSE_L) && entry->held) {
|
||||||
was_clicked=1;
|
was_clicked=1;
|
||||||
}
|
}
|
||||||
|
@ -11184,24 +11190,27 @@ bool gui_button_id(int id, vec4 r, const char *skin) {
|
||||||
entry->hover = true;
|
entry->hover = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (input_up(MOUSE_L) && entry->held) {
|
|
||||||
entry->held = false;
|
|
||||||
any_widget_used = false;
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
entry->hover = false;
|
entry->hover = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, btn, r);
|
if (input_up(MOUSE_L) && entry->held) {
|
||||||
|
entry->held = false;
|
||||||
|
any_widget_used = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, btn, skin, r);
|
||||||
|
|
||||||
return was_clicked;
|
return was_clicked;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin) {
|
bool gui_button_label_id(int id, const char *text, vec4 rect, const char *skin) {
|
||||||
|
gui_state_t *entry = gui_getstate(id);
|
||||||
bool state = gui_button_id(id, rect, skin);
|
bool state = gui_button_id(id, rect, skin);
|
||||||
vec2 buttonsize={0};
|
vec2 buttonsize={0};
|
||||||
skin=skin?skin:"button";
|
skin=skin?skin:"button";
|
||||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &buttonsize);
|
char *btn = va("%s%s", skin, entry->held?"_press":entry->hover?"_hover":"");
|
||||||
|
buttonsize = gui_getskinsize(btn, skin);
|
||||||
|
|
||||||
vec2 textsize = font_rect(text);
|
vec2 textsize = font_rect(text);
|
||||||
vec2 pos;
|
vec2 pos;
|
||||||
|
@ -11234,7 +11243,8 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl
|
||||||
|
|
||||||
skin = skin?skin:"slider";
|
skin = skin?skin:"slider";
|
||||||
char *cursorskin = va("%s_cursor%s", skin, entry->held?"_press":entry->hover?"_hover":"");
|
char *cursorskin = va("%s_cursor%s", skin, entry->held?"_press":entry->hover?"_hover":"");
|
||||||
if (gui_ismouseinrect(skin, rect) && !any_widget_used) {
|
char *fbcursor = va("%s_cursor", skin);
|
||||||
|
if (gui_ismouseinrect(skin, NULL, rect) && !any_widget_used) {
|
||||||
any_widget_used = entry->held = input_held(MOUSE_L);
|
any_widget_used = entry->held = input_held(MOUSE_L);
|
||||||
entry->hover = true;
|
entry->hover = true;
|
||||||
}
|
}
|
||||||
|
@ -11247,13 +11257,12 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl
|
||||||
}
|
}
|
||||||
|
|
||||||
float old_value = *value;
|
float old_value = *value;
|
||||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, rect);
|
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, NULL, rect);
|
||||||
|
|
||||||
vec2 slidersize={0}, cursorsize={0};
|
vec2 slidersize={0}, cursorsize={0};
|
||||||
vec4 usablerect=rect;
|
vec4 usablerect = gui_getscissorrect(skin, NULL, rect);
|
||||||
if (last_skin->getscissorrect) last_skin->getscissorrect(last_skin->userdata, skin, rect, &usablerect);
|
slidersize = gui_getskinsize(skin, NULL);
|
||||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &slidersize);
|
cursorsize = gui_getskinsize(cursorskin, fbcursor);
|
||||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, cursorskin, &cursorsize);
|
|
||||||
if (entry->held) {
|
if (entry->held) {
|
||||||
*value = posx2slider(usablerect, min, max, input(MOUSE_X), step);
|
*value = posx2slider(usablerect, min, max, input(MOUSE_X), step);
|
||||||
}
|
}
|
||||||
|
@ -11264,7 +11273,7 @@ bool gui_slider_id(int id, vec4 rect, const char *skin, float min, float max, fl
|
||||||
cursorrect.y += cursorpos.y;
|
cursorrect.y += cursorpos.y;
|
||||||
cursorrect.z = cursorsize.x;
|
cursorrect.z = cursorsize.x;
|
||||||
cursorrect.w = cursorsize.y;
|
cursorrect.w = cursorsize.y;
|
||||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, cursorskin, cursorrect);
|
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, cursorskin, fbcursor, cursorrect);
|
||||||
|
|
||||||
return entry->held && (old_value!=*value);
|
return entry->held && (old_value!=*value);
|
||||||
}
|
}
|
||||||
|
@ -11273,7 +11282,7 @@ bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin,
|
||||||
bool state = gui_slider_id(id, rect, skin, min, max, step, value);
|
bool state = gui_slider_id(id, rect, skin, min, max, step, value);
|
||||||
vec2 slidersize={0};
|
vec2 slidersize={0};
|
||||||
skin=skin?skin:"slider";
|
skin=skin?skin:"slider";
|
||||||
if (last_skin->getskinsize) last_skin->getskinsize(last_skin->userdata, skin, &slidersize);
|
slidersize = gui_getskinsize(skin, NULL);
|
||||||
|
|
||||||
vec2 textsize = font_rect(text);
|
vec2 textsize = font_rect(text);
|
||||||
vec2 pos;
|
vec2 pos;
|
||||||
|
@ -11286,7 +11295,7 @@ bool gui_slider_label_id(int id, const char *text, vec4 rect, const char *skin,
|
||||||
|
|
||||||
void gui_rect_id(int id, vec4 r, const char *skin) {
|
void gui_rect_id(int id, vec4 r, const char *skin) {
|
||||||
(void)id;
|
(void)id;
|
||||||
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, r);
|
if (last_skin->drawrect) last_skin->drawrect(last_skin->userdata, skin, NULL, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void gui_label_id(int id, const char *text, vec4 rect) {
|
void gui_label_id(int id, const char *text, vec4 rect) {
|
||||||
|
@ -11310,7 +11319,7 @@ atlas_slice_frame_t *skinned_getsliceframe(atlas_t *a, const char *name) {
|
||||||
for (int i = 0; i < array_count(a->slices); i++)
|
for (int i = 0; i < array_count(a->slices); i++)
|
||||||
if (!strcmp(quark_string(&a->db, a->slices[i].name), name))
|
if (!strcmp(quark_string(&a->db, a->slices[i].name), name))
|
||||||
return &a->slice_frames[a->slices[i].frames[0]];
|
return &a->slice_frames[a->slices[i].frames[0]];
|
||||||
PRINTF("slice name: '%s' is missing in atlas!\n", name);
|
// PRINTF("slice name: '%s' is missing in atlas!\n", name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11321,9 +11330,10 @@ void skinned_draw_missing_rect(vec4 r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool skinned_ismouseinrect(void *userdata, const char *skin, vec4 r) {
|
bool skinned_ismouseinrect(void *userdata, const char *skin, const char *fallback, vec4 r) {
|
||||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||||
|
if (!f && fallback) f = skinned_getsliceframe(&a->atlas, fallback);
|
||||||
if (!f) return false;
|
if (!f) return false;
|
||||||
|
|
||||||
vec4 outer = f->bounds;
|
vec4 outer = f->bounds;
|
||||||
|
@ -11406,18 +11416,20 @@ void skinned_draw_sprite(float scale, atlas_t *a, atlas_slice_frame_t *f, vec4 r
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_draw_rect(void* userdata, const char *skin, vec4 r) {
|
void skinned_draw_rect(void* userdata, const char *skin, const char *fallback, vec4 r) {
|
||||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||||
|
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||||
|
if (!f && fallback) f = skinned_getsliceframe(&a->atlas, fallback);
|
||||||
if (!f) skinned_draw_missing_rect(r);
|
if (!f) skinned_draw_missing_rect(r);
|
||||||
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
else skinned_draw_sprite(a->scale, &a->atlas, f, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void skinned_getskinsize(void *userdata, const char *skin, vec2 *size) {
|
void skinned_getskinsize(void *userdata, const char *skin, const char *fallback, vec2 *size) {
|
||||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||||
|
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||||
|
if (!f && fallback) f = skinned_getsliceframe(&a->atlas, fallback);
|
||||||
if (f) {
|
if (f) {
|
||||||
size->x = (f->bounds.z-f->bounds.x)*a->scale;
|
size->x = (f->bounds.z-f->bounds.x)*a->scale;
|
||||||
size->y = (f->bounds.w-f->bounds.y)*a->scale;
|
size->y = (f->bounds.w-f->bounds.y)*a->scale;
|
||||||
|
@ -11425,9 +11437,10 @@ void skinned_getskinsize(void *userdata, const char *skin, vec2 *size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void skinned_getscissorrect(void* userdata, const char *skin, vec4 rect, vec4 *dims) {
|
void skinned_getscissorrect(void* userdata, const char *skin, const char *fallback, vec4 rect, vec4 *dims) {
|
||||||
skinned_t *a = C_CAST(skinned_t*, userdata);
|
skinned_t *a = C_CAST(skinned_t*, userdata);
|
||||||
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
atlas_slice_frame_t *f = skinned_getsliceframe(&a->atlas, skin);
|
||||||
|
if (!f && fallback) f = skinned_getsliceframe(&a->atlas, fallback);
|
||||||
if (!f) return;
|
if (!f) return;
|
||||||
|
|
||||||
*dims = rect;
|
*dims = rect;
|
||||||
|
|
20
engine/v4k.h
20
engine/v4k.h
|
@ -3638,6 +3638,13 @@ typedef struct anims_t {
|
||||||
|
|
||||||
API anims_t animations(const char *pathfile, int flags);
|
API anims_t animations(const char *pathfile, int flags);
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// lightmapping utils
|
||||||
|
|
||||||
|
typedef struct lightmap_t {
|
||||||
|
struct lm_context *ctx; // private
|
||||||
|
} lightmap_t;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// skyboxes
|
// skyboxes
|
||||||
|
|
||||||
|
@ -4184,18 +4191,19 @@ API void sprite_setanim(sprite_t *s, unsigned name);
|
||||||
// game ui
|
// game ui
|
||||||
|
|
||||||
typedef struct guiskin_t {
|
typedef struct guiskin_t {
|
||||||
void (*drawrect)(void* userdata, const char *skin, vec4 rect);
|
void (*drawrect)(void* userdata, const char *skin, const char *fallback, vec4 rect);
|
||||||
void (*getskinsize)(void* userdata, const char *skin, vec2 *size);
|
void (*getskinsize)(void* userdata, const char *skin, const char *fallback, vec2 *size);
|
||||||
void (*getscissorrect)(void* userdata, const char *skin, vec4 rect, vec4 *dims);
|
void (*getscissorrect)(void* userdata, const char *skin, const char *fallback, vec4 rect, vec4 *dims);
|
||||||
bool (*ismouseinrect)(void* userdata, const char *skin, vec4 rect);
|
bool (*ismouseinrect)(void* userdata, const char *skin, const char *fallback, vec4 rect);
|
||||||
void (*free)(void* userdata);
|
void (*free)(void* userdata);
|
||||||
void *userdata;
|
void *userdata;
|
||||||
} guiskin_t;
|
} guiskin_t;
|
||||||
|
|
||||||
API void gui_pushskin(guiskin_t skin);
|
API void gui_pushskin(guiskin_t skin);
|
||||||
API void* gui_userdata();
|
API void* gui_userdata();
|
||||||
API vec2 gui_getskinsize(const char *skin);
|
API vec2 gui_getskinsize(const char *skin, const char *fallback);
|
||||||
API bool gui_ismouseinrect(const char *skin, vec4 rect);
|
API bool gui_ismouseinrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
|
API vec4 gui_getscissorrect(const char *skin, const char *fallback, vec4 rect);
|
||||||
// --
|
// --
|
||||||
API void gui_panel_id(int id, vec4 rect, const char *skin);
|
API void gui_panel_id(int id, vec4 rect, const char *skin);
|
||||||
API void gui_rect_id(int id, vec4 rect, const char *skin);
|
API void gui_rect_id(int id, vec4 rect, const char *skin);
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
#include "v4k.c"
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
if (argc != 2) {
|
||||||
|
fprintf(stderr, "usage: %s [file]\n", argv[0]);
|
||||||
|
fprintf(stderr, "file: %s\n", "source file to process");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *buf = file_read(argv[1]);
|
||||||
|
if (!buf) {
|
||||||
|
fprintf(stderr, "error: %s\n", "file does not exist!");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
file_delete(argv[1]);
|
||||||
|
|
||||||
|
// determine swap mode
|
||||||
|
char mode = strstri(buf, "//@#line 1 \"") == NULL;
|
||||||
|
char **lines = strsplit(buf, "\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < array_count(lines); i++) {
|
||||||
|
char *line = STRDUP(lines[i]);
|
||||||
|
if (!mode) {
|
||||||
|
strrepl(&line, "//@#line 1 \"", "#line 1 \"");
|
||||||
|
} else {
|
||||||
|
strrepl(&line, "#line 1 \"", "//@#line 1 \"");
|
||||||
|
}
|
||||||
|
|
||||||
|
// printf("%s\n", line);
|
||||||
|
file_append(argv[1], line, strlen(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Binary file not shown.
|
@ -3,8 +3,8 @@
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"path": ".",
|
"path": ".",
|
||||||
"file_exclude_patterns": ["*.exe.manifest", "*.zip", "*.ilk", "*.exp", "_mirror/", "engine/v4k", "engine/joint/", "engine/split/"],
|
"file_exclude_patterns": ["*.exe.manifest", "*.zip", "*.ilk", "*.exp", "_mirror/", "engine/v4k", "engine/joint/", "engine/split/v4k_*"],
|
||||||
"index_exclude_patterns": ["engine/joint/v4k.h", "engine/split/**", "_mirror/**"]
|
"index_exclude_patterns": ["engine/joint/v4k.h", "engine/split/v4k_**", "_mirror/**"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"settings": {
|
"settings": {
|
||||||
|
|
Loading…
Reference in New Issue