diff options
| author | Andre Weissflog <floooh@gmail.com> | 2019-03-27 11:02:47 +0100 |
|---|---|---|
| committer | Andre Weissflog <floooh@gmail.com> | 2019-03-27 11:02:47 +0100 |
| commit | b454dfd67675f250fda84fb49dae7242dbe8af35 (patch) | |
| tree | 3bb0b6062c9d9671fd680108b7076c3e7a85641a | |
| parent | 59d734a000d6a91f5c7a6486f556db470853fb54 (diff) | |
sokol_gl.h: sgl_lookat()
| -rw-r--r-- | util/sokol_gl.h | 74 |
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)); |