fixed to fix and some more
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Geometry rendering.
|
||||
*/
|
||||
|
||||
#ifndef COM_GEM_H
|
||||
#define COM_GEM_H
|
||||
|
||||
#include "mat.h"
|
||||
#include <stdint.h>
|
||||
|
||||
/* Projects vertex position to a clip space via reordered row-major MVP matrix.
|
||||
It skips calculation of z depth component, as we assume to never use it.
|
||||
Instead, 3rd returned component is w value, for future projection.
|
||||
|
||||
We must never render from inside geometry, as it will break no Z clipping
|
||||
assumption (see com_gem_clip_vis_project()).
|
||||
*/
|
||||
static inline com_vec_t com_gem_vec_project_clip(com_mat_t a, com_vec_t b) {
|
||||
com_vec_t result;
|
||||
|
||||
#define CASE(m_c, m_n) \
|
||||
result.a[m_c] = (((int64_t)a.a[m_n * 4 + 0] * b.s.x) + \
|
||||
((int64_t)a.a[m_n * 4 + 1] * b.s.y) + \
|
||||
((int64_t)a.a[m_n * 4 + 2] * b.s.z) + a.a[m_n * 4 + 3]) >> \
|
||||
COM_FIX_FRACBITS;
|
||||
|
||||
CASE(0, 0);
|
||||
CASE(1, 1);
|
||||
CASE(2, 3);
|
||||
|
||||
#undef CASE
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* TODO: Move to separate render-specific file. */
|
||||
/* TODO: If we clip test bounding volume of a model first we can skip
|
||||
* all clipping whatsoever, which might hold true more often, than the cost of
|
||||
* testing the volume. */
|
||||
|
||||
#define COM_GEM_VERTEX_UNCLIPPED (0 << 0)
|
||||
#define COM_GEM_VERTEX_CLIPPED_X (1 << 0)
|
||||
#define COM_GEM_VERTEX_CLIPPED_Y (1 << 1)
|
||||
/* Attempt to project clip space vertex to NDC, reporting which component lies
|
||||
* outside of view. Bit test against those per component. This is needed for
|
||||
* determining new view-lying clipped triangles. */
|
||||
static inline uint8_t com_gem_clip_vis_project(com_vec_t a, com_vec_t *out) {
|
||||
uint8_t mask;
|
||||
if (a.s.x < -a.s.z || a.s.x > a.s.z)
|
||||
mask ^= COM_GEM_VERTEX_CLIPPED_X;
|
||||
if (a.s.y < -a.s.z || a.s.y > a.s.z)
|
||||
mask ^= COM_GEM_VERTEX_CLIPPED_Y;
|
||||
out->a[0] = com_fix_div(a.a[0], a.a[2]);
|
||||
out->a[1] = com_fix_div(a.a[1], a.a[2]);
|
||||
return mask;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user