Draw Manager: Add support for temporary matrix override.

This allow to specify custom matrices for certain specific passes.
This commit is contained in:
2017-06-08 20:19:42 +02:00
parent 4abb3c1bc4
commit 1ee5d08c95
2 changed files with 54 additions and 10 deletions

View File

@@ -198,6 +198,7 @@ void DRW_framebuffer_bind(struct GPUFrameBuffer *fb);
void DRW_framebuffer_clear(bool color, bool depth, bool stencil, float clear_col[4], float clear_depth);
void DRW_framebuffer_read_data(int x, int y, int w, int h, int channels, int slot, float *data);
void DRW_framebuffer_texture_attach(struct GPUFrameBuffer *fb, struct GPUTexture *tex, int slot, int mip);
void DRW_framebuffer_cubeface_attach(struct GPUFrameBuffer *fb, struct GPUTexture *tex, int slot, int face, int mip);
void DRW_framebuffer_texture_detach(struct GPUTexture *tex);
void DRW_framebuffer_blit(struct GPUFrameBuffer *fb_read, struct GPUFrameBuffer *fb_write, bool depth);
void DRW_framebuffer_viewport_size(struct GPUFrameBuffer *UNUSED(fb_read), int w, int h);
@@ -314,7 +315,7 @@ void DRW_pass_foreach_shgroup(DRWPass *pass, void (*callback)(void *userData, DR
/* Viewport */
typedef enum {
DRW_MAT_PERS,
DRW_MAT_PERS = 0,
DRW_MAT_PERSINV,
DRW_MAT_VIEW,
DRW_MAT_VIEWINV,
@@ -324,6 +325,8 @@ typedef enum {
void DRW_viewport_init(const bContext *C);
void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type);
void DRW_viewport_matrix_override_set(float mat[4][4], DRWViewportMatrixType type);
void DRW_viewport_matrix_override_unset(DRWViewportMatrixType type);
const float *DRW_viewport_size_get(void);
const float *DRW_viewport_screenvecs_get(void);
const float *DRW_viewport_pixelsize_get(void);

View File

@@ -300,6 +300,11 @@ static struct DRWGlobalState {
ListBase enabled_engines; /* RenderEngineType */
} DST = {NULL};
static struct DRWMatrixOveride {
float mat[6][4][4];
bool override[6];
} viewport_matrix_override = {0};
ListBase DRW_engines = {NULL, NULL};
#ifdef USE_GPU_SELECT
@@ -1506,17 +1511,42 @@ static void draw_geometry_prepare(
bool do_eye = (interface->eye != -1);
bool do_orco = (interface->orcotexfac != -1) && (texcoloc != NULL) && (texcosize != NULL);
/* Matrix override */
float (*persmat)[4];
float (*persinv)[4];
float (*viewmat)[4];
float (*viewinv)[4];
float (*winmat)[4];
float (*wininv)[4];
persmat = (viewport_matrix_override.override[DRW_MAT_PERS])
? viewport_matrix_override.mat[DRW_MAT_PERS] : rv3d->persmat;
persinv = (viewport_matrix_override.override[DRW_MAT_PERSINV])
? viewport_matrix_override.mat[DRW_MAT_PERSINV] : rv3d->persinv;
viewmat = (viewport_matrix_override.override[DRW_MAT_VIEW])
? viewport_matrix_override.mat[DRW_MAT_VIEW] : rv3d->viewmat;
viewinv = (viewport_matrix_override.override[DRW_MAT_VIEWINV])
? viewport_matrix_override.mat[DRW_MAT_VIEWINV] : rv3d->viewinv;
winmat = (viewport_matrix_override.override[DRW_MAT_WIN])
? viewport_matrix_override.mat[DRW_MAT_WIN] : rv3d->winmat;
if (do_pi) {
invert_m4_m4(pi, rv3d->winmat);
if (viewport_matrix_override.override[DRW_MAT_WININV]) {
wininv = viewport_matrix_override.mat[DRW_MAT_WININV];
}
else {
invert_m4_m4(pi, winmat);
wininv = pi;
}
}
if (do_mi) {
invert_m4_m4(mi, obmat);
}
if (do_mvp) {
mul_m4_m4m4(mvp, rv3d->persmat, obmat);
mul_m4_m4m4(mvp, persmat, obmat);
}
if (do_mv || do_mvi || do_n || do_eye) {
mul_m4_m4m4(mv, rv3d->viewmat, obmat);
mul_m4_m4m4(mv, viewmat, obmat);
}
if (do_mvi) {
invert_m4_m4(mvi, mv);
@@ -1558,22 +1588,22 @@ static void draw_geometry_prepare(
GPU_shader_uniform_vector(shgroup->shader, interface->modelviewprojection, 16, 1, (float *)mvp);
}
if (interface->viewinverse != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->viewinverse, 16, 1, (float *)rv3d->viewinv);
GPU_shader_uniform_vector(shgroup->shader, interface->viewinverse, 16, 1, (float *)viewinv);
}
if (interface->viewprojection != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->viewprojection, 16, 1, (float *)rv3d->persmat);
GPU_shader_uniform_vector(shgroup->shader, interface->viewprojection, 16, 1, (float *)persmat);
}
if (interface->viewprojectioninverse != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->viewprojectioninverse, 16, 1, (float *)rv3d->persinv);
GPU_shader_uniform_vector(shgroup->shader, interface->viewprojectioninverse, 16, 1, (float *)persinv);
}
if (interface->projection != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->projection, 16, 1, (float *)rv3d->winmat);
GPU_shader_uniform_vector(shgroup->shader, interface->projection, 16, 1, (float *)winmat);
}
if (interface->projectioninverse != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->projectioninverse, 16, 1, (float *)pi);
GPU_shader_uniform_vector(shgroup->shader, interface->projectioninverse, 16, 1, (float *)wininv);
}
if (interface->view != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->view, 16, 1, (float *)rv3d->viewmat);
GPU_shader_uniform_vector(shgroup->shader, interface->view, 16, 1, (float *)viewmat);
}
if (interface->modelview != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->modelview, 16, 1, (float *)mv);
@@ -2234,6 +2264,17 @@ void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type)
}
}
void DRW_viewport_matrix_override_set(float mat[4][4], DRWViewportMatrixType type)
{
copy_m4_m4(viewport_matrix_override.mat[type], mat);
viewport_matrix_override.override[type] = true;
}
void DRW_viewport_matrix_override_unset(DRWViewportMatrixType type)
{
viewport_matrix_override.override[type] = false;
}
bool DRW_viewport_is_persp_get(void)
{
RegionView3D *rv3d = DST.draw_ctx.rv3d;