This commit is contained in:
Kamil Nowakowski 2021-04-02 11:21:38 +02:00
commit 259992c37f
13 changed files with 196 additions and 184 deletions

2
.gitignore vendored
View File

@ -77,6 +77,7 @@ examples/splitview
examples/sharing examples/sharing
examples/triangle-opengl examples/triangle-opengl
examples/wave examples/wave
examples/windows
tests/*.app tests/*.app
tests/*.exe tests/*.exe
tests/clipboard tests/clipboard
@ -87,6 +88,7 @@ tests/gamma
tests/glfwinfo tests/glfwinfo
tests/icon tests/icon
tests/iconify tests/iconify
tests/inputlag
tests/joysticks tests/joysticks
tests/monitors tests/monitors
tests/msaa tests/msaa

View File

@ -99,7 +99,7 @@ located in the `deps/` directory.
functions functions
- [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in - [linmath.h](https://github.com/datenwolf/linmath.h) for linear algebra in
examples examples
- [Nuklear](https://github.com/vurtun/nuklear) for test and example UI - [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) for test and example UI
- [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk - [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk
The documentation is generated with [Doxygen](http://doxygen.org/) if CMake can The documentation is generated with [Doxygen](http://doxygen.org/) if CMake can
@ -159,6 +159,10 @@ information on what to include when reporting a bug.
configuration change (#1761) configuration change (#1761)
- [Win32] Bugfix: Initialization would segfault on Windows 8 (not 8.1) (#1775) - [Win32] Bugfix: Initialization would segfault on Windows 8 (not 8.1) (#1775)
- [Win32] Bugfix: Duplicate size events were not filtered (#1610) - [Win32] Bugfix: Duplicate size events were not filtered (#1610)
- [Win32] Bugfix: Full screen windows were incorrectly resized by DPI changes
(#1582)
- [Win32] Bugfix: `GLFW_SCALE_TO_MONITOR` had no effect on systems older than
Windows 10 version 1703 (#1511)
- [Cocoa] Added support for `VK_EXT_metal_surface` (#1619) - [Cocoa] Added support for `VK_EXT_metal_surface` (#1619)
- [Cocoa] Added locating the Vulkan loader at runtime in an application bundle - [Cocoa] Added locating the Vulkan loader at runtime in an application bundle
- [Cocoa] Moved main menu creation to GLFW initialization time (#1649) - [Cocoa] Moved main menu creation to GLFW initialization time (#1649)
@ -178,6 +182,11 @@ information on what to include when reporting a bug.
- [Cocoa] Bugfix: Failing to retrieve the refresh rate of built-in displays - [Cocoa] Bugfix: Failing to retrieve the refresh rate of built-in displays
could leak memory could leak memory
- [Cocoa] Bugfix: Objective-C files were compiled as C with CMake 3.19 (#1787) - [Cocoa] Bugfix: Objective-C files were compiled as C with CMake 3.19 (#1787)
- [Cocoa] Bugfix: Duplicate video modes were not filtered out (#1830)
- [Cocoa] Bugfix: Menubar was not clickable on macOS 10.15+ until it lost and
regained focus (#1648,#1802)
- [Cocoa] Bugfix: Monitor name query could segfault on macOS 11 (#1809,#1833)
- [Cocoa] Bugfix: The install name of the installed dylib was relative (#1504)
- [X11] Bugfix: The CMake files did not check for the XInput headers (#1480) - [X11] Bugfix: The CMake files did not check for the XInput headers (#1480)
- [X11] Bugfix: Key names were not updated when the keyboard layout changed - [X11] Bugfix: Key names were not updated when the keyboard layout changed
(#1462,#1528) (#1462,#1528)
@ -203,6 +212,8 @@ information on what to include when reporting a bug.
combinaitons (#1598) combinaitons (#1598)
- [X11] Bugfix: Keys pressed simultaneously with others were not always - [X11] Bugfix: Keys pressed simultaneously with others were not always
reported (#1112,#1415,#1472,#1616) reported (#1112,#1415,#1472,#1616)
- [X11] Bugfix: Some window attributes were not applied on leaving fullscreen
(#1863)
- [Wayland] Removed support for `wl_shell` (#1443) - [Wayland] Removed support for `wl_shell` (#1443)
- [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432) - [Wayland] Bugfix: The `GLFW_HAND_CURSOR` shape used the wrong image (#1432)
- [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled - [Wayland] Bugfix: `CLOCK_MONOTONIC` was not correctly enabled
@ -212,6 +223,7 @@ information on what to include when reporting a bug.
(#1463) (#1463)
- [Wayland] Bugfix: Client-Side Decorations were destroyed in the wrong worder - [Wayland] Bugfix: Client-Side Decorations were destroyed in the wrong worder
(#1798) (#1798)
- [Wayland] Bugfix: Monitors physical size could report zero (#1784,#1792)
- [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled - [POSIX] Bugfix: `CLOCK_MONOTONIC` was not correctly tested for or enabled
- [NSGL] Removed enforcement of forward-compatible flag for core contexts - [NSGL] Removed enforcement of forward-compatible flag for core contexts
- [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer - [NSGL] Bugfix: `GLFW_COCOA_RETINA_FRAMEBUFFER` had no effect on newer
@ -246,13 +258,16 @@ GLFW exists because people around the world donated their time and lent their
skills. skills.
- Bobyshev Alexander - Bobyshev Alexander
- Laurent Aphecetche
- Matt Arsenault - Matt Arsenault
- ashishgamedev
- David Avedissian - David Avedissian
- Keith Bauer - Keith Bauer
- John Bartholomew - John Bartholomew
- Coşku Baş - Coşku Baş
- Niklas Behrens - Niklas Behrens
- Andrew Belt - Andrew Belt
- Nevyn Bengtsson
- Niklas Bergström - Niklas Bergström
- Denis Bernard - Denis Bernard
- Doug Binks - Doug Binks
@ -439,6 +454,7 @@ skills.
- Frank Wille - Frank Wille
- Andy Williams - Andy Williams
- Joel Winarske - Joel Winarske
- Richard A. Wilkes
- Tatsuya Yatagawa - Tatsuya Yatagawa
- Ryogo Yoshimura - Ryogo Yoshimura
- Lukas Zanner - Lukas Zanner

151
deps/linmath.h vendored
View File

@ -1,13 +1,8 @@
#ifndef LINMATH_H #ifndef LINMATH_H
#define LINMATH_H #define LINMATH_H
#include <string.h>
#include <math.h> #include <math.h>
/* 2020-03-02 Camilla Löwy <elmindreda@elmindreda.org>
* - Added inclusion of string.h for memcpy
* - Replaced tan and acos with tanf and acosf
* - Replaced double constants with float equivalents
*/
#include <string.h> #include <string.h>
#ifdef LINMATH_NO_INLINE #ifdef LINMATH_NO_INLINE
@ -38,7 +33,7 @@ LINMATH_H_FUNC void vec##n##_scale(vec##n r, vec##n const v, float const s) \
} \ } \
LINMATH_H_FUNC float vec##n##_mul_inner(vec##n const a, vec##n const b) \ LINMATH_H_FUNC float vec##n##_mul_inner(vec##n const a, vec##n const b) \
{ \ { \
float p = 0.; \ float p = 0.f; \
int i; \ int i; \
for(i=0; i<n; ++i) \ for(i=0; i<n; ++i) \
p += b[i]*a[i]; \ p += b[i]*a[i]; \
@ -64,6 +59,12 @@ LINMATH_H_FUNC void vec##n##_max(vec##n r, vec##n const a, vec##n const b) \
int i; \ int i; \
for(i=0; i<n; ++i) \ for(i=0; i<n; ++i) \
r[i] = a[i]>b[i] ? a[i] : b[i]; \ r[i] = a[i]>b[i] ? a[i] : b[i]; \
} \
LINMATH_H_FUNC void vec##n##_dup(vec##n r, vec##n const src) \
{ \
int i; \
for(i=0; i<n; ++i) \
r[i] = src[i]; \
} }
LINMATH_H_DEFINE_VEC(2) LINMATH_H_DEFINE_VEC(2)
@ -79,13 +80,13 @@ LINMATH_H_FUNC void vec3_mul_cross(vec3 r, vec3 const a, vec3 const b)
LINMATH_H_FUNC void vec3_reflect(vec3 r, vec3 const v, vec3 const n) LINMATH_H_FUNC void vec3_reflect(vec3 r, vec3 const v, vec3 const n)
{ {
float p = 2.f*vec3_mul_inner(v, n); float p = 2.f * vec3_mul_inner(v, n);
int i; int i;
for(i=0;i<3;++i) for(i=0;i<3;++i)
r[i] = v[i] - p*n[i]; r[i] = v[i] - p*n[i];
} }
LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 a, vec4 b) LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 const a, vec4 const b)
{ {
r[0] = a[1]*b[2] - a[2]*b[1]; r[0] = a[1]*b[2] - a[2]*b[1];
r[1] = a[2]*b[0] - a[0]*b[2]; r[1] = a[2]*b[0] - a[0]*b[2];
@ -93,7 +94,7 @@ LINMATH_H_FUNC void vec4_mul_cross(vec4 r, vec4 a, vec4 b)
r[3] = 1.f; r[3] = 1.f;
} }
LINMATH_H_FUNC void vec4_reflect(vec4 r, vec4 v, vec4 n) LINMATH_H_FUNC void vec4_reflect(vec4 r, vec4 const v, vec4 const n)
{ {
float p = 2.f*vec4_mul_inner(v, n); float p = 2.f*vec4_mul_inner(v, n);
int i; int i;
@ -109,61 +110,59 @@ LINMATH_H_FUNC void mat4x4_identity(mat4x4 M)
for(j=0; j<4; ++j) for(j=0; j<4; ++j)
M[i][j] = i==j ? 1.f : 0.f; M[i][j] = i==j ? 1.f : 0.f;
} }
LINMATH_H_FUNC void mat4x4_dup(mat4x4 M, mat4x4 N) LINMATH_H_FUNC void mat4x4_dup(mat4x4 M, mat4x4 const N)
{ {
int i, j; int i;
for(i=0; i<4; ++i) for(i=0; i<4; ++i)
for(j=0; j<4; ++j) vec4_dup(M[i], N[i]);
M[i][j] = N[i][j];
} }
LINMATH_H_FUNC void mat4x4_row(vec4 r, mat4x4 M, int i) LINMATH_H_FUNC void mat4x4_row(vec4 r, mat4x4 const M, int i)
{ {
int k; int k;
for(k=0; k<4; ++k) for(k=0; k<4; ++k)
r[k] = M[k][i]; r[k] = M[k][i];
} }
LINMATH_H_FUNC void mat4x4_col(vec4 r, mat4x4 M, int i) LINMATH_H_FUNC void mat4x4_col(vec4 r, mat4x4 const M, int i)
{ {
int k; int k;
for(k=0; k<4; ++k) for(k=0; k<4; ++k)
r[k] = M[i][k]; r[k] = M[i][k];
} }
LINMATH_H_FUNC void mat4x4_transpose(mat4x4 M, mat4x4 N) LINMATH_H_FUNC void mat4x4_transpose(mat4x4 M, mat4x4 const N)
{ {
// Note: if M and N are the same, the user has to
// explicitly make a copy of M and set it to N.
int i, j; int i, j;
for(j=0; j<4; ++j) for(j=0; j<4; ++j)
for(i=0; i<4; ++i) for(i=0; i<4; ++i)
M[i][j] = N[j][i]; M[i][j] = N[j][i];
} }
LINMATH_H_FUNC void mat4x4_add(mat4x4 M, mat4x4 a, mat4x4 b) LINMATH_H_FUNC void mat4x4_add(mat4x4 M, mat4x4 const a, mat4x4 const b)
{ {
int i; int i;
for(i=0; i<4; ++i) for(i=0; i<4; ++i)
vec4_add(M[i], a[i], b[i]); vec4_add(M[i], a[i], b[i]);
} }
LINMATH_H_FUNC void mat4x4_sub(mat4x4 M, mat4x4 a, mat4x4 b) LINMATH_H_FUNC void mat4x4_sub(mat4x4 M, mat4x4 const a, mat4x4 const b)
{ {
int i; int i;
for(i=0; i<4; ++i) for(i=0; i<4; ++i)
vec4_sub(M[i], a[i], b[i]); vec4_sub(M[i], a[i], b[i]);
} }
LINMATH_H_FUNC void mat4x4_scale(mat4x4 M, mat4x4 a, float k) LINMATH_H_FUNC void mat4x4_scale(mat4x4 M, mat4x4 const a, float k)
{ {
int i; int i;
for(i=0; i<4; ++i) for(i=0; i<4; ++i)
vec4_scale(M[i], a[i], k); vec4_scale(M[i], a[i], k);
} }
LINMATH_H_FUNC void mat4x4_scale_aniso(mat4x4 M, mat4x4 a, float x, float y, float z) LINMATH_H_FUNC void mat4x4_scale_aniso(mat4x4 M, mat4x4 const a, float x, float y, float z)
{ {
int i;
vec4_scale(M[0], a[0], x); vec4_scale(M[0], a[0], x);
vec4_scale(M[1], a[1], y); vec4_scale(M[1], a[1], y);
vec4_scale(M[2], a[2], z); vec4_scale(M[2], a[2], z);
for(i = 0; i < 4; ++i) { vec4_dup(M[3], a[3]);
M[3][i] = a[3][i];
}
} }
LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b) LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 const a, mat4x4 const b)
{ {
mat4x4 temp; mat4x4 temp;
int k, r, c; int k, r, c;
@ -174,7 +173,7 @@ LINMATH_H_FUNC void mat4x4_mul(mat4x4 M, mat4x4 a, mat4x4 b)
} }
mat4x4_dup(M, temp); mat4x4_dup(M, temp);
} }
LINMATH_H_FUNC void mat4x4_mul_vec4(vec4 r, mat4x4 M, vec4 v) LINMATH_H_FUNC void mat4x4_mul_vec4(vec4 r, mat4x4 const M, vec4 const v)
{ {
int i, j; int i, j;
for(j=0; j<4; ++j) { for(j=0; j<4; ++j) {
@ -200,13 +199,13 @@ LINMATH_H_FUNC void mat4x4_translate_in_place(mat4x4 M, float x, float y, float
M[3][i] += vec4_mul_inner(r, t); M[3][i] += vec4_mul_inner(r, t);
} }
} }
LINMATH_H_FUNC void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 a, vec3 b) LINMATH_H_FUNC void mat4x4_from_vec3_mul_outer(mat4x4 M, vec3 const a, vec3 const b)
{ {
int i, j; int i, j;
for(i=0; i<4; ++i) for(j=0; j<4; ++j) for(i=0; i<4; ++i) for(j=0; j<4; ++j)
M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f; M[i][j] = i<3 && j<3 ? a[i] * b[j] : 0.f;
} }
LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z, float angle) LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 const M, float x, float y, float z, float angle)
{ {
float s = sinf(angle); float s = sinf(angle);
float c = cosf(angle); float c = cosf(angle);
@ -234,13 +233,13 @@ LINMATH_H_FUNC void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z,
mat4x4_add(T, T, C); mat4x4_add(T, T, C);
mat4x4_add(T, T, S); mat4x4_add(T, T, S);
T[3][3] = 1.; T[3][3] = 1.f;
mat4x4_mul(R, M, T); mat4x4_mul(R, M, T);
} else { } else {
mat4x4_dup(R, M); mat4x4_dup(R, M);
} }
} }
LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle) LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 const M, float angle)
{ {
float s = sinf(angle); float s = sinf(angle);
float c = cosf(angle); float c = cosf(angle);
@ -252,7 +251,7 @@ LINMATH_H_FUNC void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle)
}; };
mat4x4_mul(Q, M, R); mat4x4_mul(Q, M, R);
} }
LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle) LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 const M, float angle)
{ {
float s = sinf(angle); float s = sinf(angle);
float c = cosf(angle); float c = cosf(angle);
@ -264,7 +263,7 @@ LINMATH_H_FUNC void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle)
}; };
mat4x4_mul(Q, M, R); mat4x4_mul(Q, M, R);
} }
LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle) LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 const M, float angle)
{ {
float s = sinf(angle); float s = sinf(angle);
float c = cosf(angle); float c = cosf(angle);
@ -276,7 +275,7 @@ LINMATH_H_FUNC void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle)
}; };
mat4x4_mul(Q, M, R); mat4x4_mul(Q, M, R);
} }
LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 M) LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 const M)
{ {
float s[6]; float s[6];
float c[6]; float c[6];
@ -317,10 +316,10 @@ LINMATH_H_FUNC void mat4x4_invert(mat4x4 T, mat4x4 M)
T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet; T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet;
T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet; T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet;
} }
LINMATH_H_FUNC void mat4x4_orthonormalize(mat4x4 R, mat4x4 M) LINMATH_H_FUNC void mat4x4_orthonormalize(mat4x4 R, mat4x4 const M)
{ {
mat4x4_dup(R, M); mat4x4_dup(R, M);
float s = 1.; float s = 1.f;
vec3 h; vec3 h;
vec3_norm(R[2], R[2]); vec3_norm(R[2], R[2]);
@ -398,7 +397,7 @@ LINMATH_H_FUNC void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, floa
m[3][2] = -((2.f * f * n) / (f - n)); m[3][2] = -((2.f * f * n) / (f - n));
m[3][3] = 0.f; m[3][3] = 0.f;
} }
LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up) LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 const eye, vec3 const center, vec3 const up)
{ {
/* Adapted from Android's OpenGL Matrix.java. */ /* Adapted from Android's OpenGL Matrix.java. */
/* See the OpenGL GLUT documentation for gluLookAt for a description */ /* See the OpenGL GLUT documentation for gluLookAt for a description */
@ -441,24 +440,18 @@ LINMATH_H_FUNC void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up)
} }
typedef float quat[4]; typedef float quat[4];
#define quat_add vec4_add
#define quat_sub vec4_sub
#define quat_norm vec4_norm
#define quat_scale vec4_scale
#define quat_mul_inner vec4_mul_inner
LINMATH_H_FUNC void quat_identity(quat q) LINMATH_H_FUNC void quat_identity(quat q)
{ {
q[0] = q[1] = q[2] = 0.f; q[0] = q[1] = q[2] = 0.f;
q[3] = 1.f; q[3] = 1.f;
} }
LINMATH_H_FUNC void quat_add(quat r, quat a, quat b) LINMATH_H_FUNC void quat_mul(quat r, quat const p, quat const q)
{
int i;
for(i=0; i<4; ++i)
r[i] = a[i] + b[i];
}
LINMATH_H_FUNC void quat_sub(quat r, quat a, quat b)
{
int i;
for(i=0; i<4; ++i)
r[i] = a[i] - b[i];
}
LINMATH_H_FUNC void quat_mul(quat r, quat p, quat q)
{ {
vec3 w; vec3 w;
vec3_mul_cross(r, p, q); vec3_mul_cross(r, p, q);
@ -468,37 +461,22 @@ LINMATH_H_FUNC void quat_mul(quat r, quat p, quat q)
vec3_add(r, r, w); vec3_add(r, r, w);
r[3] = p[3]*q[3] - vec3_mul_inner(p, q); r[3] = p[3]*q[3] - vec3_mul_inner(p, q);
} }
LINMATH_H_FUNC void quat_scale(quat r, quat v, float s) LINMATH_H_FUNC void quat_conj(quat r, quat const q)
{
int i;
for(i=0; i<4; ++i)
r[i] = v[i] * s;
}
LINMATH_H_FUNC float quat_inner_product(quat a, quat b)
{
float p = 0.f;
int i;
for(i=0; i<4; ++i)
p += b[i]*a[i];
return p;
}
LINMATH_H_FUNC void quat_conj(quat r, quat q)
{ {
int i; int i;
for(i=0; i<3; ++i) for(i=0; i<3; ++i)
r[i] = -q[i]; r[i] = -q[i];
r[3] = q[3]; r[3] = q[3];
} }
LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 axis) { LINMATH_H_FUNC void quat_rotate(quat r, float angle, vec3 const axis) {
vec3 v; vec3 axis_norm;
vec3_scale(v, axis, sinf(angle / 2)); vec3_norm(axis_norm, axis);
int i; float s = sinf(angle / 2);
for(i=0; i<3; ++i) float c = cosf(angle / 2);
r[i] = v[i]; vec3_scale(r, axis_norm, s);
r[3] = cosf(angle / 2); r[3] = c;
} }
#define quat_norm vec4_norm LINMATH_H_FUNC void quat_mul_vec3(vec3 r, quat const q, vec3 const v)
LINMATH_H_FUNC void quat_mul_vec3(vec3 r, quat q, vec3 v)
{ {
/* /*
* Method by Fabian 'ryg' Giessen (of Farbrausch) * Method by Fabian 'ryg' Giessen (of Farbrausch)
@ -518,7 +496,7 @@ v' = v + q.w * t + cross(q.xyz, t)
vec3_add(r, v, t); vec3_add(r, v, t);
vec3_add(r, r, u); vec3_add(r, r, u);
} }
LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat q) LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat const q)
{ {
float a = q[3]; float a = q[3];
float b = q[0]; float b = q[0];
@ -548,18 +526,21 @@ LINMATH_H_FUNC void mat4x4_from_quat(mat4x4 M, quat q)
M[3][3] = 1.f; M[3][3] = 1.f;
} }
LINMATH_H_FUNC void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q) LINMATH_H_FUNC void mat4x4o_mul_quat(mat4x4 R, mat4x4 const M, quat const q)
{ {
/* XXX: The way this is written only works for othogonal matrices. */ /* XXX: The way this is written only works for orthogonal matrices. */
/* TODO: Take care of non-orthogonal case. */ /* TODO: Take care of non-orthogonal case. */
quat_mul_vec3(R[0], q, M[0]); quat_mul_vec3(R[0], q, M[0]);
quat_mul_vec3(R[1], q, M[1]); quat_mul_vec3(R[1], q, M[1]);
quat_mul_vec3(R[2], q, M[2]); quat_mul_vec3(R[2], q, M[2]);
R[3][0] = R[3][1] = R[3][2] = 0.f; R[3][0] = R[3][1] = R[3][2] = 0.f;
R[3][3] = 1.f; R[0][3] = M[0][3];
R[1][3] = M[1][3];
R[2][3] = M[2][3];
R[3][3] = M[3][3]; // typically 1.0, but here we make it general
} }
LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 M) LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 const M)
{ {
float r=0.f; float r=0.f;
int i; int i;
@ -589,7 +570,7 @@ LINMATH_H_FUNC void quat_from_mat4x4(quat q, mat4x4 M)
q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r); q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r);
} }
LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 M, vec2 _a, vec2 _b, float s) LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 const M, vec2 const _a, vec2 const _b, float s)
{ {
vec2 a; memcpy(a, _a, sizeof(a)); vec2 a; memcpy(a, _a, sizeof(a));
vec2 b; memcpy(b, _b, sizeof(b)); vec2 b; memcpy(b, _b, sizeof(b));
@ -597,14 +578,14 @@ LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 M, vec2 _a, vec2 _b, float s
float z_a = 0.; float z_a = 0.;
float z_b = 0.; float z_b = 0.;
if(vec2_len(a) < 1.f) { if(vec2_len(a) < 1.) {
z_a = sqrtf(1.f - vec2_mul_inner(a, a)); z_a = sqrtf(1. - vec2_mul_inner(a, a));
} else { } else {
vec2_norm(a, a); vec2_norm(a, a);
} }
if(vec2_len(b) < 1.f) { if(vec2_len(b) < 1.) {
z_b = sqrtf(1.f - vec2_mul_inner(b, b)); z_b = sqrtf(1. - vec2_mul_inner(b, b));
} else { } else {
vec2_norm(b, b); vec2_norm(b, b);
} }
@ -615,7 +596,7 @@ LINMATH_H_FUNC void mat4x4_arcball(mat4x4 R, mat4x4 M, vec2 _a, vec2 _b, float s
vec3 c_; vec3 c_;
vec3_mul_cross(c_, a_, b_); vec3_mul_cross(c_, a_, b_);
float const angle = acosf(vec3_mul_inner(a_, b_)) * s; float const angle = acos(vec3_mul_inner(a_, b_)) * s;
mat4x4_rotate(R, M, c_[0], c_[1], c_[2], angle); mat4x4_rotate(R, M, c_[0], c_[1], c_[2], angle);
} }
#endif #endif

View File

@ -1074,13 +1074,6 @@ VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = YES ALPHABETICAL_INDEX = YES
# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
# which the alphabetical index list will be split.
# Minimum value: 1, maximum value: 20, default value: 5.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
COLS_IN_ALPHA_INDEX = 5
# In case all classes in a project start with a common prefix, all classes will # In case all classes in a project start with a common prefix, all classes will
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
# can be used to specify a prefix (or a list of prefixes) that should be ignored # can be used to specify a prefix (or a list of prefixes) that should be ignored

View File

@ -37,7 +37,7 @@ elseif (_GLFW_OSMESA)
endif() endif()
if (_GLFW_X11 OR _GLFW_WAYLAND) if (_GLFW_X11 OR _GLFW_WAYLAND)
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c) target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c)
else() else()
target_sources(glfw PRIVATE null_joystick.h null_joystick.c) target_sources(glfw PRIVATE null_joystick.h null_joystick.c)
@ -120,7 +120,7 @@ endif()
# Make GCC warn about declarations that VS 2010 and 2012 won't accept for all # Make GCC warn about declarations that VS 2010 and 2012 won't accept for all
# source files that VS will build (Clang ignores this because we set -std=c99) # source files that VS will build (Clang ignores this because we set -std=c99)
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
set_source_files_properties(context.c init.c input.c monitor.c vulkan.c set_source_files_properties(context.c init.c input.c monitor.c vulkan.c
window.c win32_init.c win32_joystick.c window.c win32_init.c win32_joystick.c
win32_monitor.c win32_time.c win32_thread.c win32_monitor.c win32_time.c win32_thread.c
@ -130,11 +130,11 @@ if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
endif() endif()
# Enable a reasonable set of warnings # Enable a reasonable set of warnings
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR CMAKE_C_COMPILER_ID STREQUAL "Clang" OR
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang") CMAKE_C_COMPILER_ID STREQUAL "AppleClang")
if ("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC") if (CMAKE_C_SIMULATE_ID STREQUAL "MSVC")
# Tell Clang-CL that this is a Clang flag # Tell Clang-CL that this is a Clang flag
target_compile_options(glfw PRIVATE "/clang:-Wall") target_compile_options(glfw PRIVATE "/clang:-Wall")
else() else()
@ -203,9 +203,6 @@ if (BUILD_SHARED_LIBS)
endif() endif()
target_compile_definitions(glfw INTERFACE GLFW_DLL) target_compile_definitions(glfw INTERFACE GLFW_DLL)
elseif (APPLE)
set_target_properties(glfw PROPERTIES
INSTALL_NAME_DIR "${CMAKE_INSTALL_LIBDIR}")
endif() endif()
if (MINGW) if (MINGW)

View File

@ -428,9 +428,6 @@ static GLFWbool initializeTIS(void)
{ {
if (_glfw.hints.init.ns.menubar) if (_glfw.hints.init.ns.menubar)
{ {
// In case we are unbundled, make us a proper UI application
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
// Menu bar setup must go between sharedApplication and finishLaunching // Menu bar setup must go between sharedApplication and finishLaunching
// in order to properly emulate the behavior of NSApplicationMain // in order to properly emulate the behavior of NSApplicationMain
@ -557,6 +554,10 @@ int _glfwPlatformInit(void)
if (![[NSRunningApplication currentApplication] isFinishedLaunching]) if (![[NSRunningApplication currentApplication] isFinishedLaunching])
[NSApp run]; [NSApp run];
// In case we are unbundled, make us a proper UI application
if (_glfw.hints.init.ns.menubar)
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
return GLFW_TRUE; return GLFW_TRUE;
} // autoreleasepool } // autoreleasepool

View File

@ -39,8 +39,21 @@
// Get the name of the specified display, or NULL // Get the name of the specified display, or NULL
// //
static char* getDisplayName(CGDirectDisplayID displayID) static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
{ {
// IOKit doesn't work on Apple Silicon anymore
// Luckily, 10.15 introduced -[NSScreen localizedName].
// Use it if available, and fall back to IOKit otherwise.
if (screen)
{
if ([screen respondsToSelector:@selector(localizedName)])
{
NSString* name = [screen valueForKey:@"localizedName"];
if (name)
return _glfw_strdup([name UTF8String]);
}
}
io_iterator_t it; io_iterator_t it;
io_service_t service; io_service_t service;
CFDictionaryRef info; CFDictionaryRef info;
@ -209,31 +222,6 @@ static void endFadeReservation(CGDisplayFadeReservationToken token)
} }
} }
// Finds and caches the NSScreen corresponding to the specified monitor
//
static GLFWbool refreshMonitorScreen(_GLFWmonitor* monitor)
{
if (monitor->ns.screen)
return GLFW_TRUE;
for (NSScreen* screen in [NSScreen screens])
{
NSNumber* displayID = [screen deviceDescription][@"NSScreenNumber"];
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
if (monitor->ns.unitNumber == CGDisplayUnitNumber([displayID unsignedIntValue]))
{
monitor->ns.screen = screen;
return GLFW_TRUE;
}
}
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to find a screen for monitor");
return GLFW_FALSE;
}
// Returns the display refresh rate queried from the I/O registry // Returns the display refresh rate queried from the I/O registry
// //
static double getFallbackRefreshRate(CGDirectDisplayID displayID) static double getFallbackRefreshRate(CGDirectDisplayID displayID)
@ -334,27 +322,46 @@ void _glfwPollMonitorsNS(void)
if (CGDisplayIsAsleep(displays[i])) if (CGDisplayIsAsleep(displays[i]))
continue; continue;
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
NSScreen* screen = nil;
for (screen in [NSScreen screens])
{
NSNumber* screenNumber = [screen deviceDescription][@"NSScreenNumber"];
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
if (CGDisplayUnitNumber([screenNumber unsignedIntValue]) == unitNumber)
break;
}
// HACK: Compare unit numbers instead of display IDs to work around // HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics // display replacement on machines with automatic graphics
// switching // switching
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]); uint32_t j;
for (uint32_t j = 0; j < disconnectedCount; j++) for (j = 0; j < disconnectedCount; j++)
{ {
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber) if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
{ {
disconnected[j]->ns.screen = screen;
disconnected[j] = NULL; disconnected[j] = NULL;
break; break;
} }
} }
if (j < disconnectedCount)
continue;
const CGSize size = CGDisplayScreenSize(displays[i]); const CGSize size = CGDisplayScreenSize(displays[i]);
char* name = getDisplayName(displays[i]); char* name = getMonitorName(displays[i], screen);
if (!name) if (!name)
name = _glfw_strdup("Unknown"); name = _glfw_strdup("Unknown");
_GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height); _GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height);
monitor->ns.displayID = displays[i]; monitor->ns.displayID = displays[i];
monitor->ns.unitNumber = unitNumber; monitor->ns.unitNumber = unitNumber;
monitor->ns.screen = screen;
free(name); free(name);
@ -463,8 +470,11 @@ void _glfwPlatformGetMonitorContentScale(_GLFWmonitor* monitor,
{ {
@autoreleasepool { @autoreleasepool {
if (!refreshMonitorScreen(monitor)) if (!monitor->ns.screen)
return; {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Cannot query content scale without screen");
}
const NSRect points = [monitor->ns.screen frame]; const NSRect points = [monitor->ns.screen frame];
const NSRect pixels = [monitor->ns.screen convertRectToBacking:points]; const NSRect pixels = [monitor->ns.screen convertRectToBacking:points];
@ -483,8 +493,11 @@ void _glfwPlatformGetMonitorWorkarea(_GLFWmonitor* monitor,
{ {
@autoreleasepool { @autoreleasepool {
if (!refreshMonitorScreen(monitor)) if (!monitor->ns.screen)
return; {
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Cannot query workarea without screen");
}
const NSRect frameRect = [monitor->ns.screen visibleFrame]; const NSRect frameRect = [monitor->ns.screen visibleFrame];
@ -527,7 +540,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* count)
} }
// Skip duplicate modes // Skip duplicate modes
if (i < *count) if (j < *count)
continue; continue;
(*count)++; (*count)++;

View File

@ -353,9 +353,9 @@ struct _GLFWcontext
int robustness; int robustness;
int release; int release;
PFNGLGETSTRINGIPROC GetStringi; PFNGLGETSTRINGIPROC GetStringi;
PFNGLGETINTEGERVPROC GetIntegerv; PFNGLGETINTEGERVPROC GetIntegerv;
PFNGLGETSTRINGPROC GetString; PFNGLGETSTRINGPROC GetString;
_GLFWmakecontextcurrentfun makeCurrent; _GLFWmakecontextcurrentfun makeCurrent;
_GLFWswapbuffersfun swapBuffers; _GLFWswapbuffersfun swapBuffers;
@ -408,23 +408,23 @@ struct _GLFWwindow
_GLFWcontext context; _GLFWcontext context;
struct { struct {
GLFWwindowposfun pos; GLFWwindowposfun pos;
GLFWwindowsizefun size; GLFWwindowsizefun size;
GLFWwindowclosefun close; GLFWwindowclosefun close;
GLFWwindowrefreshfun refresh; GLFWwindowrefreshfun refresh;
GLFWwindowfocusfun focus; GLFWwindowfocusfun focus;
GLFWwindowiconifyfun iconify; GLFWwindowiconifyfun iconify;
GLFWwindowmaximizefun maximize; GLFWwindowmaximizefun maximize;
GLFWframebuffersizefun fbsize; GLFWframebuffersizefun fbsize;
GLFWwindowcontentscalefun scale; GLFWwindowcontentscalefun scale;
GLFWmousebuttonfun mouseButton; GLFWmousebuttonfun mouseButton;
GLFWcursorposfun cursorPos; GLFWcursorposfun cursorPos;
GLFWcursorenterfun cursorEnter; GLFWcursorenterfun cursorEnter;
GLFWscrollfun scroll; GLFWscrollfun scroll;
GLFWkeyfun key; GLFWkeyfun key;
GLFWcharfun character; GLFWcharfun character;
GLFWcharmodsfun charmods; GLFWcharmodsfun charmods;
GLFWdropfun drop; GLFWdropfun drop;
} callbacks; } callbacks;
// This is defined in the window API's platform.h // This is defined in the window API's platform.h

View File

@ -39,6 +39,10 @@ static const GUID _glfw_GUID_DEVINTERFACE_HID =
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG) #if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
#if defined(_GLFW_BUILD_DLL)
#warning "These symbols must be exported by the executable and have no effect in a DLL"
#endif
// Executables (but not DLLs) exporting this symbol with this value will be // Executables (but not DLLs) exporting this symbol with this value will be
// automatically directed to the high-performance GPU on Nvidia Optimus systems // automatically directed to the high-performance GPU on Nvidia Optimus systems
// with up-to-date drivers // with up-to-date drivers
@ -614,7 +618,9 @@ void _glfwPlatformTerminate(void)
const char* _glfwPlatformGetVersionString(void) const char* _glfwPlatformGetVersionString(void)
{ {
return _GLFW_VERSION_NUMBER " Win32 WGL EGL OSMesa" return _GLFW_VERSION_NUMBER " Win32 WGL EGL OSMesa"
#if defined(__MINGW32__) #if defined(__MINGW64_VERSION_MAJOR)
" MinGW-w64"
#elif defined(__MINGW32__)
" MinGW" " MinGW"
#elif defined(_MSC_VER) #elif defined(_MSC_VER)
" VisualC" " VisualC"

View File

@ -501,7 +501,17 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
case WM_NCCREATE: case WM_NCCREATE:
{ {
if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32()) if (_glfwIsWindows10AnniversaryUpdateOrGreaterWin32())
EnableNonClientDpiScaling(hWnd); {
const CREATESTRUCTW* cs = (const CREATESTRUCTW*) lParam;
const _GLFWwndconfig* wndconfig = cs->lpCreateParams;
// On per-monitor DPI aware V1 systems, only enable
// non-client scaling for windows that scale the client area
// We need WM_GETDPISCALEDSIZE from V2 to keep the client
// area static when the non-client area is scaled
if (wndconfig && wndconfig->scaleToMonitor)
EnableNonClientDpiScaling(hWnd);
}
break; break;
} }
@ -1138,9 +1148,11 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
const float xscale = HIWORD(wParam) / (float) USER_DEFAULT_SCREEN_DPI; const float xscale = HIWORD(wParam) / (float) USER_DEFAULT_SCREEN_DPI;
const float yscale = LOWORD(wParam) / (float) USER_DEFAULT_SCREEN_DPI; const float yscale = LOWORD(wParam) / (float) USER_DEFAULT_SCREEN_DPI;
// Only apply the suggested size if the OS is new enough to have // Resize windowed mode windows that either permit rescaling or that
// sent a WM_GETDPISCALEDSIZE before this // need it to compensate for non-client area scaling
if (_glfwIsWindows10CreatorsUpdateOrGreaterWin32()) if (!window->monitor &&
(window->win32.scaleToMonitor ||
_glfwIsWindows10CreatorsUpdateOrGreaterWin32()))
{ {
RECT* suggested = (RECT*) lParam; RECT* suggested = (RECT*) lParam;
SetWindowPos(window->win32.handle, HWND_TOP, SetWindowPos(window->win32.handle, HWND_TOP,
@ -1255,7 +1267,7 @@ static int createNativeWindow(_GLFWwindow* window,
wndconfig->parent ? wndconfig->parent->win32.handle : NULL, wndconfig->parent ? wndconfig->parent->win32.handle : NULL,
NULL, // No window menu NULL, // No window menu
GetModuleHandleW(NULL), GetModuleHandleW(NULL),
NULL); (LPVOID) wndconfig);
free(wideTitle); free(wideTitle);

View File

@ -901,27 +901,18 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
window->autoIconify = value; window->autoIconify = value;
else if (attrib == GLFW_RESIZABLE) else if (attrib == GLFW_RESIZABLE)
{ {
if (window->resizable == value)
return;
window->resizable = value; window->resizable = value;
if (!window->monitor) if (!window->monitor)
_glfwPlatformSetWindowResizable(window, value); _glfwPlatformSetWindowResizable(window, value);
} }
else if (attrib == GLFW_DECORATED) else if (attrib == GLFW_DECORATED)
{ {
if (window->decorated == value)
return;
window->decorated = value; window->decorated = value;
if (!window->monitor) if (!window->monitor)
_glfwPlatformSetWindowDecorated(window, value); _glfwPlatformSetWindowDecorated(window, value);
} }
else if (attrib == GLFW_FLOATING) else if (attrib == GLFW_FLOATING)
{ {
if (window->floating == value)
return;
window->floating = value; window->floating = value;
if (!window->monitor) if (!window->monitor)
_glfwPlatformSetWindowFloating(window, value); _glfwPlatformSetWindowFloating(window, value);
@ -930,9 +921,6 @@ GLFWAPI void glfwSetWindowAttrib(GLFWwindow* handle, int attrib, int value)
window->focusOnShow = value; window->focusOnShow = value;
else if (attrib == GLFW_MOUSE_PASSTHROUGH) else if (attrib == GLFW_MOUSE_PASSTHROUGH)
{ {
if (window->mousePassthrough == value)
return;
window->mousePassthrough = value; window->mousePassthrough = value;
_glfwPlatformSetWindowMousePassthrough(window, value); _glfwPlatformSetWindowMousePassthrough(window, value);
} }

View File

@ -81,22 +81,21 @@ static void outputHandleMode(void* data,
monitor->modes[monitor->modeCount - 1] = mode; monitor->modes[monitor->modeCount - 1] = mode;
if (flags & WL_OUTPUT_MODE_CURRENT) if (flags & WL_OUTPUT_MODE_CURRENT)
{
monitor->wl.currentMode = monitor->modeCount - 1; monitor->wl.currentMode = monitor->modeCount - 1;
if (monitor->widthMM <= 0 || monitor->heightMM <= 0)
{
// If Wayland does not provide a physical size, assume the default 96 DPI
monitor->widthMM = (int) (width * 25.4f / 96.f);
monitor->heightMM = (int) (height * 25.4f / 96.f);
}
}
} }
static void outputHandleDone(void* data, struct wl_output* output) static void outputHandleDone(void* data, struct wl_output* output)
{ {
struct _GLFWmonitor *monitor = data; struct _GLFWmonitor *monitor = data;
if (monitor->widthMM <= 0 || monitor->heightMM <= 0)
{
// If Wayland does not provide a physical size, assume the default 96 DPI
const GLFWvidmode* mode = &monitor->modes[monitor->wl.currentMode];
monitor->widthMM = (int) (mode->width * 25.4f / 96.f);
monitor->heightMM = (int) (mode->height * 25.4f / 96.f);
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST); _glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
} }

View File

@ -2485,7 +2485,11 @@ void _glfwPlatformSetWindowMonitor(_GLFWwindow* window,
} }
if (window->monitor) if (window->monitor)
{
_glfwPlatformSetWindowDecorated(window, window->decorated);
_glfwPlatformSetWindowFloating(window, window->floating);
releaseMonitor(window); releaseMonitor(window);
}
_glfwInputWindowMonitor(window, monitor); _glfwInputWindowMonitor(window, monitor);
updateNormalHints(window, width, height); updateNormalHints(window, width, height);