From 916ea3ce1f1d0951af5e4be0617fd40327f05e2b Mon Sep 17 00:00:00 2001 From: Andy C Date: Mon, 16 Sep 2019 22:46:05 +0300 Subject: [PATCH] Hotfix v1.0.2 * Optimize point light accumulation, somewhat * Update dependencies --- lib/cglm/.gitignore | 1 + lib/cglm/README.md | 4 + lib/cglm/cglm.podspec | 2 +- lib/cglm/docs/source/troubleshooting.rst | 7 + lib/cglm/include/cglm/mat4.h | 3 + lib/cglm/test/include/common.h | 38 ++- lib/cglm/test/runner.c | 51 ++-- lib/cglm/test/src/test_affine.c | 22 +- lib/cglm/test/src/test_bezier.c | 4 +- lib/cglm/test/src/test_cam.c | 12 +- lib/cglm/test/src/test_clamp.c | 4 +- lib/cglm/test/src/test_common.c | 44 +++ lib/cglm/test/src/test_common.h | 9 + lib/cglm/test/src/test_euler.c | 8 +- lib/cglm/test/src/test_mat3.c | 4 +- lib/cglm/test/src/test_mat4.c | 319 ++++++++++++++++++---- lib/cglm/test/src/test_quat.c | 32 +-- lib/cglm/test/src/test_vec3.c | 20 +- lib/cglm/test/src/test_vec4.c | 55 ++-- lib/cglm/test/tests.h | 57 +++- lib/cglm/win/.gitignore | 5 + lib/cglm/win/cglm-test.vcxproj | 189 +++++++++++++ lib/cglm/win/cglm-test.vcxproj.filters | 65 +++++ lib/cglm/win/cglm.sln | 17 +- lib/cglm/win/cglm.vcxproj.filters | 4 - lib/glfw/docs/Doxyfile.in | 2 +- lib/glfw/docs/input.dox | 2 +- lib/glfw/examples/particles.c | 6 +- lib/glfw/examples/splitview.c | 2 +- lib/glfw/include/GLFW/glfw3.h | 14 +- lib/glfw/src/win32_init.c | 4 +- lib/glfw/src/wl_window.c | 2 +- lib/glfw/tests/events.c | 2 +- lib/imgui/docs/CHANGELOG.txt | 6 + lib/imgui/docs/TODO.txt | 7 +- lib/imgui/examples/imgui_impl_opengl3.cpp | 24 +- lib/imgui/imgui.cpp | 73 +++-- lib/imgui/imgui_demo.cpp | 2 +- lib/imgui/imgui_internal.h | 5 +- lib/imgui/imgui_widgets.cpp | 9 +- run/shaders/gbuf_light_main.frag | 4 +- run/shaders/gbuf_light_point.frag | 15 +- src/assets.h | 7 +- src/data/model.c | 1 + src/data/model.h | 1 + src/gui/gui.cc | 4 +- src/main.c | 14 +- src/main.h | 1 + src/render/program.c | 4 + src/render/render.c | 9 + src/render/render.h | 1 + 51 files changed, 960 insertions(+), 237 deletions(-) create mode 100644 lib/cglm/win/cglm-test.vcxproj create mode 100644 lib/cglm/win/cglm-test.vcxproj.filters diff --git a/lib/cglm/.gitignore b/lib/cglm/.gitignore index 90ccabb..8f9fd0c 100644 --- a/lib/cglm/.gitignore +++ b/lib/cglm/.gitignore @@ -71,3 +71,4 @@ win/Debug cglm-test-ios* /cglm.pc test-driver +Default-568h@2x.png diff --git a/lib/cglm/README.md b/lib/cglm/README.md index 624d18c..fc5ed4b 100644 --- a/lib/cglm/README.md +++ b/lib/cglm/README.md @@ -166,6 +166,10 @@ if `msbuild` won't work (because of multi version VS) then try to build with `de $ devenv cglm.sln /Build Release ``` +#### Running Tests on Windows + +You can see test project in same visual studio solution file. It is enough to run that project to run tests. + ### Building Docs First you need install Sphinx: http://www.sphinx-doc.org/en/master/usage/installation.html then: diff --git a/lib/cglm/cglm.podspec b/lib/cglm/cglm.podspec index 4022572..9d4b836 100644 --- a/lib/cglm/cglm.podspec +++ b/lib/cglm/cglm.podspec @@ -2,7 +2,7 @@ Pod::Spec.new do |s| # Description s.name = "cglm" - s.version = "0.5.1" + s.version = "0.6.1" s.summary = "📽 Optimized OpenGL/Graphics Math (glm) for C" s.description = <<-DESC cglm is math library for graphics programming for C. It is similar to original glm but it is written for C instead of C++ (you can use here too). See the documentation or README for all features. diff --git a/lib/cglm/docs/source/troubleshooting.rst b/lib/cglm/docs/source/troubleshooting.rst index 9084cab..6510cd5 100644 --- a/lib/cglm/docs/source/troubleshooting.rst +++ b/lib/cglm/docs/source/troubleshooting.rst @@ -57,6 +57,13 @@ For instance you may called **glm_vec4_** functions for **vec3** data type. It will try to write 32 byte but since **vec3** is 24 byte it should throw memory access error or exit the app without saying anything. +**UPDATE - IMPORTANT:** + + | On MSVC or some other compilers, if alignment is enabled (default) then double check alignment requirements if you got a crash. + + | If you send GLM_VEC4_ONE or similar macros directly to a function, it may be crashed. + | Because compiler may not apply alignment as defined on **typedef** to that macro while passing it (on stack) to a function. + Wrong Results: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/cglm/include/cglm/mat4.h b/lib/cglm/include/cglm/mat4.h index e6b916b..7a72f97 100644 --- a/lib/cglm/include/cglm/mat4.h +++ b/lib/cglm/include/cglm/mat4.h @@ -446,6 +446,9 @@ glm_mat4_quat(mat4 m, versor dest) { /*! * @brief multiply vector with mat4 * + * actually the result is vec4, after multiplication the last component + * is trimmed. if you need it don't use this func. + * * @param[in] m mat4(affine transform) * @param[in] v vec3 * @param[in] last 4th item to make it vec4 diff --git a/lib/cglm/test/include/common.h b/lib/cglm/test/include/common.h index e58edc2..0b4a6d8 100644 --- a/lib/cglm/test/include/common.h +++ b/lib/cglm/test/include/common.h @@ -51,6 +51,13 @@ typedef struct test_entry_t { #define TEST_ENTRY(FUN) { #FUN, test_ ## FUN, 0, 0 }, #define TEST_LIST static test_entry_t tests[] = +#define TEST_OK 1 +#define TEST_SUCCESS return (test_status_t){NULL, TEST_OK}; + +#define TEST_IMPL(FUN) \ + test_status_t test_ ## FUN (void); \ + test_status_t test_ ## FUN() + #define ASSERT_EXT(expr, msg) \ if (!(expr)) { \ fprintf(stderr, \ @@ -70,12 +77,31 @@ typedef struct test_entry_t { #define ASSERT_CHOOSER(...) ASSERT_ARG3(__VA_ARGS__, ASSERT_ARG2, ASSERT_ARG1) #define ASSERT(...) do { ASSERT_CHOOSER(__VA_ARGS__)(__VA_ARGS__) } while(0); +#define ASSERTIFY(expr) do { \ + test_status_t ts; \ + ts = expr; \ + if (ts.status != TEST_OK) { \ + fprintf(stderr, \ + RED " assert fail" RESET \ + " in " BOLDCYAN "%s " RESET \ + "on " BOLDMAGENTA "line %d" RESET \ + " : " BOLDWHITE " ASSERTIFY(%s)\n" RESET, \ + __FILE__, \ + __LINE__, \ + #expr); \ + return (test_status_t){ts.msg, 0}; \ + } \ + } while(0); -#define TEST_OK 1 -#define TEST_SUCCESS return (test_status_t){NULL, TEST_OK}; - -#define TEST_IMPL(FUN) \ - test_status_t test_ ## FUN (void); \ - test_status_t test_ ## FUN() +#if defined(_WIN32) +# define drand48() ((float)(rand() / (RAND_MAX + 1.0))) +# define OK_TEXT "ok:" +# define FAIL_TEXT "fail:" +# define FINAL_TEXT "^_^" +#else +# define OK_TEXT "✔︎" +# define FAIL_TEXT "𐄂" +# define FINAL_TEXT "🎉" +#endif #endif /* common_h */ diff --git a/lib/cglm/test/runner.c b/lib/cglm/test/runner.c index 35fcac3..7d4d858 100644 --- a/lib/cglm/test/runner.c +++ b/lib/cglm/test/runner.c @@ -10,30 +10,47 @@ #include #include +#include int main(int argc, const char * argv[]) { test_entry_t *entry; test_status_t st; - int32_t i, count, passed, failed; - double start, end, elapsed; + int32_t i, count, passed, failed, maxlen; + double start, end, elapsed, total; - passed = failed = 0; + passed = failed = maxlen = 0; + total = 0.0; count = sizeof(tests) / sizeof(tests[0]); - + fprintf(stderr, CYAN "\nWelcome to cglm tests\n\n" RESET); - + + for (i = 0; i < count; i++) { + int32_t len; + + entry = tests + i; + len = (int32_t)strlen(entry->name); + + maxlen = GLM_MAX(maxlen, len); + } + + maxlen += 5; + + fprintf(stderr, + BOLDWHITE " %-*s %-*s\n", + maxlen, "Test Name", maxlen, "Elapsed Time"); + for (i = 0; i < count; i++) { entry = tests + i; start = clock(); st = entry->entry(); end = clock(); elapsed = (end - start) / CLOCKS_PER_SEC; + total += elapsed; if (!st.status) { fprintf(stderr, - BOLDRED " 𐄂" BOLDWHITE " %s " RESET, - entry->name); + BOLDRED " " FAIL_TEXT BOLDWHITE " %s " RESET, entry->name); if (st.msg) { fprintf(stderr, YELLOW "- %s" RESET, @@ -44,29 +61,31 @@ main(int argc, const char * argv[]) { failed++; } else { - fprintf(stderr, GREEN " ✔︎" RESET " %s - " , entry->name); - + fprintf(stderr, GREEN " " OK_TEXT RESET " %-*s ", maxlen, entry->name); + if (elapsed > 0.01) - fprintf(stderr, YELLOW "%.2f", elapsed); + fprintf(stderr, YELLOW "%.2fs", elapsed); else fprintf(stderr, "0"); - fprintf(stderr, "s\n" RESET); + fprintf(stderr, "\n" RESET); passed++; } } - + if (failed == 0) { - fprintf(stderr, BOLDGREEN "\n All tests are passed 🎉\n" RESET); + fprintf(stderr, + BOLDGREEN "\n All tests are passed " FINAL_TEXT "\n" RESET); } fprintf(stderr, - CYAN "\ncglm test results:\n" RESET - "------------------\n" - + CYAN "\ncglm test results (%0.2fs):\n" RESET + "--------------------------\n" + MAGENTA "%d" RESET " tests are runned, " GREEN "%d" RESET " %s passed, " RED "%d" RESET " %s failed\n\n" RESET, + total, count, passed, passed > 1 ? "are" : "is", diff --git a/lib/cglm/test/src/test_affine.c b/lib/cglm/test/src/test_affine.c index c78b6b2..4f51aea 100644 --- a/lib/cglm/test/src/test_affine.c +++ b/lib/cglm/test/src/test_affine.c @@ -17,7 +17,7 @@ TEST_IMPL(affine) { glmc_mat4_mul(t1, t2, t3); /* R * T */ glm_translate(t1, (vec3){34, 57, 36}); - ASSERT(test_assert_mat4_eq(t1, t3).status == 1) + ASSERTIFY(test_assert_mat4_eq(t1, t3)) /* test rotate is postmultiplied */ glmc_rotate_make(t1, GLM_PI_4f, GLM_YUP); @@ -26,7 +26,7 @@ TEST_IMPL(affine) { glmc_mat4_mul(t2, t1, t3); /* T * R */ glm_rotate(t2, GLM_PI_4f, GLM_YUP); - ASSERT(test_assert_mat4_eq(t2, t3).status == 1) + ASSERTIFY(test_assert_mat4_eq(t2, t3)) /* test scale is postmultiplied */ glmc_rotate_make(t1, GLM_PI_4f, GLM_YUP); @@ -37,7 +37,7 @@ TEST_IMPL(affine) { glmc_mat4_mul(t3, t4, t5); /* T * R * S */ glm_scale(t3, (vec3){3, 5, 6}); - ASSERT(test_assert_mat4_eq(t3, t5).status == 1) + ASSERTIFY(test_assert_mat4_eq(t3, t5)) /* test translate_x */ glmc_rotate_make(t1, GLM_PI_4f, GLM_YUP); @@ -45,7 +45,7 @@ TEST_IMPL(affine) { glmc_mat4_mul(t1, t2, t3); /* R * T */ glm_translate_x(t1, 34); - ASSERT(test_assert_mat4_eq(t1, t3).status == 1) + ASSERTIFY(test_assert_mat4_eq(t1, t3)) /* test translate_y */ glmc_rotate_make(t1, GLM_PI_4f, GLM_YUP); @@ -53,7 +53,7 @@ TEST_IMPL(affine) { glmc_mat4_mul(t1, t2, t3); /* R * T */ glm_translate_y(t1, 57); - ASSERT(test_assert_mat4_eq(t1, t3).status == 1) + ASSERTIFY(test_assert_mat4_eq(t1, t3)) /* test translate_z */ glmc_rotate_make(t1, GLM_PI_4f, GLM_YUP); @@ -61,7 +61,7 @@ TEST_IMPL(affine) { glmc_mat4_mul(t1, t2, t3); /* R * T */ glm_translate_z(t1, 36); - ASSERT(test_assert_mat4_eq(t1, t3).status == 1) + ASSERTIFY(test_assert_mat4_eq(t1, t3)) /* test rotate_x */ glmc_rotate_make(t1, GLM_PI_4f, (vec3){1, 0, 0}); @@ -70,7 +70,7 @@ TEST_IMPL(affine) { glmc_mat4_mul(t2, t1, t3); /* T * R */ glm_rotate_x(t2, GLM_PI_4f, t2); - ASSERT(test_assert_mat4_eq(t2, t3).status == 1) + ASSERTIFY(test_assert_mat4_eq(t2, t3)) /* test rotate_y */ glmc_rotate_make(t1, GLM_PI_4f, (vec3){0, 1, 0}); @@ -79,7 +79,7 @@ TEST_IMPL(affine) { glmc_mat4_mul(t2, t1, t3); /* T * R */ glm_rotate_y(t2, GLM_PI_4f, t2); - ASSERT(test_assert_mat4_eq(t2, t3).status == 1) + ASSERTIFY(test_assert_mat4_eq(t2, t3)) /* test rotate_z */ glmc_rotate_make(t1, GLM_PI_4f, (vec3){0, 0, 1}); @@ -88,7 +88,7 @@ TEST_IMPL(affine) { glmc_mat4_mul(t2, t1, t3); /* T * R */ glm_rotate_z(t2, GLM_PI_4f, t2); - ASSERT(test_assert_mat4_eq(t2, t3).status == 1) + ASSERTIFY(test_assert_mat4_eq(t2, t3)) /* test rotate */ glmc_rotate_make(t1, GLM_PI_4f, (vec3){0, 0, 1}); @@ -97,7 +97,7 @@ TEST_IMPL(affine) { glmc_mat4_mul(t2, t1, t3); /* T * R */ glmc_rotate(t2, GLM_PI_4f, (vec3){0, 0, 1}); - ASSERT(test_assert_mat4_eq(t3, t2).status == 1) + ASSERTIFY(test_assert_mat4_eq(t3, t2)) /* test scale_uni */ glmc_rotate_make(t1, GLM_PI_4f, GLM_YUP); @@ -108,7 +108,7 @@ TEST_IMPL(affine) { glmc_mat4_mul(t3, t4, t5); /* T * R * S */ glm_scale_uni(t3, 3); - ASSERT(test_assert_mat4_eq(t3, t5).status == 1) + ASSERTIFY(test_assert_mat4_eq(t3, t5)) TEST_SUCCESS } diff --git a/lib/cglm/test/src/test_bezier.c b/lib/cglm/test/src/test_bezier.c index 460c47a..8c22e65 100644 --- a/lib/cglm/test/src/test_bezier.c +++ b/lib/cglm/test/src/test_bezier.c @@ -50,8 +50,8 @@ TEST_IMPL(bezier) { Bs_plain = test_bezier_plain(s, p0, c0, c1, p1); ASSERT(glm_eq(Bs, Bs_plain)); - ASSERT(test_assert_eqf(smc, Bs_plain).status == 1) - ASSERT(test_assert_eqf(Bs, smc).status == 1) + ASSERTIFY(test_assert_eqf(smc, Bs_plain)) + ASSERTIFY(test_assert_eqf(Bs, smc)) /* test cubic hermite */ smc = glm_smc(s, GLM_HERMITE_MAT, (vec4){p0, p1, c0, c1}); diff --git a/lib/cglm/test/src/test_cam.c b/lib/cglm/test/src/test_cam.c index 889e295..f444bdd 100644 --- a/lib/cglm/test/src/test_cam.c +++ b/lib/cglm/test/src/test_cam.c @@ -19,7 +19,7 @@ TEST_IMPL(camera_lookat) { glm_look(eye, dir, up, view2); - ASSERT(test_assert_mat4_eq(view1, view2).status == 1) + ASSERTIFY(test_assert_mat4_eq(view1, view2)) TEST_SUCCESS } @@ -41,15 +41,15 @@ TEST_IMPL(camera_decomp) { glm_persp_sizes(proj, fovy, sizes); - glm_frustum(-sizes[0] * 0.5, - sizes[0] * 0.5, - -sizes[1] * 0.5, - sizes[1] * 0.5, + glm_frustum(-sizes[0] * 0.5f, + sizes[0] * 0.5f, + -sizes[1] * 0.5f, + sizes[1] * 0.5f, nearVal, farVal, proj2); - ASSERT(test_assert_mat4_eq(proj, proj2).status == 1) + ASSERTIFY(test_assert_mat4_eq(proj, proj2)) TEST_SUCCESS } diff --git a/lib/cglm/test/src/test_clamp.c b/lib/cglm/test/src/test_clamp.c index 30e70f4..1d1c0c2 100644 --- a/lib/cglm/test/src/test_clamp.c +++ b/lib/cglm/test/src/test_clamp.c @@ -8,8 +8,8 @@ #include "test_common.h" TEST_IMPL(clamp) { - vec3 v3 = {15.07, 0.4, 17.3}; - vec4 v4 = {5.07, 2.3, 1.3, 1.4}; + vec3 v3 = {15.07f, 0.4f, 17.3f}; + vec4 v4 = {5.07f, 2.3f, 1.3f, 1.4f}; ASSERT(glm_clamp(1.6f, 0.0f, 1.0f) == 1.0f) ASSERT(glm_clamp(-1.6f, 0.0f, 1.0f) == 0.0f) diff --git a/lib/cglm/test/src/test_common.c b/lib/cglm/test/src/test_common.c index 4e966b5..9999e3d 100644 --- a/lib/cglm/test/src/test_common.c +++ b/lib/cglm/test/src/test_common.c @@ -124,6 +124,50 @@ test_assert_mat3_eq(mat3 m1, mat3 m2) { TEST_SUCCESS } +test_status_t +test_assert_mat3_eqt(mat3 m1, mat3 m2) { + int i, j, k; + + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + for (k = 0; k < 3; k++) + ASSERT(fabsf(m1[j][i] - m2[i][j]) <= 0.0000009); + } + } + + TEST_SUCCESS +} + +test_status_t +test_assert_mat4_eq_identity(mat4 m4) { + int i, j; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + if (i == j) { + ASSERT(glm_eq(m4[i][j], 1.0f)) + } else { + ASSERT(glm_eq(m4[i][j], 0.0f)) + } + } + } + + TEST_SUCCESS +} + +test_status_t +test_assert_mat4_eq_zero(mat4 m4) { + int i, j; + + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + ASSERT(glm_eq(m4[i][j], 0.0f)) + } + } + + TEST_SUCCESS +} + test_status_t test_assert_eqf(float a, float b) { ASSERT(fabsf(a - b) <= 0.000009); /* rounding errors */ diff --git a/lib/cglm/test/src/test_common.h b/lib/cglm/test/src/test_common.h index 73d9502..13b9310 100644 --- a/lib/cglm/test/src/test_common.h +++ b/lib/cglm/test/src/test_common.h @@ -25,9 +25,18 @@ test_assert_mat4_eq(mat4 m1, mat4 m2); test_status_t test_assert_mat4_eq2(mat4 m1, mat4 m2, float eps); +test_status_t +test_assert_mat4_eq_identity(mat4 m4); + +test_status_t +test_assert_mat4_eq_zero(mat4 m4); + test_status_t test_assert_mat3_eq(mat3 m1, mat3 m2); +test_status_t +test_assert_mat3_eqt(mat3 m1, mat3 m2); + test_status_t test_assert_vec3_eq(vec3 v1, vec3 v2); diff --git a/lib/cglm/test/src/test_euler.c b/lib/cglm/test/src/test_euler.c index 74618b3..b71e0f0 100644 --- a/lib/cglm/test/src/test_euler.c +++ b/lib/cglm/test/src/test_euler.c @@ -21,11 +21,11 @@ TEST_IMPL(euler) { glmc_euler_angles(rot1, outAngles); /* angles must be equal in that range */ - ASSERT(test_assert_vec3_eq(inAngles, outAngles).status == 1) + ASSERTIFY(test_assert_vec3_eq(inAngles, outAngles)) /* matrices must be equal */ glmc_euler_xyz(outAngles, rot2); - ASSERT(test_assert_mat4_eq(rot1, rot2).status == 1) + ASSERTIFY(test_assert_mat4_eq(rot1, rot2)) /* change range */ inAngles[0] = glm_rad(-145.0f); /* X angle */ @@ -39,7 +39,7 @@ TEST_IMPL(euler) { /* matrices must be equal */ glmc_euler_xyz(outAngles, rot2); - ASSERT(test_assert_mat4_eq(rot1, rot2).status == 1) - + ASSERTIFY(test_assert_mat4_eq(rot1, rot2)) + TEST_SUCCESS } diff --git a/lib/cglm/test/src/test_mat3.c b/lib/cglm/test/src/test_mat3.c index 6f43dd4..4d9dc07 100644 --- a/lib/cglm/test/src/test_mat3.c +++ b/lib/cglm/test/src/test_mat3.c @@ -52,7 +52,7 @@ TEST_IMPL(mat3_mul) { } } - ASSERT(test_assert_mat3_eq(m3, m4).status == 1) + ASSERTIFY(test_assert_mat3_eq(m3, m4)) TEST_SUCCESS } @@ -70,7 +70,7 @@ TEST_IMPL(mat3_inv) { /* test inverse precise */ glmc_mat3_inv(m1, m2); glmc_mat3_inv(m2, m3); - ASSERT(test_assert_mat3_eq(m1, m3).status == 1) + ASSERTIFY(test_assert_mat3_eq(m1, m3)) } TEST_SUCCESS diff --git a/lib/cglm/test/src/test_mat4.c b/lib/cglm/test/src/test_mat4.c index 49ae8ca..2a9568b 100644 --- a/lib/cglm/test/src/test_mat4.c +++ b/lib/cglm/test/src/test_mat4.c @@ -7,61 +7,272 @@ #include "test_common.h" -#define m 4 -#define n 4 +#define A_MATRIX {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}} +#define A_MATRIX3 {{1,2,3},{5,6,7},{9,10,11}} -TEST_IMPL(mat4_identity) { +TEST_IMPL(glm_mat4_ucopy) { + mat4 m1 = A_MATRIX; + mat4 m2 = GLM_MAT4_IDENTITY_INIT; + + glm_mat4_ucopy(m1, m2); + + ASSERTIFY(test_assert_mat4_eq(m1, m2)) + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_copy) { + mat4 m1 = A_MATRIX; + mat4 m2 = GLM_MAT4_IDENTITY_INIT; + + glm_mat4_copy(m1, m2); + + test_assert_mat4_eq(m1, m2); + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_identity) { mat4 m1 = GLM_MAT4_IDENTITY_INIT; mat4 m2 = GLM_MAT4_IDENTITY_INIT; mat4 m3; - int i, j; - - /* test identity matrix multiplication */ - glm_mat4_mul(m1, m2, m3); - for (i = 0; i < m; i++) { - for (j = 0; j < n; j++) { - if (i == j) { - ASSERT(glm_eq(m3[i][j], 1.0f)) - } else { - ASSERT(glm_eq(m3[i][j], 0.0f)) - } + + glm_mat4_identity(m3); + + ASSERTIFY(test_assert_mat4_eq_identity(m1)) + ASSERTIFY(test_assert_mat4_eq_identity(m2)) + ASSERTIFY(test_assert_mat4_eq_identity(m3)) + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_identity_array) { + int i, count; + mat4 matrices[4] = { + A_MATRIX, + A_MATRIX, + A_MATRIX, + A_MATRIX + }; + + count = 4; + + glm_mat4_identity_array(matrices, count); + + for (i = 0; i < count; i++) { + ASSERTIFY(test_assert_mat4_eq_identity(matrices[i])) + } + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_zero) { + mat4 m1 = GLM_MAT4_ZERO_INIT; + mat4 m2 = GLM_MAT4_ZERO_INIT; + mat4 m3; + + glm_mat4_zero(m3); + + ASSERTIFY(test_assert_mat4_eq_zero(m1)) + ASSERTIFY(test_assert_mat4_eq_zero(m2)) + ASSERTIFY(test_assert_mat4_eq_zero(m3)) + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_pick3) { + mat4 m1 = A_MATRIX; + mat3 m2 = GLM_MAT3_ZERO_INIT; + mat3 m3 = A_MATRIX3; + + glm_mat4_pick3(m1, m2); + + ASSERTIFY(test_assert_mat3_eq(m2, m3)) + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_pick3t) { + mat4 m1 = A_MATRIX; + mat3 m2 = GLM_MAT3_ZERO_INIT; + mat3 m3 = A_MATRIX3; + + glm_mat4_pick3t(m1, m2); + + ASSERTIFY(test_assert_mat3_eqt(m2, m3)) + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_ins3) { + mat4 m1 = GLM_MAT4_IDENTITY_INIT; + mat3 m2 = A_MATRIX3; + int i, j; + + glm_mat4_ins3(m2, m1); + + for (i = 0; i < 3; i++) { + for (j = 0; j < 3; j++) { + ASSERT(m1[i][j] == m2[i][j]) } } - + + ASSERT(glm_eq(m1[3][0], 0.0f)) + ASSERT(glm_eq(m1[3][1], 0.0f)) + ASSERT(glm_eq(m1[3][2], 0.0f)) + ASSERT(glm_eq(m1[3][3], 1.0f)) + TEST_SUCCESS } -TEST_IMPL(mat4_mul) { - mat4 m1 = GLM_MAT4_IDENTITY_INIT; - mat4 m2 = GLM_MAT4_IDENTITY_INIT; - mat4 m3; - mat4 m4 = GLM_MAT4_ZERO_INIT; - int i, j, k; - +TEST_IMPL(glm_mat4_mul) { + mat4 m1 = GLM_MAT4_IDENTITY_INIT; + mat4 m2 = GLM_MAT4_IDENTITY_INIT; + mat4 m3; + mat4 m4 = GLM_MAT4_ZERO_INIT; + int i, j, k; + /* test random matrices */ /* random matrices */ test_rand_mat4(m1); test_rand_mat4(m2); - + glm_mat4_mul(m1, m2, m3); - for (i = 0; i < m; i++) { - for (j = 0; j < n; j++) { - for (k = 0; k < m; k++) - /* column-major */ + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + for (k = 0; k < 4; k++) + /* column-major */ m4[i][j] += m1[k][j] * m2[i][k]; } } - - ASSERT(test_assert_mat4_eq(m3, m4).status == TEST_OK) - + + ASSERTIFY(test_assert_mat4_eq(m3, m4)) + /* test pre compiled */ glmc_mat4_mul(m1, m2, m3); - ASSERT(test_assert_mat4_eq(m3, m4).status == TEST_OK) - + ASSERTIFY(test_assert_mat4_eq(m3, m4)) + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_mulN) { + mat4 res1, res2; + mat4 m1 = A_MATRIX; + mat4 m2 = A_MATRIX; + mat4 m3 = A_MATRIX; + + mat4 *matrices[] = { + &m1, &m2, &m3 + }; + + glm_mat4_mulN(matrices, sizeof(matrices) / sizeof(matrices[0]), res1); + + glm_mat4_mul(*matrices[0], *matrices[1], res2); + glm_mat4_mul(res2, *matrices[2], res2); + + ASSERTIFY(test_assert_mat4_eq(res1, res1)) + TEST_SUCCESS } -TEST_IMPL(mat4_all) { +TEST_IMPL(glm_mat4_mulv) { + vec4 res; + mat4 mat = A_MATRIX; + vec4 v = {1.0f, 2.0f, 3.0f, 4.0f}; + int i; + + glm_mat4_mulv(mat, v, res); + + for (i = 0; i < 4; i++) { + ASSERT(glm_eq(res[i], + v[0] * mat[0][i] + + v[1] * mat[1][i] + + v[2] * mat[2][i] + + v[3] * mat[3][i])) + } + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_mulv3) { + vec4 res; + mat4 mat = A_MATRIX; + vec3 v = {1.0f, 2.0f, 3.0f}; + float last; + int i; + + last = 1.0f; + + glm_mat4_mulv3(mat, v, last, res); + + for (i = 0; i < 3; i++) { + ASSERT(glm_eq(res[i], + v[0] * mat[0][i] + + v[1] * mat[1][i] + + v[2] * mat[2][i] + + last * mat[3][i])) + } + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_trace) { + mat4 mat = A_MATRIX; + float trace; + + trace = glm_mat4_trace(mat); + + ASSERT(glm_eq(trace, mat[0][0] + mat[1][1] + mat[2][2] + mat[3][3])) + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_trace3) { + mat4 mat = A_MATRIX; + float trace; + + trace = glm_mat4_trace3(mat); + + ASSERT(glm_eq(trace, mat[0][0] + mat[1][1] + mat[2][2])) + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_quat) { + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_transpose_to) { + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_transpose) { + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_scale_p) { + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_scale) { + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_det) { + mat4 m1 = GLM_MAT4_IDENTITY_INIT; + + test_rand_mat4(m1); + + /* test determinant */ + ASSERT(glm_mat4_det(m1) == glmc_mat4_det(m1)) +#if defined( __SSE2__ ) + ASSERT(glmc_mat4_det(m1) == glm_mat4_det_sse2(m1)) +#endif + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_inv) { mat4 m1 = GLM_MAT4_IDENTITY_INIT; mat4 m3; mat4 m4 = GLM_MAT4_ZERO_INIT; @@ -71,33 +282,33 @@ TEST_IMPL(mat4_all) { for (i = 0; i < 100000; i++) { test_rand_mat4(m3); test_rand_mat4(m4); - + /* test inverse precise */ - glm_mat4_inv_precise(m3, m4); - glm_mat4_inv_precise(m4, m5); - ASSERT(test_assert_mat4_eq(m3, m5).status == TEST_OK) - + glm_mat4_inv(m3, m4); + glm_mat4_inv(m4, m5); + ASSERTIFY(test_assert_mat4_eq(m3, m5)) + test_rand_mat4(m3); test_rand_mat4(m4); glmc_mat4_inv_precise(m3, m4); glmc_mat4_inv_precise(m4, m5); - ASSERT(test_assert_mat4_eq(m3, m5).status == TEST_OK) - + ASSERTIFY(test_assert_mat4_eq(m3, m5)) + /* test inverse rcp */ test_rand_mat4(m3); test_rand_mat4(m4); - + glm_mat4_inv_fast(m3, m4); glm_mat4_inv_fast(m4, m5); - ASSERT(test_assert_mat4_eq2(m3, m5, 0.0009f).status == TEST_OK) - + ASSERTIFY(test_assert_mat4_eq2(m3, m5, 0.0009f)) + test_rand_mat4(m3); test_rand_mat4(m4); - + glmc_mat4_inv(m3, m4); glmc_mat4_inv(m4, m5); - ASSERT(test_assert_mat4_eq2(m3, m5, 0.0009f).status == TEST_OK) + ASSERTIFY(test_assert_mat4_eq2(m3, m5, 0.0009f)) } /* test determinant */ @@ -105,6 +316,22 @@ TEST_IMPL(mat4_all) { #if defined( __SSE2__ ) ASSERT(glmc_mat4_det(m1) == glm_mat4_det_sse2(m1)) #endif - + + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_inv_fast) { + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_swap_col) { + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_swap_row) { + TEST_SUCCESS +} + +TEST_IMPL(glm_mat4_rmc) { TEST_SUCCESS } diff --git a/lib/cglm/test/src/test_quat.c b/lib/cglm/test/src/test_quat.c index 97ddd49..44725ee 100644 --- a/lib/cglm/test/src/test_quat.c +++ b/lib/cglm/test/src/test_quat.c @@ -27,7 +27,7 @@ TEST_IMPL(quat) { ASSERT(glm_eq(glm_quat_real(q4), cosf(glm_rad(0.0f) * 0.5f))) glm_quat_mat4(q4, rot1); - ASSERT(test_assert_mat4_eq2(rot1, GLM_MAT4_IDENTITY, 0.000009).status == 1) + ASSERTIFY(test_assert_mat4_eq2(rot1, GLM_MAT4_IDENTITY, 0.000009f)) /* 1. test quat to mat and mat to quat */ for (i = 0; i < 1000; i++) { @@ -38,17 +38,17 @@ TEST_IMPL(quat) { glmc_quat_mat4(outQuat, outRot); /* 2. test first quat and generated one equality */ - ASSERT(test_assert_quat_eq_abs(inQuat, outQuat).status == 1); + ASSERTIFY(test_assert_quat_eq_abs(inQuat, outQuat)); /* 3. test first rot and second rotation */ /* almost equal */ - ASSERT(test_assert_mat4_eq2(inRot, outRot, 0.000009).status == 1); + ASSERTIFY(test_assert_mat4_eq2(inRot, outRot, 0.000009f)); /* 4. test SSE mul and raw mul */ #if defined( __SSE__ ) || defined( __SSE2__ ) test_quat_mul_raw(inQuat, outQuat, q3); glm_quat_mul_sse2(inQuat, outQuat, q4); - ASSERT(test_assert_quat_eq(q3, q4).status == 1); + ASSERTIFY(test_assert_quat_eq(q3, q4)); #endif } @@ -62,7 +62,7 @@ TEST_IMPL(quat) { /* create view matrix with quaternion */ glm_quat_look(eye, q3, view2); - ASSERT(test_assert_mat4_eq2(view1, view2, 0.000009).status == 1); + ASSERTIFY(test_assert_mat4_eq2(view1, view2, 0.000009f)); /* 6. test quaternion rotation matrix result */ test_rand_quat(q3); @@ -72,7 +72,7 @@ TEST_IMPL(quat) { glm_quat_axis(q3, axis); glm_rotate_make(rot2, glm_quat_angle(q3), axis); - ASSERT(test_assert_mat4_eq2(rot1, rot2, 0.000009).status == 1); + ASSERTIFY(test_assert_mat4_eq2(rot1, rot2, 0.000009f)); /* 7. test quaternion multiplication (hamilton product), final rotation = first rotation + second = quat1 * quat2 @@ -92,7 +92,7 @@ TEST_IMPL(quat) { glm_quat_mat4(q5, rot2); /* result must be same (almost) */ - ASSERT(test_assert_mat4_eq2(rot1, rot2, 0.000009).status == 1) + ASSERTIFY(test_assert_mat4_eq2(rot1, rot2, 0.000009f)) /* 8. test quaternion for look rotation */ @@ -102,21 +102,21 @@ TEST_IMPL(quat) { /* result must be identity */ glm_quat_identity(q4); - ASSERT(test_assert_quat_eq(q3, q4).status == 1) + ASSERTIFY(test_assert_quat_eq(q3, q4)) /* look at from 0, 0, 1 to zero, direction = 0, 0, -1 */ glm_quat_forp(GLM_ZUP, GLM_VEC3_ZERO, (vec3){0, 0, -1}, GLM_YUP, q3); /* result must be identity */ glm_quat_identity(q4); - ASSERT(test_assert_quat_eq(q3, q4).status == 1) + ASSERTIFY(test_assert_quat_eq(q3, q4)) /* 8.2 perpendicular */ glm_quat_for(GLM_XUP, (vec3){0, 0, -1}, GLM_YUP, q3); /* result must be -90 */ glm_quatv(q4, glm_rad(-90.0f), GLM_YUP); - ASSERT(test_assert_quat_eq(q3, q4).status == 1) + ASSERTIFY(test_assert_quat_eq(q3, q4)) /* 9. test imag, real */ @@ -139,7 +139,7 @@ TEST_IMPL(quat) { imag[1] = -1.0f; imag[2] = 0.0f; - ASSERT(test_assert_vec3_eq(imag, axis).status == 1); + ASSERTIFY(test_assert_vec3_eq(imag, axis)); /* 10. test rotate vector using quat */ /* (0,0,-1) around (1,0,0) must give (0,1,0) */ @@ -157,7 +157,7 @@ TEST_IMPL(quat) { && fabsf(v1[1] - 1.0f) <= 0.00009f && fabsf(v1[2]) <= 0.00009f) - ASSERT(test_assert_vec3_eq(v1, v2).status == 1) + ASSERTIFY(test_assert_vec3_eq(v1, v2)) /* 11. test rotate transform */ glm_translate_make(rot1, (vec3){-10.0, 45.0f, 8.0f}); @@ -168,7 +168,7 @@ TEST_IMPL(quat) { glm_quat_rotate(rot2, q3, rot2); /* result must be same (almost) */ - ASSERT(test_assert_mat4_eq2(rot1, rot2, 0.000009).status == 1) + ASSERTIFY(test_assert_mat4_eq2(rot1, rot2, 0.000009f)) glm_rotate_make(rot1, glm_rad(-90), GLM_ZUP); glm_translate(rot1, (vec3){-10.0, 45.0f, 8.0f}); @@ -179,7 +179,7 @@ TEST_IMPL(quat) { glm_translate(rot2, (vec3){-10.0, 45.0f, 8.0f}); /* result must be same (almost) */ - ASSERT(test_assert_mat4_eq2(rot1, rot2, 0.000009).status == 1) + ASSERTIFY(test_assert_mat4_eq2(rot1, rot2, 0.000009f)) /* reverse */ glm_rotate_make(rot1, glm_rad(-90), GLM_ZUP); @@ -187,7 +187,7 @@ TEST_IMPL(quat) { glm_quat_rotate(rot1, q3, rot1); /* result must be identity */ - ASSERT(test_assert_mat4_eq2(rot1, GLM_MAT4_IDENTITY, 0.000009).status == 1) + ASSERTIFY(test_assert_mat4_eq2(rot1, GLM_MAT4_IDENTITY, 0.000009f)) test_rand_quat(q3); @@ -196,7 +196,7 @@ TEST_IMPL(quat) { glm_quat_mul(q3, q4, q5); glm_quat_identity(q3); - ASSERT(test_assert_quat_eq(q3, q5).status == 1) + ASSERTIFY(test_assert_quat_eq(q3, q5)) /* TODO: add tests for slerp, lerp */ diff --git a/lib/cglm/test/src/test_vec3.c b/lib/cglm/test/src/test_vec3.c index c529cc2..5db3b32 100644 --- a/lib/cglm/test/src/test_vec3.c +++ b/lib/cglm/test/src/test_vec3.c @@ -15,11 +15,11 @@ TEST_IMPL(vec3) { /* test zero */ glm_vec3_zero(v); - ASSERT(test_assert_vec3_eq(GLM_VEC3_ZERO, v).status == 1) + ASSERTIFY(test_assert_vec3_eq(GLM_VEC3_ZERO, v)) /* test one */ glm_vec3_one(v); - ASSERT(test_assert_vec3_eq(GLM_VEC3_ONE, v).status == 1) + ASSERTIFY(test_assert_vec3_eq(GLM_VEC3_ONE, v)) /* adds, subs, div, divs, mul */ glm_vec3_add(v, GLM_VEC3_ONE, v); @@ -50,7 +50,7 @@ TEST_IMPL(vec3) { glm_vec3_normalize_to(v, v1); glm_vec3_scale(v1, 0.8f, v1); glm_vec3_scale_as(v, 0.8f, v); - ASSERT(test_assert_vec3_eq(v1, v).status == 1) + ASSERTIFY(test_assert_vec3_eq(v1, v)) /* addadd, subadd, muladd */ glm_vec3_one(v); @@ -73,8 +73,8 @@ TEST_IMPL(vec3) { glm_mat4_pick3(rot1, rot1m3); glm_vec3_rotate_m3(rot1m3, v, v2); - ASSERT(test_assert_vec3_eq(v1, v2).status == 1) - ASSERT(test_assert_vec3_eq(v1, GLM_ZUP).status == 1) + ASSERTIFY(test_assert_vec3_eq(v1, v2)) + ASSERTIFY(test_assert_vec3_eq(v1, GLM_ZUP)) /* structs */ vs1 = test_rand_vec3s(); @@ -82,7 +82,7 @@ TEST_IMPL(vec3) { vs3 = glms_vec3_add(vs1, vs2); vs4 = glms_vec3_maxv(vs1, vs3); - ASSERT(test_assert_vec3s_eq(vs3, vs4).status == 1) + ASSERTIFY(test_assert_vec3s_eq(vs3, vs4)) /* swizzle */ @@ -91,24 +91,24 @@ TEST_IMPL(vec3) { v1[1] = 2; v1[2] = 3; glm_vec3_swizzle(v1, GLM_ZYX, v1); - ASSERT(test_assert_vec3_eq(v1, (vec3){3, 2, 1}).status == 1) + ASSERTIFY(test_assert_vec3_eq(v1, (vec3){3, 2, 1})) glm_vec3_swizzle(v1, GLM_XXX, v1); - ASSERT(test_assert_vec3_eq(v1, (vec3){3, 3, 3}).status == 1) + ASSERTIFY(test_assert_vec3_eq(v1, (vec3){3, 3, 3})) v1[0] = 1; v1[1] = 2; v1[2] = 3; glm_vec3_swizzle(v1, GLM_YYY, v1); - ASSERT(test_assert_vec3_eq(v1, (vec3){2, 2, 2}).status == 1) + ASSERTIFY(test_assert_vec3_eq(v1, (vec3){2, 2, 2})) v1[0] = 1; v1[1] = 2; v1[2] = 3; glm_vec3_swizzle(v1, GLM_ZZZ, v1); - ASSERT(test_assert_vec3_eq(v1, (vec3){3, 3, 3}).status == 1) + ASSERTIFY(test_assert_vec3_eq(v1, (vec3){3, 3, 3})) TEST_SUCCESS } diff --git a/lib/cglm/test/src/test_vec4.c b/lib/cglm/test/src/test_vec4.c index df59274..160f1e7 100644 --- a/lib/cglm/test/src/test_vec4.c +++ b/lib/cglm/test/src/test_vec4.c @@ -63,11 +63,14 @@ test_vec4_clamp(vec4 v, float minVal, float maxVal) { } TEST_IMPL(vec4) { - vec4 v, v1, v2, v3, v4; + vec4 v, v1, v2, v3, v4, one, zero; vec4s vs1, vs2, vs3, vs4; int i; float d1, d2; + glm_vec4_one(one); + glm_vec4_zero(zero); + for (i = 0; i < 1000; i++) { /* 1. test SSE/SIMD dot product */ test_rand_vec4(v); @@ -98,28 +101,28 @@ TEST_IMPL(vec4) { test_rand_vec4(v2); d1 = glm_vec4_distance(v1, v2); d2 = sqrtf(powf(v1[0] - v2[0], 2.0f) - + pow(v1[1] - v2[1], 2.0f) - + pow(v1[2] - v2[2], 2.0f) - + pow(v1[3] - v2[3], 2.0f)); + + powf(v1[1] - v2[1], 2.0f) + + powf(v1[2] - v2[2], 2.0f) + + powf(v1[3] - v2[3], 2.0f)); ASSERT(fabsf(d1 - d2) <= 0.000009) } /* test zero */ glm_vec4_zero(v); - ASSERT(test_assert_vec4_eq(GLM_VEC4_ZERO, v).status == 1) + ASSERTIFY(test_assert_vec4_eq(zero, v)) /* test one */ glm_vec4_one(v); - ASSERT(test_assert_vec4_eq(GLM_VEC4_ONE, v).status == 1) + ASSERTIFY(test_assert_vec4_eq(one, v)) /* adds, subs, div, divs, mul */ - glm_vec4_add(v, GLM_VEC4_ONE, v); + glm_vec4_add(v, one, v); ASSERT(glmc_vec4_eq_eps(v, 2)) glm_vec4_adds(v, 10, v); ASSERT(glmc_vec4_eq_eps(v, 12)) - glm_vec4_sub(v, GLM_VEC4_ONE, v); + glm_vec4_sub(v, one, v); ASSERT(glmc_vec4_eq_eps(v, 11)) glm_vec4_subs(v, 1, v); @@ -129,27 +132,27 @@ TEST_IMPL(vec4) { glm_vec4_div(v, v1, v); ASSERT(glmc_vec4_eq_eps(v, 5)) - glm_vec4_divs(v, 0.5, v); + glm_vec4_divs(v, 0.5f, v); ASSERT(glmc_vec4_eq_eps(v, 10)) glm_vec4_mul(v, v1, v); ASSERT(glmc_vec4_eq_eps(v, 20)) - glm_vec4_scale(v, 0.5, v); + glm_vec4_scale(v, 0.5f, v); ASSERT(glmc_vec4_eq_eps(v, 10)) glm_vec4_normalize_to(v, v1); - glm_vec4_scale(v1, 0.8, v1); - glm_vec4_scale_as(v, 0.8, v); - ASSERT(test_assert_vec4_eq(v1, v).status == 1) + glm_vec4_scale(v1, 0.8f, v1); + glm_vec4_scale_as(v, 0.8f, v); + ASSERTIFY(test_assert_vec4_eq(v1, v)) /* addadd, subadd, muladd */ glm_vec4_one(v); - glm_vec4_addadd(GLM_VEC4_ONE, GLM_VEC4_ONE, v); + glm_vec4_addadd(one, one, v); ASSERT(glmc_vec4_eq_eps(v, 3)) - glm_vec4_subadd(GLM_VEC4_ONE, GLM_VEC4_ZERO, v); + glm_vec4_subadd(one, zero, v); ASSERT(glmc_vec4_eq_eps(v, 4)) glm_vec4_broadcast(2, v1); @@ -163,16 +166,16 @@ TEST_IMPL(vec4) { glm_vec4_maxv(v1, v2, v3); test_vec4_maxv(v1, v2, v4); - ASSERT(test_assert_vec4_eq(v3, v4).status == 1) + ASSERTIFY(test_assert_vec4_eq(v3, v4)) glm_vec4_minv(v1, v2, v3); test_vec4_minv(v1, v2, v4); - ASSERT(test_assert_vec4_eq(v3, v4).status == 1) + ASSERTIFY(test_assert_vec4_eq(v3, v4)) /* clamp */ - glm_vec4_clamp(v3, 0.1, 0.8); - test_vec4_clamp(v4, 0.1, 0.8); - ASSERT(test_assert_vec4_eq(v3, v4).status == 1) + glm_vec4_clamp(v3, 0.1f, 0.8f); + test_vec4_clamp(v4, 0.1f, 0.8f); + ASSERTIFY(test_assert_vec4_eq(v3, v4)) ASSERT(v3[0] >= 0.0999 && v3[0] <= 0.80001) /* rounding erros */ ASSERT(v3[1] >= 0.0999 && v3[1] <= 0.80001) @@ -188,10 +191,10 @@ TEST_IMPL(vec4) { v1[3] = 4; glm_vec4_swizzle(v1, GLM_WZYX, v1); - ASSERT(test_assert_vec4_eq(v1, (vec4){4, 3, 2, 1}).status == 1) + ASSERTIFY(test_assert_vec4_eq(v1, (vec4){4, 3, 2, 1})) glm_vec4_swizzle(v1, GLM_XXXX, v1); - ASSERT(test_assert_vec4_eq(v1, (vec4){4, 4, 4, 4}).status == 1) + ASSERTIFY(test_assert_vec4_eq(v1, (vec4){4, 4, 4, 4})) v1[0] = 1; v1[1] = 2; @@ -199,7 +202,7 @@ TEST_IMPL(vec4) { v1[3] = 4; glm_vec4_swizzle(v1, GLM_YYYY, v1); - ASSERT(test_assert_vec4_eq(v1, (vec4){2, 2, 2, 2}).status == 1) + ASSERTIFY(test_assert_vec4_eq(v1, (vec4){2, 2, 2, 2})) v1[0] = 1; v1[1] = 2; @@ -207,7 +210,7 @@ TEST_IMPL(vec4) { v1[3] = 4; glm_vec4_swizzle(v1, GLM_ZZZZ, v1); - ASSERT(test_assert_vec4_eq(v1, (vec4){3, 3, 3, 3}).status == 1) + ASSERTIFY(test_assert_vec4_eq(v1, (vec4){3, 3, 3, 3})) v1[0] = 1; v1[1] = 2; @@ -215,7 +218,7 @@ TEST_IMPL(vec4) { v1[3] = 4; glm_vec4_swizzle(v1, GLM_WWWW, v1); - ASSERT(test_assert_vec4_eq(v1, (vec4){4, 4, 4, 4}).status == 1) + ASSERTIFY(test_assert_vec4_eq(v1, (vec4){4, 4, 4, 4})) /* structs */ vs1 = test_rand_vec4s(); @@ -223,7 +226,7 @@ TEST_IMPL(vec4) { vs3 = glms_vec4_add(vs1, vs2); vs4 = glms_vec4_maxv(vs1, vs3); - ASSERT(test_assert_vec4s_eq(vs3, vs4).status == 1) + ASSERTIFY(test_assert_vec4s_eq(vs3, vs4)) TEST_SUCCESS } diff --git a/lib/cglm/test/tests.h b/lib/cglm/test/tests.h index 88562f3..1229842 100644 --- a/lib/cglm/test/tests.h +++ b/lib/cglm/test/tests.h @@ -17,9 +17,32 @@ */ /* mat4 */ -TEST_DECLARE(mat4_identity) -TEST_DECLARE(mat4_mul) -TEST_DECLARE(mat4_all) +TEST_DECLARE(glm_mat4_ucopy) +TEST_DECLARE(glm_mat4_copy) +TEST_DECLARE(glm_mat4_identity) +TEST_DECLARE(glm_mat4_identity_array) +TEST_DECLARE(glm_mat4_zero) +TEST_DECLARE(glm_mat4_pick3) +TEST_DECLARE(glm_mat4_pick3t) +TEST_DECLARE(glm_mat4_ins3) +TEST_DECLARE(glm_mat4_mul) +TEST_DECLARE(glm_mat4_mulN) +TEST_DECLARE(glm_mat4_mulv) +TEST_DECLARE(glm_mat4_mulv3) +TEST_DECLARE(glm_mat4_trace) +TEST_DECLARE(glm_mat4_trace3) +TEST_DECLARE(glm_mat4_quat) +TEST_DECLARE(glm_mat4_transpose_to) +TEST_DECLARE(glm_mat4_transpose) +TEST_DECLARE(glm_mat4_scale_p) +TEST_DECLARE(glm_mat4_scale) +TEST_DECLARE(glm_mat4_det) +TEST_DECLARE(glm_mat4_inv) +TEST_DECLARE(glm_mat4_inv_fast) +TEST_DECLARE(glm_mat4_swap_col) +TEST_DECLARE(glm_mat4_swap_row) +TEST_DECLARE(glm_mat4_rmc) + TEST_DECLARE(affine) @@ -57,9 +80,31 @@ TEST_DECLARE(vec4) TEST_LIST { /* mat4 */ - TEST_ENTRY(mat4_identity) - TEST_ENTRY(mat4_mul) - TEST_ENTRY(mat4_all) + TEST_ENTRY(glm_mat4_ucopy) + TEST_ENTRY(glm_mat4_copy) + TEST_ENTRY(glm_mat4_identity) + TEST_ENTRY(glm_mat4_identity_array) + TEST_ENTRY(glm_mat4_zero) + TEST_ENTRY(glm_mat4_pick3) + TEST_ENTRY(glm_mat4_pick3t) + TEST_ENTRY(glm_mat4_ins3) + TEST_ENTRY(glm_mat4_mul) + TEST_ENTRY(glm_mat4_mulN) + TEST_ENTRY(glm_mat4_mulv) + TEST_ENTRY(glm_mat4_mulv3) + TEST_ENTRY(glm_mat4_trace) + TEST_ENTRY(glm_mat4_trace3) + TEST_ENTRY(glm_mat4_quat) + TEST_ENTRY(glm_mat4_transpose_to) + TEST_ENTRY(glm_mat4_transpose) + TEST_ENTRY(glm_mat4_scale_p) + TEST_ENTRY(glm_mat4_scale) + TEST_ENTRY(glm_mat4_det) + TEST_ENTRY(glm_mat4_inv) + TEST_ENTRY(glm_mat4_inv_fast) + TEST_ENTRY(glm_mat4_swap_col) + TEST_ENTRY(glm_mat4_swap_row) + TEST_ENTRY(glm_mat4_rmc) TEST_ENTRY(affine) diff --git a/lib/cglm/win/.gitignore b/lib/cglm/win/.gitignore index da6703c..96c0a51 100644 --- a/lib/cglm/win/.gitignore +++ b/lib/cglm/win/.gitignore @@ -1,4 +1,9 @@ !cglm.sln + !cglm.vcxproj !cglm.vcxproj.filters + +!cglm-test.vcxproj +!cglm-test.vcxproj.filters + !packages.config diff --git a/lib/cglm/win/cglm-test.vcxproj b/lib/cglm/win/cglm-test.vcxproj new file mode 100644 index 0000000..c833e6c --- /dev/null +++ b/lib/cglm/win/cglm-test.vcxproj @@ -0,0 +1,189 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + {ca8bcaf9-cd25-4133-8f62-3d1449b5d2fc} + + + + 16.0 + {200E0DF1-7532-44E6-8273-84FB92C5557E} + Win32Proj + cglmtest + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + + + true + + + true + + + false + + + + + + Level3 + MaxSpeed + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + %(AdditionalDependencies) + + + + + + + Level3 + Disabled + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../include;%(AdditionalIncludeDirectories) + + + Console + true + %(AdditionalDependencies) + + + + + + + Level3 + Disabled + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../include;%(AdditionalIncludeDirectories) + + + Console + true + %(AdditionalDependencies) + + + + + + + Level3 + MaxSpeed + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ../include;%(AdditionalIncludeDirectories) + + + Console + true + true + true + %(AdditionalDependencies) + + + + + + \ No newline at end of file diff --git a/lib/cglm/win/cglm-test.vcxproj.filters b/lib/cglm/win/cglm-test.vcxproj.filters new file mode 100644 index 0000000..c68818e --- /dev/null +++ b/lib/cglm/win/cglm-test.vcxproj.filters @@ -0,0 +1,65 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + src + + + + + include + + + include + + + include + + + \ No newline at end of file diff --git a/lib/cglm/win/cglm.sln b/lib/cglm/win/cglm.sln index 6316235..04f08b4 100644 --- a/lib/cglm/win/cglm.sln +++ b/lib/cglm/win/cglm.sln @@ -1,10 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26403.7 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.29123.88 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cglm", "cglm.vcxproj", "{CA8BCAF9-CD25-4133-8F62-3D1449B5D2FC}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cglm-test", "cglm-test.vcxproj", "{200E0DF1-7532-44E6-8273-84FB92C5557E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x64 = Debug|x64 @@ -21,8 +23,19 @@ Global {CA8BCAF9-CD25-4133-8F62-3D1449B5D2FC}.Release|x64.Build.0 = Release|x64 {CA8BCAF9-CD25-4133-8F62-3D1449B5D2FC}.Release|x86.ActiveCfg = Release|Win32 {CA8BCAF9-CD25-4133-8F62-3D1449B5D2FC}.Release|x86.Build.0 = Release|Win32 + {200E0DF1-7532-44E6-8273-84FB92C5557E}.Debug|x64.ActiveCfg = Debug|x64 + {200E0DF1-7532-44E6-8273-84FB92C5557E}.Debug|x64.Build.0 = Debug|x64 + {200E0DF1-7532-44E6-8273-84FB92C5557E}.Debug|x86.ActiveCfg = Debug|Win32 + {200E0DF1-7532-44E6-8273-84FB92C5557E}.Debug|x86.Build.0 = Debug|Win32 + {200E0DF1-7532-44E6-8273-84FB92C5557E}.Release|x64.ActiveCfg = Release|x64 + {200E0DF1-7532-44E6-8273-84FB92C5557E}.Release|x64.Build.0 = Release|x64 + {200E0DF1-7532-44E6-8273-84FB92C5557E}.Release|x86.ActiveCfg = Release|Win32 + {200E0DF1-7532-44E6-8273-84FB92C5557E}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2AEF23C9-433B-428B-BEBC-068BF3AC9A65} + EndGlobalSection EndGlobal diff --git a/lib/cglm/win/cglm.vcxproj.filters b/lib/cglm/win/cglm.vcxproj.filters index a9e3f47..21c554c 100644 --- a/lib/cglm/win/cglm.vcxproj.filters +++ b/lib/cglm/win/cglm.vcxproj.filters @@ -5,10 +5,6 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx diff --git a/lib/glfw/docs/Doxyfile.in b/lib/glfw/docs/Doxyfile.in index bbbbbd6..ab55f63 100644 --- a/lib/glfw/docs/Doxyfile.in +++ b/lib/glfw/docs/Doxyfile.in @@ -1714,7 +1714,7 @@ UML_LOOK = NO # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more -# managable. Set this to 0 for no limit. Note that the threshold may be +# manageable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 diff --git a/lib/glfw/docs/input.dox b/lib/glfw/docs/input.dox index 8823cb2..8d78e6c 100644 --- a/lib/glfw/docs/input.dox +++ b/lib/glfw/docs/input.dox @@ -889,7 +889,7 @@ timer varies depending on the operating system and hardware. You can query the frequency, in Hz, with @ref glfwGetTimerFrequency. @code -uint64_t freqency = glfwGetTimerFrequency(); +uint64_t frequency = glfwGetTimerFrequency(); @endcode diff --git a/lib/glfw/examples/particles.c b/lib/glfw/examples/particles.c index 248c851..9556cca 100644 --- a/lib/glfw/examples/particles.c +++ b/lib/glfw/examples/particles.c @@ -444,7 +444,7 @@ static void draw_particles(GLFWwindow* window, double t, float dt) } // Set up vertex arrays. We use interleaved arrays, which is easier to - // handle (in most situations) and it gives a linear memeory access + // handle (in most situations) and it gives a linear memory access // access pattern (which may give better performance in some // situations). GL_T2F_C4UB_V3F means: 2 floats for texture coords, // 4 ubytes for color and 3 floats for vertex coord (in that order). @@ -654,7 +654,7 @@ static void draw_fountain(void) //======================================================================== -// Recursive function for building variable tesselated floor +// Recursive function for building variable tessellated floor //======================================================================== static void tessellate_floor(float x1, float y1, float x2, float y2, int depth) @@ -721,7 +721,7 @@ static void draw_floor(void) glMaterialfv(GL_FRONT, GL_SPECULAR, floor_specular); glMaterialf(GL_FRONT, GL_SHININESS, floor_shininess); - // Draw floor as a bunch of triangle strips (high tesselation + // Draw floor as a bunch of triangle strips (high tessellation // improves lighting) glNormal3f(0.f, 0.f, 1.f); glBegin(GL_QUADS); diff --git a/lib/glfw/examples/splitview.c b/lib/glfw/examples/splitview.c index 58eb11e..58441db 100644 --- a/lib/glfw/examples/splitview.c +++ b/lib/glfw/examples/splitview.c @@ -3,7 +3,7 @@ // // The program uses a "split window" view, rendering four views of the // same scene in one window (e.g. uesful for 3D modelling software). This -// demo uses scissors to separete the four different rendering areas from +// demo uses scissors to separate the four different rendering areas from // each other. // // (If the code seems a little bit strange here and there, it may be diff --git a/lib/glfw/include/GLFW/glfw3.h b/lib/glfw/include/GLFW/glfw3.h index e8c9b15..dad45a4 100644 --- a/lib/glfw/include/GLFW/glfw3.h +++ b/lib/glfw/include/GLFW/glfw3.h @@ -2041,7 +2041,7 @@ GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void); */ GLFWAPI void glfwGetMonitorPos(GLFWmonitor* monitor, int* xpos, int* ypos); -/*! @brief Retrives the work area of the monitor. +/*! @brief Retrieves the work area of the monitor. * * This function returns the position, in screen coordinates, of the upper-left * corner of the work area of the specified monitor along with the work area @@ -2325,7 +2325,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * GLFW_INVALID_VALUE and @ref GLFW_PLATFORM_ERROR. * - * @remark @wayland Gamma handling is a priviledged protocol, this function + * @remark @wayland Gamma handling is a privileged protocol, this function * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR. * * @thread_safety This function must only be called from the main thread. @@ -2349,7 +2349,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark @wayland Gamma handling is a priviledged protocol, this function + * @remark @wayland Gamma handling is a privileged protocol, this function * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR while * returning `NULL`. * @@ -2393,7 +2393,7 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * * @remark @win32 The gamma ramp size must be 256. * - * @remark @wayland Gamma handling is a priviledged protocol, this function + * @remark @wayland Gamma handling is a privileged protocol, this function * will thus never be implemented and emits @ref GLFW_PLATFORM_ERROR. * * @pointer_lifetime The specified gamma ramp is copied before this function @@ -2612,7 +2612,7 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value); * * @remark @macos When activating frame autosaving with * [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified - * window size and position may be overriden by previously saved values. + * window size and position may be overridden by previously saved values. * * @remark @x11 Some window managers will not respect the placement of * initially hidden windows. @@ -4984,7 +4984,7 @@ GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count); */ GLFWAPI const char* glfwGetJoystickName(int jid); -/*! @brief Returns the SDL comaptible GUID of the specified joystick. +/*! @brief Returns the SDL compatible GUID of the specified joystick. * * This function returns the SDL compatible GUID, as a UTF-8 encoded * hexadecimal string, of the specified joystick. The returned string is @@ -5205,7 +5205,7 @@ GLFWAPI const char* glfwGetGamepadName(int jid); /*! @brief Retrieves the state of the specified joystick remapped as a gamepad. * - * This function retrives the state of the specified joystick remapped to + * This function retrieves the state of the specified joystick remapped to * an Xbox-like gamepad. * * If the specified joystick is not present or does not have a gamepad mapping diff --git a/lib/glfw/src/win32_init.c b/lib/glfw/src/win32_init.c index 950a52a..260e888 100644 --- a/lib/glfw/src/win32_init.c +++ b/lib/glfw/src/win32_init.c @@ -525,7 +525,7 @@ BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp) cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); // HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the - // latter lies unless the user knew to embedd a non-default manifest + // latter lies unless the user knew to embed a non-default manifest // announcing support for Windows 10 via supportedOS GUID return RtlVerifyVersionInfo(&osvi, mask, cond) == 0; } @@ -540,7 +540,7 @@ BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build) cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL); // HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the - // latter lies unless the user knew to embedd a non-default manifest + // latter lies unless the user knew to embed a non-default manifest // announcing support for Windows 10 via supportedOS GUID return RtlVerifyVersionInfo(&osvi, mask, cond) == 0; } diff --git a/lib/glfw/src/wl_window.c b/lib/glfw/src/wl_window.c index 5c7011f..200b004 100644 --- a/lib/glfw/src/wl_window.c +++ b/lib/glfw/src/wl_window.c @@ -68,7 +68,7 @@ static int createTmpfileCloexec(char* tmpname) * SCM_RIGHTS methods. * * posix_fallocate() is used to guarantee that disk space is available - * for the file at the given size. If disk space is insufficent, errno + * for the file at the given size. If disk space is insufficient, errno * is set to ENOSPC. If posix_fallocate() is not supported, program may * receive SIGBUS on accessing mmap()'ed file contents instead. */ diff --git a/lib/glfw/tests/events.c b/lib/glfw/tests/events.c index ba7f00a..251e15d 100644 --- a/lib/glfw/tests/events.c +++ b/lib/glfw/tests/events.c @@ -175,7 +175,7 @@ static const char* get_key_name(int key) case GLFW_KEY_KP_8: return "KEYPAD 8"; case GLFW_KEY_KP_9: return "KEYPAD 9"; case GLFW_KEY_KP_DIVIDE: return "KEYPAD DIVIDE"; - case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTPLY"; + case GLFW_KEY_KP_MULTIPLY: return "KEYPAD MULTIPLY"; case GLFW_KEY_KP_SUBTRACT: return "KEYPAD SUBTRACT"; case GLFW_KEY_KP_ADD: return "KEYPAD ADD"; case GLFW_KEY_KP_DECIMAL: return "KEYPAD DECIMAL"; diff --git a/lib/imgui/docs/CHANGELOG.txt b/lib/imgui/docs/CHANGELOG.txt index a34aef9..6e487ae 100644 --- a/lib/imgui/docs/CHANGELOG.txt +++ b/lib/imgui/docs/CHANGELOG.txt @@ -34,6 +34,7 @@ HOW TO UPDATE? ----------------------------------------------------------------------- Other Changes: +- Nav, Scrolling: Added support for Home/End key. (#787) - ColorPicker: Made rendering aware of global style alpha of the picker can be faded out. (#2711) Note that some elements won't accurately fade down with the same intensity, and the color wheel when enabled will have small overlap glitches with (style.Alpha < 1.0). @@ -44,13 +45,18 @@ Other Changes: (before 1.71 tab bars fed the sum of current width which created feedback loops in certain situations). - TabBar: improved shrinking for large number of tabs to avoid leaving extraneous space on the right side. Individuals tabs are given integer-rounded width and remainder is spread between tabs left-to-right. +- Columns, Separator: Fixed a bug where non-visible separators within columns would alter the next row position + differently than visible ones. - SliderScalar: Improved assert when using U32 or U64 types with a large v_max value. (#2765) [@loicmouton] - DragInt, DragFloat, DragScalar: Using (v_min > v_max) allows locking any edit to the value. +- DragScalar: Fixed dragging of unsigned values on ARM cpu. (#2780) [@dBagrat] - ImDrawList: clarified the name of many parameters so reading the code is a little easier. (#2740) - Using offsetof() when available in C++11. Avoids Clang sanitizer complaining about old-style macros. (#94) - Added a mechanism to compact/free the larger allocations of unused windows (buffers are compacted when a window is unused for 60 seconds, as per io.ConfigWindowsMemoryCompactTimer = 60.0f). Note that memory usage has never been reported as a problem, so this is merely a touch of overzealous luxury. (#2636) +- Backends: OpenGL3: Tweaked initialization code allow application calling ImGui_ImplOpenGL3_CreateFontsTexture() + before ImGui_ImplOpenGL3_NewFrame() if for some reason they wanted. - Backends: DX11: Fixed GSGetShader() call not passing an initialized instance count, would generally make the debug layer complain (Added in 1.72). - Backends: Vulkan: Added support for specifying multisample count. diff --git a/lib/imgui/docs/TODO.txt b/lib/imgui/docs/TODO.txt index f289eba..70c64c4 100644 --- a/lib/imgui/docs/TODO.txt +++ b/lib/imgui/docs/TODO.txt @@ -300,12 +300,14 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - font/opt: Considering storing standalone AdvanceX table as 16-bit fixed point integer? - font/opt: Glyph currently 40 bytes (2+9*4). Consider storing UV as 16 bits integer? (->32 bytes). X0/Y0/X1/Y1 as 16 fixed-point integers? Or X0/Y0 as float and X1/Y1 as fixed8_8? + - nav: some features such as PageUp/Down/Home/End should probably work without ImGuiConfigFlags_NavEnableKeyboard? (where do we draw the line?) + - nav: configuration flag to disable global shortcuts (currently only CTRL-Tab) ? + - nav: Home/End behavior when navigable item is not fully visible at the edge of scrolling? should be backtrack to keep item into view? - nav: NavScrollToBringItemIntoView() with item bigger than view should focus top-right? Repro: using Nav in "About Window" - nav: wrap around logic to allow e.g. grid based layout (pressing NavRight on the right-most element would go to the next row, etc.). see internal's NavMoveRequestTryWrapping(). - nav: patterns to make it possible for arrows key to update selection - - nav: restore/find nearest navid when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name) + - nav: restore/find nearest NavId when current one disappear (e.g. pressed a button that disappear, or perhaps auto restoring when current button change name) - nav: SetItemDefaultFocus() level of priority, so widget like Selectable when inside a popup could claim a low-priority default focus on the first selected iem - - nav: allow input system to be be more tolerant of io.DeltaTime=0.0f - nav: ESC within a menu of a child window seems to exit the child window. - nav: NavFlattened: ESC on a flattened child should select something. - nav: NavFlattened: broken: in typical usage scenario, the items of a fully clipped child are currently not considered to enter into a NavFlattened child. @@ -323,7 +325,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - nav: esc/enter default behavior for popups, e.g. be able to mark an "ok" or "cancel" button that would get triggered by those keys. - nav: when activating a button that changes label (without a static ID) or disappear, can we somehow automatically recover into a nearest highlight item? - nav: there's currently no way to completely clear focus with the keyboard. depending on patterns used by the application to dispatch inputs, it may be desirable. - - nav: configuration flag to disable global shortcuts (currently only CTRL-tab) ? - focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622) - focus: SetKeyboardFocusHere() on with >= 0 offset could be done on same frame (else latch and modulate on beginning of next frame) - focus: unable to use SetKeyboardFocusHere() on clipped widgets. (#787) diff --git a/lib/imgui/examples/imgui_impl_opengl3.cpp b/lib/imgui/examples/imgui_impl_opengl3.cpp index 9585215..199638e 100644 --- a/lib/imgui/examples/imgui_impl_opengl3.cpp +++ b/lib/imgui/examples/imgui_impl_opengl3.cpp @@ -13,6 +13,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2019-09-16: OpenGL: Tweak initialization code to allow application calling ImGui_ImplOpenGL3_CreateFontsTexture() before the first NewFrame() call. // 2019-05-29: OpenGL: Desktop GL only: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag. // 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state. // 2019-03-29: OpenGL: Not calling glBindBuffer more than necessary in the render loop. @@ -164,7 +165,7 @@ void ImGui_ImplOpenGL3_Shutdown() void ImGui_ImplOpenGL3_NewFrame() { - if (!g_FontTexture) + if (!g_ShaderHandle) ImGui_ImplOpenGL3_CreateDeviceObjects(); } @@ -613,20 +614,13 @@ bool ImGui_ImplOpenGL3_CreateDeviceObjects() void ImGui_ImplOpenGL3_DestroyDeviceObjects() { - if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); - if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); - g_VboHandle = g_ElementsHandle = 0; - - if (g_ShaderHandle && g_VertHandle) glDetachShader(g_ShaderHandle, g_VertHandle); - if (g_VertHandle) glDeleteShader(g_VertHandle); - g_VertHandle = 0; - - if (g_ShaderHandle && g_FragHandle) glDetachShader(g_ShaderHandle, g_FragHandle); - if (g_FragHandle) glDeleteShader(g_FragHandle); - g_FragHandle = 0; - - if (g_ShaderHandle) glDeleteProgram(g_ShaderHandle); - g_ShaderHandle = 0; + if (g_VboHandle) { glDeleteBuffers(1, &g_VboHandle); g_VboHandle = 0; } + if (g_ElementsHandle) { glDeleteBuffers(1, &g_ElementsHandle); g_ElementsHandle = 0; } + if (g_ShaderHandle && g_VertHandle) { glDetachShader(g_ShaderHandle, g_VertHandle); } + if (g_ShaderHandle && g_FragHandle) { glDetachShader(g_ShaderHandle, g_FragHandle); } + if (g_VertHandle) { glDeleteShader(g_VertHandle); g_VertHandle = 0; } + if (g_FragHandle) { glDeleteShader(g_FragHandle); g_FragHandle = 0; } + if (g_ShaderHandle) { glDeleteProgram(g_ShaderHandle); g_ShaderHandle = 0; } ImGui_ImplOpenGL3_DestroyFontsTexture(); } diff --git a/lib/imgui/imgui.cpp b/lib/imgui/imgui.cpp index 89541b2..1dc4862 100644 --- a/lib/imgui/imgui.cpp +++ b/lib/imgui/imgui.cpp @@ -1078,7 +1078,7 @@ static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& // Navigation static void NavUpdate(); static void NavUpdateWindowing(); -static void NavUpdateWindowingList(); +static void NavUpdateWindowingOverlay(); static void NavUpdateMoveResult(); static float NavUpdatePageUpPageDown(int allowed_dir_flags); static inline void NavUpdateAnyRequestFlag(); @@ -4184,8 +4184,8 @@ void ImGui::EndFrame() End(); // Show CTRL+TAB list window - if (g.NavWindowingTarget) - NavUpdateWindowingList(); + if (g.NavWindowingTarget != NULL) + NavUpdateWindowingOverlay(); // Drag and Drop: Elapse payload (if delivered, or if source stops being submitted) if (g.DragDropActive) @@ -8074,7 +8074,7 @@ void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, const Im { ImGuiContext& g = *GImGui; IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_None); - ImGui::NavMoveRequestCancel(); + NavMoveRequestCancel(); g.NavMoveDir = move_dir; g.NavMoveClipDir = clip_dir; g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; @@ -8410,10 +8410,10 @@ static void ImGui::NavUpdate() g.NavMoveRequestFlags = ImGuiNavMoveFlags_None; if (g.NavWindow && !g.NavWindowingTarget && allowed_dir_flags && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) { - if ((allowed_dir_flags & (1<RectRel.Min + result->Window->Pos, result->RectRel.Max + result->Window->Pos); - ImVec2 delta_scroll = ScrollToBringRectIntoView(result->Window, rect_abs); + ImVec2 delta_scroll; + if (g.NavMoveRequestFlags & ImGuiNavMoveFlags_ScrollToEdge) + { + float scroll_target = (g.NavMoveDir == ImGuiDir_Up) ? result->Window->ScrollMax.y : 0.0f; + delta_scroll.y = result->Window->Scroll.y - scroll_target; + SetScrollY(result->Window, scroll_target); + } + else + { + ImRect rect_abs = ImRect(result->RectRel.Min + result->Window->Pos, result->RectRel.Max + result->Window->Pos); + delta_scroll = ScrollToBringRectIntoView(result->Window, rect_abs); + } // Offset our result position so mouse position can be applied immediately after in NavUpdate() result->RectRel.TranslateX(-delta_scroll.x); @@ -8565,6 +8576,7 @@ static void ImGui::NavUpdateMoveResult() g.NavMoveFromClampedRefRect = false; } +// Handle PageUp/PageDown/Home/End keys static float ImGui::NavUpdatePageUpPageDown(int allowed_dir_flags) { ImGuiContext& g = *GImGui; @@ -8574,9 +8586,11 @@ static float ImGui::NavUpdatePageUpPageDown(int allowed_dir_flags) return 0.0f; ImGuiWindow* window = g.NavWindow; - bool page_up_held = IsKeyDown(g.IO.KeyMap[ImGuiKey_PageUp]) && (allowed_dir_flags & (1 << ImGuiDir_Up)); - bool page_down_held = IsKeyDown(g.IO.KeyMap[ImGuiKey_PageDown]) && (allowed_dir_flags & (1 << ImGuiDir_Down)); - if (page_up_held != page_down_held) // If either (not both) are pressed + const bool page_up_held = IsKeyDown(g.IO.KeyMap[ImGuiKey_PageUp]) && (allowed_dir_flags & (1 << ImGuiDir_Up)); + const bool page_down_held = IsKeyDown(g.IO.KeyMap[ImGuiKey_PageDown]) && (allowed_dir_flags & (1 << ImGuiDir_Down)); + const bool home_pressed = IsKeyPressed(g.IO.KeyMap[ImGuiKey_Home]) && (allowed_dir_flags & (1 << ImGuiDir_Up)); + const bool end_pressed = IsKeyPressed(g.IO.KeyMap[ImGuiKey_End]) && (allowed_dir_flags & (1 << ImGuiDir_Down)); + if (page_up_held != page_down_held || home_pressed != end_pressed) // If either (not both) are pressed { if (window->DC.NavLayerActiveMask == 0x00 && window->DC.NavHasScroll) { @@ -8585,26 +8599,49 @@ static float ImGui::NavUpdatePageUpPageDown(int allowed_dir_flags) SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight()); else if (IsKeyPressed(g.IO.KeyMap[ImGuiKey_PageDown], true)) SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight()); + else if (home_pressed) + SetScrollY(window, 0.0f); + else if (end_pressed) + SetScrollY(window, window->ScrollMax.y); } else { - const ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer]; + ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer]; const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight()); float nav_scoring_rect_offset_y = 0.0f; if (IsKeyPressed(g.IO.KeyMap[ImGuiKey_PageUp], true)) { nav_scoring_rect_offset_y = -page_offset_y; - g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset, we intentionally request the opposite direction (so we can always land on the last item) + g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item) g.NavMoveClipDir = ImGuiDir_Up; g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet; } else if (IsKeyPressed(g.IO.KeyMap[ImGuiKey_PageDown], true)) { nav_scoring_rect_offset_y = +page_offset_y; - g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset, we intentionally request the opposite direction (so we can always land on the last item) + g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item) g.NavMoveClipDir = ImGuiDir_Down; g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet; } + else if (home_pressed) + { + // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y + // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdge flag, we don't scroll immediately to avoid scrolling happening before nav result. + // Preserve current horizontal position if we have any. + nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y; + if (nav_rect_rel.IsInverted()) + nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f; + g.NavMoveDir = ImGuiDir_Down; + g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge; + } + else if (end_pressed) + { + nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y; + if (nav_rect_rel.IsInverted()) + nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f; + g.NavMoveDir = ImGuiDir_Up; + g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge; + } return nav_scoring_rect_offset_y; } } @@ -8800,7 +8837,7 @@ static const char* GetFallbackWindowNameForWindowingList(ImGuiWindow* window) } // Overlay displayed when using CTRL+TAB. Called by EndFrame(). -void ImGui::NavUpdateWindowingList() +void ImGui::NavUpdateWindowingOverlay() { ImGuiContext& g = *GImGui; IM_ASSERT(g.NavWindowingTarget != NULL); diff --git a/lib/imgui/imgui_demo.cpp b/lib/imgui/imgui_demo.cpp index d5bc96c..fd1d85a 100644 --- a/lib/imgui/imgui_demo.cpp +++ b/lib/imgui/imgui_demo.cpp @@ -1451,7 +1451,7 @@ static void ShowDemoWindowWidgets() ImGui::PushID("set2"); static float values2[4] = { 0.20f, 0.80f, 0.40f, 0.25f }; const int rows = 3; - const ImVec2 small_slider_size(18, (160.0f-(rows-1)*spacing)/rows); + const ImVec2 small_slider_size(18, (float)(int)((160.0f - (rows - 1) * spacing) / rows)); for (int nx = 0; nx < 4; nx++) { if (nx > 0) ImGui::SameLine(); diff --git a/lib/imgui/imgui_internal.h b/lib/imgui/imgui_internal.h index f13aeed..9c87d2a 100644 --- a/lib/imgui/imgui_internal.h +++ b/lib/imgui/imgui_internal.h @@ -497,7 +497,8 @@ enum ImGuiNavMoveFlags_ ImGuiNavMoveFlags_WrapX = 1 << 2, // On failed request, request from opposite side one line down (when NavDir==right) or one line up (when NavDir==left) ImGuiNavMoveFlags_WrapY = 1 << 3, // This is not super useful for provided for completeness ImGuiNavMoveFlags_AllowCurrentNavId = 1 << 4, // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place) - ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5 // Store alternate result in NavMoveResultLocalVisibleSet that only comprise elements that are already fully visible. + ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisibleSet that only comprise elements that are already fully visible. + ImGuiNavMoveFlags_ScrollToEdge = 1 << 6 }; enum ImGuiNavForward @@ -960,7 +961,7 @@ struct ImGuiContext ImGuiNavMoveFlags NavMoveRequestFlags; ImGuiNavForward NavMoveRequestForward; // None / ForwardQueued / ForwardActive (this is used to navigate sibling parent menus from a child menu) ImGuiDir NavMoveDir, NavMoveDirLast; // Direction of the move request (left/right/up/down), direction of the previous move request - ImGuiDir NavMoveClipDir; + ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename? ImGuiNavMoveResult NavMoveResultLocal; // Best move request candidate within NavWindow ImGuiNavMoveResult NavMoveResultLocalVisibleSet; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag) ImGuiNavMoveResult NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag) diff --git a/lib/imgui/imgui_widgets.cpp b/lib/imgui/imgui_widgets.cpp index a91268b..35ce143 100644 --- a/lib/imgui/imgui_widgets.cpp +++ b/lib/imgui/imgui_widgets.cpp @@ -1261,7 +1261,10 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags) if (!ItemAdd(bb, 0)) { if (columns) + { PopColumnsBackground(); + columns->LineMinY = window->DC.CursorPos.y; + } return; } @@ -1975,12 +1978,12 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const // Offset + round to user desired precision, with a curve on the v_min..v_max range to get more precision on one side of the range FLOATTYPE v_old_norm_curved = ImPow((FLOATTYPE)(v_cur - v_min) / (FLOATTYPE)(v_max - v_min), (FLOATTYPE)1.0f / power); FLOATTYPE v_new_norm_curved = v_old_norm_curved + (g.DragCurrentAccum / (v_max - v_min)); - v_cur = v_min + (TYPE)ImPow(ImSaturate((float)v_new_norm_curved), power) * (v_max - v_min); + v_cur = v_min + (SIGNEDTYPE)ImPow(ImSaturate((float)v_new_norm_curved), power) * (v_max - v_min); v_old_ref_for_accum_remainder = v_old_norm_curved; } else { - v_cur += (TYPE)g.DragCurrentAccum; + v_cur += (SIGNEDTYPE)g.DragCurrentAccum; } // Round to user desired precision based on format string @@ -5624,7 +5627,7 @@ bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_item // We include ItemSpacing.y so that a list sized for the exact number of items doesn't make a scrollbar appears. We could also enforce that by passing a flag to BeginChild(). ImVec2 size; size.x = 0.0f; - size.y = GetTextLineHeightWithSpacing() * height_in_items_f + style.FramePadding.y * 2.0f; + size.y = ImFloor(GetTextLineHeightWithSpacing() * height_in_items_f + style.FramePadding.y * 2.0f); return ListBoxHeader(label, size); } diff --git a/run/shaders/gbuf_light_main.frag b/run/shaders/gbuf_light_main.frag index b4eaf47..fa1ae99 100644 --- a/run/shaders/gbuf_light_main.frag +++ b/run/shaders/gbuf_light_main.frag @@ -170,11 +170,9 @@ void main() { #elif defined(DEBUG_VIS_GBUF_NORMAL) outAux2 = vec4(N, 1.0); #elif defined(DEBUG_VIS_GBUF_ORM) - outAux2 = vec4(0.0, aux1.gb, 1.0); + outAux2 = vec4(aux1, 1.0); #elif defined(DEBUG_VIS_GBUF_VELOCITY) outAux2 = vec4(0.05 + velocity * 4.0, 0.0, 1.0); - #elif defined(DEBUG_VIS_GBUF_ORM) - outAux2 = vec4(aux1, 1.0); #elif defined(DEBUG_VIS_WORLDPOS) outAux2 = vec4(FragPosWorld * 0.01, 1.0); #elif defined(DEBUG_VIS_DEPTH_RAW) diff --git a/run/shaders/gbuf_light_point.frag b/run/shaders/gbuf_light_point.frag index 73c4562..c4bafa7 100644 --- a/run/shaders/gbuf_light_point.frag +++ b/run/shaders/gbuf_light_point.frag @@ -1,11 +1,7 @@ #version 330 core -in vec2 fragCoordClip; -in vec2 fragCoord01; - layout(location = 0) out vec4 outColorHDR; -layout(location = 1) out vec4 outAux2; -uniform vec2 iResolution; +uniform ivec2 iResolution; uniform float iTime; uniform int iFrame; @@ -107,6 +103,7 @@ highp float rand (vec2 co) { void main() { ivec2 fc = ivec2(gl_FragCoord.xy); + vec2 fragCoordClip = (gl_FragCoord.xy / vec2(iResolution)) * 2.0 - 1.0; // Don't do lighting calculations for missing fragments (e.g. sky): // FIXME: Replace this with a discard once we have an actual skybox shader. @@ -123,7 +120,6 @@ void main() { vec3 diffuse = texelFetch(gColorLDR, fc, 0).rgb; vec3 aux1 = texelFetch(gAux1, fc, 0).rgb; - vec2 velocity = texelFetch(gAuxHDR16, fc, 0).rg; float rough = max(aux1.g, 0.1); // lighting looks wrong around 0 (specular highlight goes away entirely) float metal = aux1.b; @@ -137,7 +133,8 @@ void main() { vec3 L = uPointLightPosition - FragPosWorld; vec3 Lo = PointLightLo(N, V, L, uPointLightColor, diffuse, metal, rough); - outColorHDR = texelFetch(gColorHDR, fc, 0) + vec4(Lo, 1.0); - - outAux2 = texelFetch(gAux2, fc, 0); // keep info in aux2 (debug vis) + #ifdef DEBUG_SHOW_LIGHT_VOLUMES + Lo += vec3(0.01); + #endif + outColorHDR = vec4(Lo, 1.0); // should be added to gColorHDR } \ No newline at end of file diff --git a/src/assets.h b/src/assets.h index 7ab1b9f..9efa813 100644 --- a/src/assets.h +++ b/src/assets.h @@ -17,7 +17,7 @@ X(PROG_GBUF_MAIN, VSH_DEFAULT, FSH_GBUF_MAIN) \ X(PROG_SHADOW, VSH_SHADOW, FSH_SHADOW) \ X(PROG_GBUF_LIGHT_MAIN, VSH_FULLSCREEN_PASS, FSH_GBUF_LIGHT_MAIN) \ - X(PROG_GBUF_LIGHT_POINT, VSH_FULLSCREEN_PASS, FSH_GBUF_LIGHT_POINT) \ + X(PROG_GBUF_LIGHT_POINT, VSH_DEFAULT, FSH_GBUF_LIGHT_POINT) \ X(PROG_SHADOW_RESOLVE, VSH_FULLSCREEN_PASS, FSH_SHADOW_RESOLVE) \ X(PROG_FINAL, VSH_FULLSCREEN_PASS, FSH_FINAL) \ X(PROG_TAA, VSH_FULLSCREEN_PASS, FSH_TAA) \ @@ -216,6 +216,11 @@ COLOR(GL_COLOR_ATTACHMENT0, RT_COLOR_HDR) \ COLOR(GL_COLOR_ATTACHMENT1, RT_AUX2) \ END(FB_ONLY_COLOR_HDR) \ +\ + BEGIN(FB_ONLY_COLOR_HDR_NO_AUX) \ + DEPTH(GL_DEPTH_ATTACHMENT, RT_DEPTH) \ + COLOR(GL_COLOR_ATTACHMENT0, RT_COLOR_HDR) \ + END(FB_ONLY_COLOR_HDR_NO_AUX) \ \ BEGIN(FB_ONLY_COLOR_LDR) \ DEPTH(GL_DEPTH_ATTACHMENT, RT_DEPTH) \ diff --git a/src/data/model.c b/src/data/model.c index 2501ec9..ef12c66 100644 --- a/src/data/model.c +++ b/src/data/model.c @@ -40,6 +40,7 @@ void InitMaterial (Material* m) { m->blend = false; m->blend_srcf = GL_SRC_ALPHA; // suitable for back-to-front transparency m->blend_dstf = GL_ONE_MINUS_SRC_ALPHA; // suitable for back-to-front transparency + m->blend_func = GL_FUNC_ADD; m->stipple = false; // NOTE: 0.5 is the GLTF default alpha cutoff. GLTF also doesn't include the concept of a soft // cutoff at all, so setting it to anything over 0.5 would result in models rendering diff --git a/src/data/model.h b/src/data/model.h index d490f50..987683b 100644 --- a/src/data/model.h +++ b/src/data/model.h @@ -7,6 +7,7 @@ typedef struct Material { bool blend; GLenum blend_srcf; GLenum blend_dstf; + GLenum blend_func; bool stipple; float stipple_soft_cutoff; float stipple_hard_cutoff; diff --git a/src/gui/gui.cc b/src/gui/gui.cc index 2b12f19..2ee73c2 100644 --- a/src/gui/gui.cc +++ b/src/gui/gui.cc @@ -514,11 +514,13 @@ static void sDrawConfigurator (vxConfig* conf, GLFWwindow* window) { ImGui::Checkbox("Noisy sampling", &conf->shadowNoise); ImGui::Checkbox("Visualize point lights", &conf->debugShowPointLights); + ImGui::SameLine(200); + ImGui::Checkbox("Visualize light volumes", &conf->debugShowLightVolumes); ImGui::Checkbox("Clear GBuffer on redraw", &conf->clearColorBuffers); if (ImGui::IsItemHovered()) { ImGui::BeginTooltip(); - ImGui::Text("Clears all color buffers at the start of the frame. By default, only depth buffers are cleared."); + ImGui::Text("Clears all color buffers at the start of the frame."); ImGui::Text("This is mostly useful when debugging under RenderDoc."); ImGui::EndTooltip(); } diff --git a/src/main.c b/src/main.c index 7ee9080..89d695e 100644 --- a/src/main.c +++ b/src/main.c @@ -570,14 +570,20 @@ void GameTick (vxConfig* conf, GLFWwindow* window, vxFrame* frame, vxFrame* last EndRenderPass(); StartRenderPass(&rs, "GBuffer point lighting"); - BindFramebuffer(FB_ONLY_COLOR_HDR); SetRenderProgram(&rs, &PROG_GBUF_LIGHT_POINT); - SetCamera(&rs, &conf->camMain); - // Render a cube for each light: + BindFramebuffer(FB_ONLY_COLOR_HDR_NO_AUX); + SetCamera(&rs, &camMainJittered); + // Render a light volume, to limit the amount of pixels that have to be shaded, for each point light. for (int i = 0; i < rl.pointLightCount; i++) { glUniform3fv(UNIF_POINTLIGHT_POSITION, 1, (float*) rl.pointLights[i].position); glUniform3fv(UNIF_POINTLIGHT_COLOR, 1, (float*) rl.pointLights[i].color); - RenderMesh(&rs, conf, frame, &MESH_QUAD, &MAT_FULLSCREEN_QUAD); + const float threshold = 0.05; // intensity beyond which we don't render the light + float intensity = glm_vec3_max(rl.pointLights[i].color); + float radius = sqrtf(intensity / threshold); + RenderState lightRs = rs; + MulModelPosition(&lightRs, rl.pointLights[i].position, rl.pointLights[i].position); + MulModelScale(&lightRs, (vec3){radius, radius, radius}, (vec3){radius, radius, radius}); + RenderMesh(&lightRs, conf, frame, &MESH_CUBE, &MAT_LIGHT_VOLUME); } EndRenderPass(); diff --git a/src/main.h b/src/main.h index 0e280fe..daf675c 100644 --- a/src/main.h +++ b/src/main.h @@ -59,6 +59,7 @@ typedef struct vxConfig { int debugVisMode; bool debugShowPointLights; + bool debugShowLightVolumes; float shadowBiasMin; float shadowBiasMax; diff --git a/src/render/program.c b/src/render/program.c index e01fdc4..34999ae 100644 --- a/src/render/program.c +++ b/src/render/program.c @@ -63,6 +63,10 @@ static DefineBlock sGenerateDefineBlock (vxConfig* conf) { }); #undef CASE + DEFINE(bool, debugShowLightVolumes, { + if (debugShowLightVolumes) { WRITE("#define DEBUG_SHOW_LIGHT_VOLUMES"); } + }); + DEFINE(int, shadowPcfTapsX, { WRITE("#define SHADOW_PCF_TAPS_X %d\n", conf->shadowPcfTapsX); }); DEFINE(int, shadowPcfTapsY, { WRITE("#define SHADOW_PCF_TAPS_Y %d\n", conf->shadowPcfTapsY); }); diff --git a/src/render/render.c b/src/render/render.c index f4248b8..bfadb01 100644 --- a/src/render/render.c +++ b/src/render/render.c @@ -7,6 +7,7 @@ PFNGLTEXTUREBARRIERPROC vxglTextureBarrier = vxglDummyTextureBarrier; int vxglMaxTextureUnits = 16; // resonable default, apparently getting GL_MAX_TEXTURE_IMAGE_UNITS can fail Material MAT_FULLSCREEN_QUAD; +Material MAT_LIGHT_VOLUME; Material MAT_DIFFUSE_WHITE; Mesh MESH_QUAD; Mesh MESH_CUBE; @@ -27,6 +28,13 @@ void InitRenderSystem() { // Generate standard materials: InitMaterial(&MAT_FULLSCREEN_QUAD); MAT_FULLSCREEN_QUAD.depth_test = false; + InitMaterial(&MAT_LIGHT_VOLUME); + MAT_LIGHT_VOLUME.depth_test = false; + MAT_LIGHT_VOLUME.cull = true; + MAT_LIGHT_VOLUME.cull_face = GL_FRONT; + MAT_LIGHT_VOLUME.blend = true; + MAT_LIGHT_VOLUME.blend_srcf = GL_ONE; + MAT_LIGHT_VOLUME.blend_dstf = GL_ONE; InitMaterial(&MAT_DIFFUSE_WHITE); MAT_DIFFUSE_WHITE.const_metallic = 0.0f; @@ -383,6 +391,7 @@ void SetRenderMaterial (RenderState* rs, Material* mat) { if (mat->blend) { glEnable(GL_BLEND); glBlendFunc(mat->blend_srcf, mat->blend_dstf); + glBlendEquation(mat->blend_func); } else { glDisable(GL_BLEND); } diff --git a/src/render/render.h b/src/render/render.h index d5ed296..4ec87ad 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -12,6 +12,7 @@ extern PFNGLTEXTUREBARRIERPROC vxglTextureBarrier; extern int vxglMaxTextureUnits; extern Material MAT_FULLSCREEN_QUAD; +extern Material MAT_LIGHT_VOLUME; extern Material MAT_DIFFUSE_WHITE; extern Mesh MESH_QUAD; extern Mesh MESH_CUBE;