aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndre Weissflog <floooh@gmail.com>2019-03-27 11:02:47 +0100
committerAndre Weissflog <floooh@gmail.com>2019-03-27 11:02:47 +0100
commitb454dfd67675f250fda84fb49dae7242dbe8af35 (patch)
tree3bb0b6062c9d9671fd680108b7076c3e7a85641a
parent59d734a000d6a91f5c7a6486f556db470853fb54 (diff)
sokol_gl.h: sgl_lookat()
-rw-r--r--util/sokol_gl.h74
1 files changed, 61 insertions, 13 deletions
diff --git a/util/sokol_gl.h b/util/sokol_gl.h
index 0478f27f..1a31b8c7 100644
--- a/util/sokol_gl.h
+++ b/util/sokol_gl.h
@@ -609,7 +609,6 @@ static sg_pipeline _sgl_pipeline(uint16_t state_bits) {
return _sgl.pip[pip_index];
}
-/* initialize identity matrix */
static void _sgl_identity(_sgl_matrix_t* m) {
for (int c = 0; c < 4; c++) {
for (int r = 0; r < 4; r++) {
@@ -618,7 +617,16 @@ static void _sgl_identity(_sgl_matrix_t* m) {
}
}
-/* multiply matrices, can be in-place if p and a are identical */
+static void _sgl_transpose(_sgl_matrix_t* dst, const _sgl_matrix_t* m) {
+ SOKOL_ASSERT(dst != m);
+ for (int c = 0; c < 4; c++) {
+ for (int r = 0; r < 4; r++) {
+ dst->v[r][c] = m->v[c][r];
+ }
+ }
+}
+
+/* _sgl_rotate, _sgl_frustum, _sgl_ortho from MESA m_matric.c */
static void _sgl_matmul4(_sgl_matrix_t* p, const _sgl_matrix_t* a, const _sgl_matrix_t* b) {
for (int r = 0; r < 4; r++) {
float ai0=a->v[0][r], ai1=a->v[1][r], ai2=a->v[2][r], ai3=a->v[3][r];
@@ -629,21 +637,10 @@ static void _sgl_matmul4(_sgl_matrix_t* p, const _sgl_matrix_t* a, const _sgl_ma
}
}
-/* in-place matrix multiplication */
static void _sgl_mul(_sgl_matrix_t* dst, const _sgl_matrix_t* m) {
_sgl_matmul4(dst, dst, m);
}
-/* return transposed matrix */
-static void _sgl_transpose(_sgl_matrix_t* dst, const _sgl_matrix_t* m) {
- SOKOL_ASSERT(dst != m);
- for (int c = 0; c < 4; c++) {
- for (int r = 0; r < 4; r++) {
- dst->v[r][c] = m->v[c][r];
- }
- }
-}
-
static void _sgl_rotate(_sgl_matrix_t* dst, float a, float x, float y, float z) {
float s = sinf(a);
@@ -738,6 +735,7 @@ static void _sgl_ortho(_sgl_matrix_t* dst, float left, float right, float bottom
_sgl_mul(dst, &m);
}
+/* _sgl_perspective, _sgl_lookat from Regal project.c */
static void _sgl_perspective(_sgl_matrix_t* dst, float fovy, float aspect, float near, float far) {
float sine = sinf(fovy / 2.0f);
float delta_z = far - near;
@@ -756,6 +754,51 @@ static void _sgl_perspective(_sgl_matrix_t* dst, float fovy, float aspect, float
_sgl_mul(dst, &m);
}
+static void _sgl_normalize(float v[3]) {
+ float r = sqrtf(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
+ if (r == 0.0f) {
+ return;
+ }
+ v[0] /= r;
+ v[1] /= r;
+ v[2] /= r;
+}
+
+static void _sgl_cross(float v1[3], float v2[3], float res[3]) {
+ res[0] = v1[1]*v2[2] - v1[2]*v2[1];
+ res[1] = v1[2]*v2[0] - v1[0]*v2[2];
+ res[2] = v1[0]*v2[1] - v1[1]*v2[0];
+}
+
+static void _sgl_lookat(_sgl_matrix_t* dst,
+ float eye_x, float eye_y, float eye_z,
+ float center_x, float center_y, float center_z,
+ float up_x, float up_y, float up_z)
+{
+ float fwd[3], side[3], up[3];
+
+ fwd[0] = center_x - eye_x; fwd[1] = center_y - eye_y; fwd[2] = center_z - eye_z;
+ up[0] = up_x; up[1] = up_y; up[2] = up_z;
+ _sgl_normalize(fwd);
+ _sgl_cross(fwd, up, side);
+ _sgl_normalize(side);
+ _sgl_cross(side, fwd, up);
+
+ _sgl_matrix_t m;
+ _sgl_identity(&m);
+ m.v[0][0] = side[0];
+ m.v[1][0] = side[1];
+ m.v[2][0] = side[2];
+ m.v[0][1] = up[0];
+ m.v[1][1] = up[1];
+ m.v[2][1] = up[2];
+ m.v[0][2] = -fwd[0];
+ m.v[1][2] = -fwd[1];
+ m.v[2][2] = -fwd[2];
+ _sgl_mul(dst, &m);
+ _sgl_translate(dst, -eye_x, -eye_y, -eye_z);
+}
+
/* current top-of-stack projection matrix */
static inline _sgl_matrix_t* _sgl_matrix_projection(void) {
return &_sgl.matrix_stack[SGL_MATRIXMODE_PROJECTION][_sgl.top_of_stack[SGL_MATRIXMODE_PROJECTION]];
@@ -1265,6 +1308,11 @@ SOKOL_API_IMPL void sgl_perspective(float fov_y, float aspect, float z_near, flo
_sgl_perspective(_sgl_matrix(), fov_y, aspect, z_near, z_far);
}
+SOKOL_API_IMPL void sgl_lookat(float eye_x, float eye_y, float eye_z, float center_x, float center_y, float center_z, float up_x, float up_y, float up_z) {
+ SOKOL_ASSERT(_SGL_INIT_COOKIE == _sgl.init_cookie);
+ _sgl_lookat(_sgl_matrix(), eye_x, eye_y, eye_z, center_x, center_y, center_z, up_x, up_y, up_z);
+}
+
SOKOL_API_DECL void sgl_push_matrix(void) {
SOKOL_ASSERT(_SGL_INIT_COOKIE == _sgl.init_cookie);
SOKOL_ASSERT((_sgl.cur_matrix_mode >= 0) && (_sgl.cur_matrix_mode < SGL_NUM_MATRIXMODES));