Clay Engine: Separate mode drawing to different files/engines.

This commit is contained in:
2017-02-17 17:29:43 +01:00
parent 9cb44cbba1
commit 50fb3ea3de
13 changed files with 710 additions and 289 deletions

View File

@@ -27,6 +27,7 @@ set(INC
. .
intern intern
engines/clay engines/clay
modes/
../blenkernel ../blenkernel
../blenlib ../blenlib
@@ -55,12 +56,16 @@ set(SRC
intern/draw_cache.c intern/draw_cache.c
intern/draw_view.c intern/draw_view.c
engines/clay/clay.c engines/clay/clay.c
modes/edit_mode.c
modes/object_mode.c
intern/DRW_render.h intern/DRW_render.h
intern/draw_mode_pass.h intern/draw_mode_pass.h
intern/draw_cache.h intern/draw_cache.h
intern/draw_view.h intern/draw_view.h
engines/clay/clay.h engines/clay/clay.h
modes/edit_mode.h
modes/object_mode.h
./DRW_engine.h ./DRW_engine.h
) )

View File

@@ -126,17 +126,9 @@ enum {
/* keep it under MAX_PASSES */ /* keep it under MAX_PASSES */
typedef struct CLAY_PassList{ typedef struct CLAY_PassList{
/* default */
struct DRWPass *non_meshes_pass;
struct DRWPass *ob_center_pass;
/* engine specific */
struct DRWPass *depth_pass; struct DRWPass *depth_pass;
struct DRWPass *depth_pass_cull; struct DRWPass *depth_pass_cull;
struct DRWPass *depth_pass_hidden_wire;
struct DRWPass *clay_pass; struct DRWPass *clay_pass;
struct DRWPass *wire_overlay_pass;
struct DRWPass *wire_outline_pass;
struct DRWPass *wire_outline_pass_hidden_wire;
} CLAY_PassList; } CLAY_PassList;
//#define GTAO //#define GTAO
@@ -286,8 +278,12 @@ MaterialEngineSettings *CLAY_material_settings_create(void)
return (MaterialEngineSettings *)settings; return (MaterialEngineSettings *)settings;
} }
static void CLAY_engine_init(CLAY_StorageList *stl, CLAY_TextureList *txl, CLAY_FramebufferList *fbl) static void CLAY_engine_init(void)
{ {
CLAY_StorageList *stl = DRW_engine_storage_list_get();
CLAY_TextureList *txl = DRW_engine_texture_list_get();
CLAY_FramebufferList *fbl = DRW_engine_framebuffer_list_get();
/* Create Texture Array */ /* Create Texture Array */
if (!data.matcap_array) { if (!data.matcap_array) {
PreviewImage *prv[24]; /* For now use all of the 24 internal matcaps */ PreviewImage *prv[24]; /* For now use all of the 24 internal matcaps */
@@ -384,56 +380,56 @@ static void CLAY_engine_init(CLAY_StorageList *stl, CLAY_TextureList *txl, CLAY_
(int)viewport_size[0], (int)viewport_size[1], (int)viewport_size[0], (int)viewport_size[1],
&tex, 1); &tex, 1);
} }
}
static void CLAY_ssao_setup(void) /* SSAO setup */
{ {
float invproj[4][4]; float invproj[4][4];
float dfdyfacs[2]; float dfdyfacs[2];
bool is_persp = DRW_viewport_is_persp_get(); bool is_persp = DRW_viewport_is_persp_get();
/* view vectors for the corners of the view frustum. Can be used to recreate the world space position easily */ /* view vectors for the corners of the view frustum. Can be used to recreate the world space position easily */
float viewvecs[3][4] = { float viewvecs[3][4] = {
{-1.0f, -1.0f, -1.0f, 1.0f}, {-1.0f, -1.0f, -1.0f, 1.0f},
{1.0f, -1.0f, -1.0f, 1.0f}, {1.0f, -1.0f, -1.0f, 1.0f},
{-1.0f, 1.0f, -1.0f, 1.0f} {-1.0f, 1.0f, -1.0f, 1.0f}
}; };
int i; int i;
float *size = DRW_viewport_size_get(); float *size = DRW_viewport_size_get();
RenderEngineSettingsClay *settings = DRW_render_settings_get(NULL, RE_engine_id_BLENDER_CLAY); RenderEngineSettingsClay *settings = DRW_render_settings_get(NULL, RE_engine_id_BLENDER_CLAY);
DRW_get_dfdy_factors(dfdyfacs); DRW_get_dfdy_factors(dfdyfacs);
data.ssao_params[0] = settings->ssao_samples; data.ssao_params[0] = settings->ssao_samples;
data.ssao_params[1] = size[0] / 64.0; data.ssao_params[1] = size[0] / 64.0;
data.ssao_params[2] = size[1] / 64.0; data.ssao_params[2] = size[1] / 64.0;
data.ssao_params[3] = dfdyfacs[1]; /* dfdy sign for offscreen */ data.ssao_params[3] = dfdyfacs[1]; /* dfdy sign for offscreen */
/* invert the view matrix */ /* invert the view matrix */
DRW_viewport_matrix_get(data.winmat, DRW_MAT_WIN); DRW_viewport_matrix_get(data.winmat, DRW_MAT_WIN);
invert_m4_m4(invproj, data.winmat); invert_m4_m4(invproj, data.winmat);
/* convert the view vectors to view space */ /* convert the view vectors to view space */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
mul_m4_v4(invproj, viewvecs[i]); mul_m4_v4(invproj, viewvecs[i]);
/* normalized trick see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */ /* normalized trick see http://www.derschmale.com/2014/01/26/reconstructing-positions-from-the-depth-buffer */
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]); mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][3]);
if (is_persp) if (is_persp)
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]); mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
viewvecs[i][3] = 1.0; viewvecs[i][3] = 1.0;
copy_v4_v4(data.viewvecs[i], viewvecs[i]); copy_v4_v4(data.viewvecs[i], viewvecs[i]);
} }
/* we need to store the differences */ /* we need to store the differences */
data.viewvecs[1][0] -= data.viewvecs[0][0]; data.viewvecs[1][0] -= data.viewvecs[0][0];
data.viewvecs[1][1] = data.viewvecs[2][1] - data.viewvecs[0][1]; data.viewvecs[1][1] = data.viewvecs[2][1] - data.viewvecs[0][1];
/* calculate a depth offset as well */ /* calculate a depth offset as well */
if (!is_persp) { if (!is_persp) {
float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f}; float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
mul_m4_v4(invproj, vec_far); mul_m4_v4(invproj, vec_far);
mul_v3_fl(vec_far, 1.0f / vec_far[3]); mul_v3_fl(vec_far, 1.0f / vec_far[3]);
data.viewvecs[1][2] = vec_far[2] - data.viewvecs[0][2]; data.viewvecs[1][2] = vec_far[2] - data.viewvecs[0][2];
}
} }
} }
@@ -605,112 +601,104 @@ static DRWShadingGroup *CLAY_object_shgrp_get(Object *ob, CLAY_StorageList *stl,
return shgrps[id]; return shgrps[id];
} }
static void CLAY_create_cache(CLAY_PassList *passes, CLAY_StorageList *stl, const struct bContext *C) static DRWShadingGroup *depth_shgrp;
static DRWShadingGroup *depth_shgrp_cull;
static void CLAY_cache_init(void)
{ {
SceneLayer *sl = CTX_data_scene_layer(C); CLAY_PassList *psl = DRW_engine_pass_list_get();
DRWShadingGroup *clay_shgrp; CLAY_StorageList *stl = DRW_engine_storage_list_get();
DRWShadingGroup *depth_shgrp;
DRWShadingGroup *depth_shgrp_cull;
DRWShadingGroup *depth_shgrp_hidden_wire;
/* Depth Pass */ /* Depth Pass */
{ {
passes->depth_pass_cull = DRW_pass_create("Depth Pass Cull", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK); psl->depth_pass_cull = DRW_pass_create("Depth Pass Cull", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
depth_shgrp_cull = DRW_shgroup_create(data.depth_sh, passes->depth_pass_cull); psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
passes->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
depth_shgrp = DRW_shgroup_create(data.depth_sh, passes->depth_pass); depth_shgrp_cull = DRW_shgroup_create(data.depth_sh, psl->depth_pass_cull);
passes->depth_pass_hidden_wire = DRW_pass_create("Depth Pass Hidden Wire", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK); depth_shgrp = DRW_shgroup_create(data.depth_sh, psl->depth_pass);
depth_shgrp_hidden_wire = DRW_shgroup_create(data.depth_sh, passes->depth_pass_hidden_wire);
} }
/* Clay Pass */ /* Clay Pass */
{ {
passes->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL); psl->clay_pass = DRW_pass_create("Clay Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL);
stl->storage->ubo_current_id = 0; stl->storage->ubo_current_id = 0;
memset(stl->storage->shgrps, 0, sizeof(DRWShadingGroup *) * MAX_CLAY_MAT); memset(stl->storage->shgrps, 0, sizeof(DRWShadingGroup *) * MAX_CLAY_MAT);
} }
}
/* Object Mode */ static void CLAY_cache_populate(Object *ob)
{ {
DRW_pass_setup_common(&passes->wire_overlay_pass, const bContext *C = DRW_get_context();
&passes->wire_outline_pass, int mode = CTX_data_mode_enum(C);
&passes->wire_outline_pass_hidden_wire, CLAY_StorageList *stl = DRW_engine_storage_list_get();
&passes->non_meshes_pass, CLAY_PassList *psl = DRW_engine_pass_list_get();
&passes->ob_center_pass); struct Batch *geom;
DRWShadingGroup *clay_shgrp;
bool do_occlude_wire = false;
bool do_cull = false;
CollectionEngineSettings *ces_mode_ed, *ces_mode_ob;
if ((ob->base_flag & BASE_VISIBLED) == 0)
return;
switch (mode) {
case CTX_MODE_EDIT_MESH:
case CTX_MODE_EDIT_CURVE:
case CTX_MODE_EDIT_SURFACE:
case CTX_MODE_EDIT_TEXT:
case CTX_MODE_EDIT_ARMATURE:
case CTX_MODE_EDIT_METABALL:
case CTX_MODE_EDIT_LATTICE:
case CTX_MODE_POSE:
case CTX_MODE_SCULPT:
case CTX_MODE_PAINT_WEIGHT:
case CTX_MODE_PAINT_VERTEX:
case CTX_MODE_PAINT_TEXTURE:
case CTX_MODE_PARTICLE:
ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
break;
case CTX_MODE_OBJECT:
ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, "");
do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
break;
} }
/* TODO Create hash table of batch based on material id*/ if (do_occlude_wire)
DEG_OBJECT_ITER(sl, ob); return;
{
if ((ob->base_flag & BASE_VISIBLED) == 0) {
continue;
}
CollectionEngineSettings *ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, ""); switch (ob->type) {
CollectionEngineSettings *ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, ""); case OB_MESH:
geom = DRW_cache_surface_get(ob);
struct Batch *geom; /* Depth Prepass */
bool do_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_wire"); DRW_shgroup_call_add((do_cull) ? depth_shgrp_cull : depth_shgrp, geom, ob->obmat);
bool do_cull = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_backface_culling");
bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0) || do_wire;
switch (ob->type) { /* Shading */
case OB_MESH: clay_shgrp = CLAY_object_shgrp_get(ob, stl, psl);
geom = DRW_cache_surface_get(ob); DRW_shgroup_call_add(clay_shgrp, geom, ob->obmat);
break;
/* Depth Prepass */
if (do_occlude_wire)
DRW_shgroup_call_add(depth_shgrp_hidden_wire, geom, ob->obmat);
else
DRW_shgroup_call_add((do_cull) ? depth_shgrp_cull : depth_shgrp, geom, ob->obmat);
/* Shading */
if (!do_occlude_wire) {
clay_shgrp = CLAY_object_shgrp_get(ob, stl, passes);
DRW_shgroup_call_add(clay_shgrp, geom, ob->obmat);
}
//DRW_shgroup_wire_overlay(passes->wire_overlay_pass, ob);
/* Wires / Outlines */
if (do_occlude_wire) {
DRW_shgroup_wire_outline(passes->wire_outline_pass_hidden_wire, ob, true, false, true);
}
else {
DRW_shgroup_wire_outline(passes->wire_outline_pass, ob, do_wire, false, do_outlines);
}
break;
case OB_LAMP:
case OB_CAMERA:
case OB_EMPTY:
default:
DRW_shgroup_non_meshes(passes->non_meshes_pass, ob);
break;
}
DRW_shgroup_object_center(passes->ob_center_pass, ob);
DRW_shgroup_relationship_lines(passes->non_meshes_pass, ob);
} }
DEG_OBJECT_ITER_END }
static void CLAY_cache_finish(void)
{
CLAY_StorageList *stl = DRW_engine_storage_list_get();
DRW_uniformbuffer_update(stl->mat_ubo, &stl->storage->mat_storage); DRW_uniformbuffer_update(stl->mat_ubo, &stl->storage->mat_storage);
} }
static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context) static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context)
{ {
DRW_viewport_init(context);
/* This function may run for multiple viewports /* This function may run for multiple viewports
* so get the current viewport buffers */ * so get the current viewport buffers */
CLAY_FramebufferList *buffers = NULL; CLAY_PassList *psl = DRW_engine_pass_list_get();
CLAY_TextureList *textures = NULL; CLAY_FramebufferList *fbl = DRW_engine_framebuffer_list_get();
CLAY_PassList *passes = NULL;
CLAY_StorageList *storage = NULL;
DRW_viewport_init(context, (void **)&buffers, (void **)&textures, (void **)&passes, (void **)&storage);
CLAY_engine_init(storage, textures, buffers);
CLAY_engine_init();
/* TODO : tag to refresh by the deps graph */ /* TODO : tag to refresh by the deps graph */
/* ideally only refresh when objects are added/removed */ /* ideally only refresh when objects are added/removed */
@@ -726,38 +714,39 @@ static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context
#ifdef WITH_VIEWPORT_CACHE_TEST #ifdef WITH_VIEWPORT_CACHE_TEST
once = true; once = true;
#endif #endif
CLAY_create_cache(passes, storage, context); SceneLayer *sl = CTX_data_scene_layer(context);
CLAY_cache_init();
DRW_mode_cache_init();
DEG_OBJECT_ITER(sl, ob);
{
CLAY_cache_populate(ob);
DRW_mode_cache_populate(ob);
}
DEG_OBJECT_ITER_END
CLAY_cache_finish();
DRW_mode_cache_finish();
} }
/* Start Drawing */ /* Start Drawing */
DRW_draw_background(); DRW_draw_background();
/* Pass 1 : Depth pre-pass */ /* Pass 1 : Depth pre-pass */
DRW_draw_pass(passes->depth_pass); DRW_draw_pass(psl->depth_pass);
DRW_draw_pass(passes->depth_pass_cull); DRW_draw_pass(psl->depth_pass_cull);
/* Pass 2 : Duplicate depth */ /* Pass 2 : Duplicate depth */
/* Unless we go for deferred shading we need this to avoid manual depth test and artifacts */ /* Unless we go for deferred shading we need this to avoid manual depth test and artifacts */
DRW_framebuffer_blit(buffers->default_fb, buffers->dupli_depth, true); DRW_framebuffer_blit(fbl->default_fb, fbl->dupli_depth, true);
/* Pass 3 : Shading */ /* Pass 3 : Shading */
CLAY_ssao_setup(); DRW_draw_pass(psl->clay_pass);
DRW_draw_pass(passes->clay_pass);
/* Pass 4 : Overlays */ /* Pass 4 : Overlays */
DRW_draw_grid(); /* At this point all shaded geometry should have been rendered and their depth written */
//DRW_draw_pass(passes->wire_overlay_pass); DRW_draw_mode_overlays();
DRW_draw_pass(passes->wire_outline_pass);
DRW_draw_pass(passes->non_meshes_pass);
/* Hidden Wires */
DRW_draw_pass(passes->depth_pass_hidden_wire);
DRW_draw_pass(passes->wire_outline_pass_hidden_wire);
DRW_draw_pass(passes->ob_center_pass);
DRW_draw_manipulator();
DRW_draw_region_info();
/* Always finish by this */ /* Always finish by this */
DRW_state_reset(); DRW_state_reset();

View File

@@ -197,7 +197,7 @@ typedef enum {
DRW_MAT_WIN, DRW_MAT_WIN,
} DRWViewportMatrixType; } DRWViewportMatrixType;
void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes, void **storage); void DRW_viewport_init(const bContext *C);
void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type); void DRW_viewport_matrix_get(float mat[4][4], DRWViewportMatrixType type);
float *DRW_viewport_size_get(void); float *DRW_viewport_size_get(void);
float *DRW_viewport_screenvecs_get(void); float *DRW_viewport_screenvecs_get(void);
@@ -211,13 +211,26 @@ void *DRW_material_settings_get(Material *ma, const char *engine_name);
void *DRW_render_settings_get(Scene *scene, const char *engine_name); void *DRW_render_settings_get(Scene *scene, const char *engine_name);
#endif /* __DRW_ENGINE_H__ */ #endif /* __DRW_ENGINE_H__ */
/* Cache */
void DRW_mode_cache_init(void);
void DRW_mode_cache_populate(struct Object *ob);
void DRW_mode_cache_finish(void);
/* Draw commands */ /* Draw commands */
void DRW_draw_pass(DRWPass *pass); void DRW_draw_pass(DRWPass *pass);
void DRW_draw_mode_overlays(void);
void DRW_state_reset(void); void DRW_state_reset(void);
/* Other */ /* Other */
void DRW_get_dfdy_factors(float dfdyfac[2]); void DRW_get_dfdy_factors(float dfdyfac[2]);
const struct bContext *DRW_get_context(void); const struct bContext *DRW_get_context(void);
void *DRW_engine_pass_list_get(void);
void *DRW_engine_storage_list_get(void);
void *DRW_engine_texture_list_get(void);
void *DRW_engine_framebuffer_list_get(void);
void *DRW_mode_pass_list_get(void);
void *DRW_mode_storage_list_get(void);
void *DRW_mode_texture_list_get(void);
void *DRW_mode_framebuffer_list_get(void);
#endif /* __DRW_RENDER_H__ */ #endif /* __DRW_RENDER_H__ */

View File

@@ -53,6 +53,8 @@
#include "UI_resources.h" #include "UI_resources.h"
#include "object_mode.h"
#include "edit_mode.h"
#include "clay.h" #include "clay.h"
#define MAX_ATTRIB_NAME 32 #define MAX_ATTRIB_NAME 32
@@ -159,9 +161,10 @@ enum {
static struct DRWGlobalState{ static struct DRWGlobalState{
GPUShader *shader; GPUShader *shader;
struct GPUFrameBuffer *default_framebuffer; struct GPUFrameBuffer *default_framebuffer;
FramebufferList *current_fbl; FramebufferList *fbl, *fbl_mode;
TextureList *current_txl; TextureList *txl, *txl_mode;
PassList *current_psl; PassList *psl, *psl_mode;
StorageList *stl, *stl_mode;
ListBase bound_texs; ListBase bound_texs;
int tex_bind_id; int tex_bind_id;
float size[2]; float size[2];
@@ -852,15 +855,15 @@ static void draw_shgroup(DRWShadingGroup *shgroup)
break; break;
case DRW_UNIFORM_BUFFER: case DRW_UNIFORM_BUFFER:
/* restore index from lenght we abused */ /* restore index from lenght we abused */
GPU_texture_bind(DST.current_txl->textures[uni->length], uni->bindloc); GPU_texture_bind(DST.txl->textures[uni->length], uni->bindloc);
GPU_texture_compare_mode(DST.current_txl->textures[uni->length], false); GPU_texture_compare_mode(DST.txl->textures[uni->length], false);
GPU_texture_filter_mode(DST.current_txl->textures[uni->length], false); GPU_texture_filter_mode(DST.txl->textures[uni->length], false);
bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture"); bound_tex = MEM_callocN(sizeof(DRWBoundTexture), "DRWBoundTexture");
bound_tex->tex = DST.current_txl->textures[uni->length]; bound_tex->tex = DST.txl->textures[uni->length];
BLI_addtail(&DST.bound_texs, bound_tex); BLI_addtail(&DST.bound_texs, bound_tex);
GPU_shader_uniform_texture(shgroup->shader, uni->location, DST.current_txl->textures[uni->length]); GPU_shader_uniform_texture(shgroup->shader, uni->location, DST.txl->textures[uni->length]);
break; break;
case DRW_UNIFORM_BLOCK: case DRW_UNIFORM_BLOCK:
GPU_uniformbuffer_bind((GPUUniformBuffer *)uni->value, uni->bindloc); GPU_uniformbuffer_bind((GPUUniformBuffer *)uni->value, uni->bindloc);
@@ -1013,7 +1016,74 @@ void DRW_state_reset(void)
state |= DRW_STATE_DEPTH_LESS; state |= DRW_STATE_DEPTH_LESS;
set_state(state); set_state(state);
} }
void DRW_draw_mode_overlays(void)
{
const bContext *C = DRW_get_context();
int mode = CTX_data_mode_enum(C);
DRW_draw_grid();
switch (mode) {
case CTX_MODE_EDIT_MESH:
EDIT_draw();
break;
case CTX_MODE_OBJECT:
OBJECT_draw();
break;
}
DRW_draw_manipulator();
DRW_draw_region_info();
}
#endif #endif
/* ******************************************* Mode Engine Cache ****************************************** */
void DRW_mode_cache_init(void)
{
const bContext *C = DRW_get_context();
int mode = CTX_data_mode_enum(C);
switch (mode) {
case CTX_MODE_EDIT_MESH:
EDIT_cache_init();
break;
case CTX_MODE_OBJECT:
OBJECT_cache_init();
break;
}
}
void DRW_mode_cache_populate(Object *ob)
{
const bContext *C = DRW_get_context();
int mode = CTX_data_mode_enum(C);
switch (mode) {
case CTX_MODE_EDIT_MESH:
EDIT_cache_populate(ob);
break;
case CTX_MODE_OBJECT:
OBJECT_cache_populate(ob);
break;
}
}
void DRW_mode_cache_finish(void)
{
const bContext *C = DRW_get_context();
int mode = CTX_data_mode_enum(C);
switch (mode) {
case CTX_MODE_EDIT_MESH:
EDIT_cache_finish();
break;
case CTX_MODE_OBJECT:
OBJECT_cache_finish();
break;
}
}
/* ****************************************** Settings ******************************************/ /* ****************************************** Settings ******************************************/
void *DRW_material_settings_get(Material *ma, const char *engine_name) void *DRW_material_settings_get(Material *ma, const char *engine_name)
{ {
@@ -1155,25 +1225,22 @@ float *DRW_viewport_pixelsize_get(void)
return &DST.pixsize; return &DST.pixsize;
} }
void DRW_viewport_init(const bContext *C, void **buffers, void **textures, void **passes, void **storage) void DRW_viewport_init(const bContext *C)
{ {
RegionView3D *rv3d = CTX_wm_region_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C);
GPUViewport *viewport = rv3d->viewport; GPUViewport *viewport = rv3d->viewport;
GPU_viewport_get_engine_data(viewport, buffers, textures, passes, storage); GPU_viewport_get_engine_data(viewport, &DST.fbl, &DST.txl, &DST.psl, &DST.stl);
GPU_viewport_get_mode_data(viewport, &DST.fbl_mode, &DST.txl_mode, &DST.psl_mode, &DST.stl_mode);
/* Refresh DST.size */ /* Refresh DST.size */
DefaultTextureList *txl = (DefaultTextureList *)*textures; DefaultTextureList *txl = (DefaultTextureList *)DST.txl;
DST.size[0] = (float)GPU_texture_width(txl->color); DST.size[0] = (float)GPU_texture_width(txl->color);
DST.size[1] = (float)GPU_texture_height(txl->color); DST.size[1] = (float)GPU_texture_height(txl->color);
DefaultFramebufferList *fbl = (DefaultFramebufferList *)*buffers; DefaultFramebufferList *fbl = (DefaultFramebufferList *)DST.fbl;
DST.default_framebuffer = fbl->default_fb; DST.default_framebuffer = fbl->default_fb;
DST.current_txl = (TextureList *)*textures;
DST.current_fbl = (FramebufferList *)*buffers;
DST.current_psl = (PassList *)*passes;
/* Refresh DST.screenvecs */ /* Refresh DST.screenvecs */
copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]); copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]);
copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]); copy_v3_v3(DST.screenvecs[1], rv3d->viewinv[1]);
@@ -1208,7 +1275,7 @@ bool DRW_viewport_is_persp_get(void)
bool DRW_viewport_cache_is_dirty(void) bool DRW_viewport_cache_is_dirty(void)
{ {
/* TODO Use a dirty flag */ /* TODO Use a dirty flag */
return (DST.current_psl->passes[0] == NULL); return (DST.psl->passes[0] == NULL);
} }
/* ****************************************** OTHER ***************************************** */ /* ****************************************** OTHER ***************************************** */
@@ -1218,6 +1285,46 @@ const bContext *DRW_get_context(void)
return DST.context; return DST.context;
} }
void *DRW_engine_pass_list_get(void)
{
return DST.psl;
}
void *DRW_engine_storage_list_get(void)
{
return DST.stl;
}
void *DRW_engine_texture_list_get(void)
{
return DST.txl;
}
void *DRW_engine_framebuffer_list_get(void)
{
return DST.fbl;
}
void *DRW_mode_pass_list_get(void)
{
return DST.psl_mode;
}
void *DRW_mode_storage_list_get(void)
{
return DST.stl_mode;
}
void *DRW_mode_texture_list_get(void)
{
return DST.txl_mode;
}
void *DRW_mode_framebuffer_list_get(void)
{
return DST.fbl_mode;
}
/* ****************************************** INIT ***************************************** */ /* ****************************************** INIT ***************************************** */
void DRW_engines_init(void) void DRW_engines_init(void)

View File

@@ -76,6 +76,13 @@ static float colorActive[4], colorSelect[4], colorTransform[4], colorGroup[4], c
static float colorEmpty[4], colorLamp[4], colorCamera[4], colorSpeaker[4]; static float colorEmpty[4], colorLamp[4], colorCamera[4], colorSpeaker[4];
static float lampCenterSize, lampCircleRad, lampCircleShadowRad, colorLampNoAlpha[4]; static float lampCenterSize, lampCircleRad, lampCircleShadowRad, colorLampNoAlpha[4];
/* Store list of passes for easy access */
static DRWPass *wire_overlay;
static DRWPass *wire_overlay_hidden_wire;
static DRWPass *wire_outline;
static DRWPass *non_meshes;
static DRWPass *ob_center;
static DRWShadingGroup *shgroup_dynlines_uniform_color(DRWPass *pass, float color[4]) static DRWShadingGroup *shgroup_dynlines_uniform_color(DRWPass *pass, float color[4])
{ {
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR); GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -160,9 +167,13 @@ static DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Batch *geom)
} }
/* This Function setup the passes needed for the mode rendering. /* This Function setup the passes needed for the mode rendering.
* The passes are populated by the rendering engine using the DRW_shgroup_* functions. */ * The passes are populated by the rendering engines using the DRW_shgroup_* functions.
void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPass **wire_outline_pass_hidden_wire, * If a pass is not needed use NULL instead of the pass pointer */
DRWPass **non_meshes, DRWPass **ob_center) void DRW_mode_passes_setup(DRWPass **psl_wire_overlay,
DRWPass **psl_wire_overlay_hidden_wire,
DRWPass **psl_wire_outline,
DRWPass **psl_non_meshes,
DRWPass **psl_ob_center)
{ {
UI_GetThemeColor4fv(TH_WIRE, colorWire); UI_GetThemeColor4fv(TH_WIRE, colorWire);
UI_GetThemeColor4fv(TH_WIRE_EDIT, colorWireEdit); UI_GetThemeColor4fv(TH_WIRE_EDIT, colorWireEdit);
@@ -179,67 +190,65 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
colorLampNoAlpha[3] = 1.0f; colorLampNoAlpha[3] = 1.0f;
if (wire_overlay) { if (psl_wire_overlay) {
/* This pass can draw mesh edges top of Shaded Meshes without any Z fighting */ /* This pass can draw mesh edges top of Shaded Meshes without any Z fighting */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND; DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_BLEND;
*wire_overlay = DRW_pass_create("Wire Overlays Pass", state); *psl_wire_overlay = DRW_pass_create("Wire Overlays Pass", state);
} }
if (wire_outline) { if (psl_wire_overlay_hidden_wire) {
/* This pass can draw mesh edges top of Shaded Meshes without any Z fighting */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
*psl_wire_overlay_hidden_wire = DRW_pass_create("Wire Overlays Pass", state);
}
if (psl_wire_outline) {
/* This pass can draw mesh outlines and/or fancy wireframe */ /* This pass can draw mesh outlines and/or fancy wireframe */
/* Fancy wireframes are not meant to be occluded (without Z offset) */ /* Fancy wireframes are not meant to be occluded (without Z offset) */
/* Outlines and Fancy Wires use the same VBO */ /* Outlines and Fancy Wires use the same VBO */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND; DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
*wire_outline = DRW_pass_create("Wire + Outlines Pass", state); *psl_wire_outline = DRW_pass_create("Wire + Outlines Pass", state);
} }
if (wire_outline_pass_hidden_wire) { if (psl_non_meshes) {
/* This pass can draw mesh outlines and/or fancy wireframe */
/* Fancy wireframes are not meant to be occluded (without Z offset) */
/* Outlines and Fancy Wires use the same VBO */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
*wire_outline_pass_hidden_wire = DRW_pass_create("Wire + Outlines Pass", state);
}
if (non_meshes) {
/* Non Meshes Pass (Camera, empties, lamps ...) */ /* Non Meshes Pass (Camera, empties, lamps ...) */
struct Batch *geom; struct Batch *geom;
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND; DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
state |= DRW_STATE_WIRE; state |= DRW_STATE_WIRE;
*non_meshes = DRW_pass_create("Non Meshes Pass", state); *psl_non_meshes = DRW_pass_create("Non Meshes Pass", state);
/* Empties */ /* Empties */
geom = DRW_cache_plain_axes_get(); geom = DRW_cache_plain_axes_get();
plain_axes = shgroup_instance(*non_meshes, geom); plain_axes = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_cube_get(); geom = DRW_cache_cube_get();
cube = shgroup_instance(*non_meshes, geom); cube = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_circle_get(); geom = DRW_cache_circle_get();
circle = shgroup_instance(*non_meshes, geom); circle = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_empty_sphere_get(); geom = DRW_cache_empty_sphere_get();
sphere = shgroup_instance(*non_meshes, geom); sphere = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_empty_cone_get(); geom = DRW_cache_empty_cone_get();
cone = shgroup_instance(*non_meshes, geom); cone = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_single_arrow_get(); geom = DRW_cache_single_arrow_get();
single_arrow = shgroup_instance(*non_meshes, geom); single_arrow = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_single_line_get(); geom = DRW_cache_single_line_get();
single_arrow_line = shgroup_instance(*non_meshes, geom); single_arrow_line = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_arrows_get(); geom = DRW_cache_arrows_get();
arrows = shgroup_instance(*non_meshes, geom); arrows = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_axis_names_get(); geom = DRW_cache_axis_names_get();
axis_names = shgroup_instance_axis_names(*non_meshes, geom); axis_names = shgroup_instance_axis_names(*psl_non_meshes, geom);
/* Speaker */ /* Speaker */
geom = DRW_cache_speaker_get(); geom = DRW_cache_speaker_get();
speaker = shgroup_instance(*non_meshes, geom); speaker = shgroup_instance(*psl_non_meshes, geom);
/* Lamps */ /* Lamps */
lampCenterSize = (U.obcenter_dia + 1.5f) * U.pixelsize; lampCenterSize = (U.obcenter_dia + 1.5f) * U.pixelsize;
@@ -248,32 +257,32 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
/* TODO /* TODO
* for now we create 3 times the same VBO with only lamp center coordinates * for now we create 3 times the same VBO with only lamp center coordinates
* but ideally we would only create it once */ * but ideally we would only create it once */
lamp_center = shgroup_dynpoints_uniform_color(*non_meshes, colorLampNoAlpha, &lampCenterSize); lamp_center = shgroup_dynpoints_uniform_color(*psl_non_meshes, colorLampNoAlpha, &lampCenterSize);
lamp_center_group = shgroup_dynpoints_uniform_color(*non_meshes, colorGroup, &lampCenterSize); lamp_center_group = shgroup_dynpoints_uniform_color(*psl_non_meshes, colorGroup, &lampCenterSize);
geom = DRW_cache_lamp_get(); geom = DRW_cache_lamp_get();
lamp_circle = shgroup_instance_screenspace(*non_meshes, geom, &lampCircleRad); lamp_circle = shgroup_instance_screenspace(*psl_non_meshes, geom, &lampCircleRad);
lamp_circle_shadow = shgroup_instance_screenspace(*non_meshes, geom, &lampCircleShadowRad); lamp_circle_shadow = shgroup_instance_screenspace(*psl_non_meshes, geom, &lampCircleShadowRad);
geom = DRW_cache_lamp_sunrays_get(); geom = DRW_cache_lamp_sunrays_get();
lamp_sunrays = shgroup_instance_screenspace(*non_meshes, geom, &lampCircleRad); lamp_sunrays = shgroup_instance_screenspace(*psl_non_meshes, geom, &lampCircleRad);
lamp_groundline = shgroup_groundlines_uniform_color(*non_meshes, colorLamp); lamp_groundline = shgroup_groundlines_uniform_color(*psl_non_meshes, colorLamp);
lamp_groundpoint = shgroup_groundpoints_uniform_color(*non_meshes, colorLamp); lamp_groundpoint = shgroup_groundpoints_uniform_color(*psl_non_meshes, colorLamp);
/* Relationship Lines */ /* Relationship Lines */
relationship_lines = shgroup_dynlines_uniform_color(*non_meshes, colorWire); relationship_lines = shgroup_dynlines_uniform_color(*psl_non_meshes, colorWire);
DRW_shgroup_state_set(relationship_lines, DRW_STATE_STIPPLE_3); DRW_shgroup_state_set(relationship_lines, DRW_STATE_STIPPLE_3);
} }
if (ob_center) { if (psl_ob_center) {
/* Object Center pass grouped by State */ /* Object Center pass grouped by State */
DRWShadingGroup *grp; DRWShadingGroup *grp;
static float colorDeselect[4], outlineColor[4]; static float colorDeselect[4], outlineColor[4];
static float outlineWidth, size; static float outlineWidth, size;
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_POINT; DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_BLEND | DRW_STATE_POINT;
*ob_center = DRW_pass_create("Obj Center Pass", state); *psl_ob_center = DRW_pass_create("Obj Center Pass", state);
outlineWidth = 1.0f * U.pixelsize; outlineWidth = 1.0f * U.pixelsize;
size = U.obcenter_dia * U.pixelsize + outlineWidth; size = U.obcenter_dia * U.pixelsize + outlineWidth;
@@ -285,7 +294,7 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH); GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_SMOOTH);
/* Active */ /* Active */
grp = DRW_shgroup_point_batch_create(sh, *ob_center); grp = DRW_shgroup_point_batch_create(sh, *psl_ob_center);
DRW_shgroup_uniform_float(grp, "size", &size, 1); DRW_shgroup_uniform_float(grp, "size", &size, 1);
DRW_shgroup_uniform_float(grp, "outlineWidth", &outlineWidth, 1); DRW_shgroup_uniform_float(grp, "outlineWidth", &outlineWidth, 1);
DRW_shgroup_uniform_vec4(grp, "color", colorActive, 1); DRW_shgroup_uniform_vec4(grp, "color", colorActive, 1);
@@ -293,15 +302,22 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
center_active = grp; center_active = grp;
/* Select */ /* Select */
grp = DRW_shgroup_point_batch_create(sh, *ob_center); grp = DRW_shgroup_point_batch_create(sh, *psl_ob_center);
DRW_shgroup_uniform_vec4(grp, "color", colorSelect, 1); DRW_shgroup_uniform_vec4(grp, "color", colorSelect, 1);
center_selected = grp; center_selected = grp;
/* Deselect */ /* Deselect */
grp = DRW_shgroup_point_batch_create(sh, *ob_center); grp = DRW_shgroup_point_batch_create(sh, *psl_ob_center);
DRW_shgroup_uniform_vec4(grp, "color", colorDeselect, 1); DRW_shgroup_uniform_vec4(grp, "color", colorDeselect, 1);
center_deselected = grp; center_deselected = grp;
} }
/* Save passes refs */
wire_overlay = (psl_wire_overlay) ? *psl_wire_overlay : NULL;
wire_overlay_hidden_wire = (psl_wire_overlay_hidden_wire) ? *psl_wire_overlay_hidden_wire : NULL;
wire_outline = (psl_wire_outline) ? *psl_wire_outline : NULL;
non_meshes = (psl_non_meshes) ? *psl_non_meshes : NULL;
ob_center = (psl_ob_center) ? *psl_ob_center : NULL;
} }
/* ******************************************** WIRES *********************************************** */ /* ******************************************** WIRES *********************************************** */
@@ -373,7 +389,7 @@ static int draw_object_wire_theme(Object *ob, float **color)
return theme_id; return theme_id;
} }
void DRW_shgroup_wire_overlay(DRWPass *wire_overlay, Object *ob) void DRW_shgroup_wire_overlay(Object *ob)
{ {
#if 1 #if 1
struct Batch *geom = DRW_cache_wire_overlay_get(ob); struct Batch *geom = DRW_cache_wire_overlay_get(ob);
@@ -395,8 +411,7 @@ void DRW_shgroup_wire_overlay(DRWPass *wire_overlay, Object *ob)
#endif #endif
} }
void DRW_shgroup_wire_outline(DRWPass *wire_outline, Object *ob, void DRW_shgroup_wire_outline(Object *ob, const bool do_front, const bool do_back, const bool do_outline)
const bool do_front, const bool do_back, const bool do_outline)
{ {
GPUShader *sh; GPUShader *sh;
struct Batch *geom = DRW_cache_wire_outline_get(ob); struct Batch *geom = DRW_cache_wire_outline_get(ob);
@@ -459,7 +474,7 @@ void DRW_shgroup_wire_outline(DRWPass *wire_outline, Object *ob,
/* ***************************** NON MESHES ********************** */ /* ***************************** NON MESHES ********************** */
static void DRW_draw_lamp(Object *ob) void DRW_shgroup_lamp(Object *ob)
{ {
Lamp *la = ob->data; Lamp *la = ob->data;
float *color; float *color;
@@ -489,7 +504,7 @@ static void DRW_draw_lamp(Object *ob)
DRW_shgroup_dynamic_call_add(lamp_groundpoint, ob->obmat[3]); DRW_shgroup_dynamic_call_add(lamp_groundpoint, ob->obmat[3]);
} }
static void DRW_draw_empty(Object *ob) void DRW_shgroup_empty(Object *ob)
{ {
float *color; float *color;
draw_object_wire_theme(ob, &color); draw_object_wire_theme(ob, &color);
@@ -517,12 +532,11 @@ static void DRW_draw_empty(Object *ob)
case OB_ARROWS: case OB_ARROWS:
DRW_shgroup_dynamic_call_add(arrows, color, &ob->empty_drawsize, ob->obmat); DRW_shgroup_dynamic_call_add(arrows, color, &ob->empty_drawsize, ob->obmat);
DRW_shgroup_dynamic_call_add(axis_names, color, &ob->empty_drawsize, ob->obmat); DRW_shgroup_dynamic_call_add(axis_names, color, &ob->empty_drawsize, ob->obmat);
/* TODO Missing axes names */
break; break;
} }
} }
static void DRW_draw_speaker(Object *ob) void DRW_shgroup_speaker(Object *ob)
{ {
float *color; float *color;
static float one = 1.0f; static float one = 1.0f;
@@ -531,25 +545,7 @@ static void DRW_draw_speaker(Object *ob)
DRW_shgroup_dynamic_call_add(speaker, color, &one, ob->obmat); DRW_shgroup_dynamic_call_add(speaker, color, &one, ob->obmat);
} }
void DRW_shgroup_non_meshes(DRWPass *UNUSED(non_meshes), Object *ob) void DRW_shgroup_relationship_lines(Object *ob)
{
switch (ob->type) {
case OB_LAMP:
DRW_draw_lamp(ob);
break;
case OB_CAMERA:
case OB_EMPTY:
DRW_draw_empty(ob);
break;
case OB_SPEAKER:
DRW_draw_speaker(ob);
break;
default:
break;
}
}
void DRW_shgroup_relationship_lines(DRWPass *UNUSED(non_meshes), Object *ob)
{ {
if (ob->parent) { if (ob->parent) {
DRW_shgroup_dynamic_call_add(relationship_lines, ob->obmat[3]); DRW_shgroup_dynamic_call_add(relationship_lines, ob->obmat[3]);
@@ -559,7 +555,7 @@ void DRW_shgroup_relationship_lines(DRWPass *UNUSED(non_meshes), Object *ob)
/* ***************************** COMMON **************************** */ /* ***************************** COMMON **************************** */
void DRW_shgroup_object_center(DRWPass *UNUSED(ob_center), Object *ob) void DRW_shgroup_object_center(Object *ob)
{ {
if ((ob->base_flag & BASE_SELECTED) != 0) { if ((ob->base_flag & BASE_SELECTED) != 0) {
DRW_shgroup_dynamic_call_add(center_selected, ob->obmat[3]); DRW_shgroup_dynamic_call_add(center_selected, ob->obmat[3]);

View File

@@ -30,15 +30,18 @@ struct DRWPass;
struct Batch; struct Batch;
struct Object; struct Object;
void DRW_pass_setup_common(struct DRWPass **wire_overlay, struct DRWPass **wire_outline, struct DRWPass **wire_outline_pass_hidden_wire, void DRW_mode_passes_setup(struct DRWPass **psl_wire_overlay,
struct DRWPass **non_meshes, struct DRWPass **ob_center); struct DRWPass **psl_wire_overlay_hidden_wire,
struct DRWPass **psl_wire_outline,
struct DRWPass **psl_non_meshes,
struct DRWPass **psl_ob_center);
void DRW_shgroup_wire_overlay(struct DRWPass *wire_overlay, struct Object *ob); void DRW_shgroup_wire_overlay(struct Object *ob);
void DRW_shgroup_wire_outline( void DRW_shgroup_wire_outline(struct Object *ob, const bool do_front, const bool do_back, const bool do_outline);
struct DRWPass *wire_outline, struct Object *ob, const bool do_front, const bool do_back, const bool do_outline); void DRW_shgroup_lamp(struct Object *ob);
void DRW_shgroup_empty(struct Object *ob);
void DRW_shgroup_non_meshes(struct DRWPass *non_meshes, struct Object *ob); void DRW_shgroup_speaker(struct Object *ob);
void DRW_shgroup_relationship_lines(struct DRWPass *non_meshes, struct Object *ob); void DRW_shgroup_relationship_lines(struct Object *ob);
void DRW_shgroup_object_center(struct DRWPass *ob_center, struct Object *ob); void DRW_shgroup_object_center(struct Object *ob);
#endif /* __DRAW_MODE_PASS_H__ */ #endif /* __DRAW_MODE_PASS_H__ */

View File

@@ -0,0 +1,107 @@
/*
* Copyright 2016, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
/** \file blender/draw/modes/EDIT_mode.c
* \ingroup draw
*/
#include "DRW_render.h"
#include "draw_mode_pass.h"
#include "edit_mode.h"
/* keep it under MAX_PASSES */
typedef struct EDIT_PassList{
struct DRWPass *non_meshes_pass;
struct DRWPass *ob_center_pass;
struct DRWPass *wire_outline_pass;
struct DRWPass *depth_pass_hidden_wire;
} EDIT_PassList;
static DRWShadingGroup *depth_shgrp_hidden_wire;
void EDIT_cache_init(void)
{
EDIT_PassList *psl = DRW_mode_pass_list_get();
static struct GPUShader *depth_sh;
if (!depth_sh) {
depth_sh = DRW_shader_create_3D_depth_only();
}
psl->depth_pass_hidden_wire = DRW_pass_create("Depth Pass Hidden Wire", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
depth_shgrp_hidden_wire = DRW_shgroup_create(depth_sh, psl->depth_pass_hidden_wire);
DRW_mode_passes_setup(NULL,
NULL,
&psl->wire_outline_pass,
&psl->non_meshes_pass,
&psl->ob_center_pass);
}
void EDIT_cache_populate(Object *ob)
{
struct Batch *geom;
CollectionEngineSettings *ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
bool do_occlude_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ed, "show_occlude_wire");
switch (ob->type) {
case OB_MESH:
geom = DRW_cache_surface_get(ob);
if (do_occlude_wire) {
DRW_shgroup_call_add(depth_shgrp_hidden_wire, geom, ob->obmat);
DRW_shgroup_wire_outline(ob, true, false, true);
}
break;
case OB_LAMP:
DRW_shgroup_lamp(ob);
break;
case OB_CAMERA:
case OB_EMPTY:
DRW_shgroup_empty(ob);
break;
case OB_SPEAKER:
DRW_shgroup_speaker(ob);
break;
default:
break;
}
DRW_shgroup_object_center(ob);
DRW_shgroup_relationship_lines(ob);
}
void EDIT_cache_finish(void)
{
/* Do nothing */
}
void EDIT_draw(void)
{
EDIT_PassList *psl = DRW_mode_pass_list_get();
DRW_draw_pass(psl->depth_pass_hidden_wire);
DRW_draw_pass(psl->wire_outline_pass);
DRW_draw_pass(psl->non_meshes_pass);
DRW_draw_pass(psl->ob_center_pass);
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2016, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
/** \file blender/draw/modes/edit_mode.c
* \ingroup draw
*/
#ifndef __EDIT_MODE_H__
#define __EDIT_MODE_H__
void EDIT_cache_init(void);
void EDIT_cache_populate(Object *ob);
void EDIT_cache_finish(void);
void EDIT_draw(void);
#endif /* __EDIT_MODE_H__ */

View File

@@ -0,0 +1,91 @@
/*
* Copyright 2016, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
/** \file blender/draw/modes/object_mode.c
* \ingroup draw
*/
#include "DRW_render.h"
#include "draw_mode_pass.h"
#include "object_mode.h"
/* keep it under MAX_PASSES */
typedef struct OBJECT_PassList{
struct DRWPass *non_meshes_pass;
struct DRWPass *ob_center_pass;
struct DRWPass *wire_outline_pass;
} OBJECT_PassList;
void OBJECT_cache_init(void)
{
OBJECT_PassList *psl = DRW_mode_pass_list_get();
DRW_mode_passes_setup(NULL,
NULL,
&psl->wire_outline_pass,
&psl->non_meshes_pass,
&psl->ob_center_pass);
}
void OBJECT_cache_populate(Object *ob)
{
CollectionEngineSettings *ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, "");
bool do_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_wire");
bool do_outlines = ((ob->base_flag & BASE_SELECTED) != 0) || do_wire;
switch (ob->type) {
case OB_MESH:
DRW_shgroup_wire_outline(ob, do_wire, false, do_outlines);
break;
case OB_LAMP:
DRW_shgroup_lamp(ob);
break;
case OB_CAMERA:
case OB_EMPTY:
DRW_shgroup_empty(ob);
break;
case OB_SPEAKER:
DRW_shgroup_speaker(ob);
break;
default:
break;
}
DRW_shgroup_object_center(ob);
DRW_shgroup_relationship_lines(ob);
}
void OBJECT_cache_finish(void)
{
/* Do nothing */
}
void OBJECT_draw(void)
{
OBJECT_PassList *psl = DRW_mode_pass_list_get();
DRW_draw_pass(psl->wire_outline_pass);
DRW_draw_pass(psl->non_meshes_pass);
DRW_draw_pass(psl->ob_center_pass);
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright 2016, Blender Foundation.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Blender Institute
*
*/
/** \file blender/draw/modes/object_mode.h
* \ingroup draw
*/
#ifndef __OBJECT_MODE_H__
#define __OBJECT_MODE_H__
void OBJECT_cache_init(void);
void OBJECT_cache_populate(Object *ob);
void OBJECT_cache_finish(void);
void OBJECT_draw(void);
#endif /* __OBJECT_MODE_H__ */

View File

@@ -2356,6 +2356,7 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar)
{ {
Scene *scene = CTX_data_scene(C); Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C); View3D *v3d = CTX_wm_view3d(C);
int mode = CTX_data_mode_enum(C);
RegionView3D *rv3d = ar->regiondata; RegionView3D *rv3d = ar->regiondata;
/* TODO layers - In the future we should get RE from Layers */ /* TODO layers - In the future we should get RE from Layers */
RenderEngineType *type = RE_engines_find(scene->r.engine); RenderEngineType *type = RE_engines_find(scene->r.engine);
@@ -2368,7 +2369,7 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar)
if (!rv3d->viewport) if (!rv3d->viewport)
rv3d->viewport = GPU_viewport_create(); rv3d->viewport = GPU_viewport_create();
GPU_viewport_bind(rv3d->viewport, &ar->winrct, scene->r.engine); GPU_viewport_bind(rv3d->viewport, &ar->winrct, scene->r.engine, mode);
/* TODO viewport - there is so much to be done, in fact a lot will need to happen in the space_view3d.c /* TODO viewport - there is so much to be done, in fact a lot will need to happen in the space_view3d.c
* before we even call the drawing routine, but let's move on for now (dfelinto) * before we even call the drawing routine, but let's move on for now (dfelinto)

View File

@@ -56,7 +56,7 @@ typedef struct TextureList {
} TextureList; } TextureList;
typedef struct PassList { typedef struct PassList {
struct DRWPass *passes[MAX_TEXTURES]; struct DRWPass *passes[MAX_PASSES];
} PassList; } PassList;
typedef struct StorageList { typedef struct StorageList {
@@ -79,11 +79,12 @@ typedef struct DefaultPassList {
} DefaultPassList; } DefaultPassList;
GPUViewport *GPU_viewport_create(void); GPUViewport *GPU_viewport_create(void);
void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine); void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine, int mode);
void GPU_viewport_unbind(GPUViewport *viewport); void GPU_viewport_unbind(GPUViewport *viewport);
void GPU_viewport_free(GPUViewport *viewport); void GPU_viewport_free(GPUViewport *viewport);
void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss, void **str); void GPU_viewport_get_engine_data(GPUViewport *viewport, FramebufferList **fbs, TextureList **txs, PassList **pss, StorageList **str);
void GPU_viewport_get_mode_data(GPUViewport *viewport, FramebufferList **fbs, TextureList **txs, PassList **pss, StorageList **str);
/* debug */ /* debug */
bool GPU_viewport_debug_depth_create(GPUViewport *viewport, int width, int height, char err_out[256]); bool GPU_viewport_debug_depth_create(GPUViewport *viewport, int width, int height, char err_out[256]);

View File

@@ -56,18 +56,24 @@ struct GPUViewport {
int size[2]; int size[2];
/* Viewport Buffer Storage */ /* Viewport Buffer Storage */
/* TODO indentify to what engine conf are theses buffers */ FramebufferList *fbl;
DefaultFramebufferList *fbl; TextureList *txl;
DefaultTextureList *txl; PassList *psl;
DefaultPassList *psl;
StorageList *stl; StorageList *stl;
char engine_name[32]; char engine_name[32];
/* Mode storage */
FramebufferList *fbl_mode;
TextureList *txl_mode;
PassList *psl_mode;
StorageList *stl_mode;
int mode;
}; };
static void GPU_viewport_buffers_free(GPUViewport *viewport); static void GPU_viewport_buffers_free(FramebufferList *fbl, TextureList *txl);
static void GPU_viewport_passes_free(GPUViewport *viewport); static void GPU_viewport_storage_free(StorageList *stl);
static void GPU_viewport_storage_free(GPUViewport *viewport); static void GPU_viewport_passes_free(PassList *psl);
GPUViewport *GPU_viewport_create(void) GPUViewport *GPU_viewport_create(void)
{ {
@@ -76,12 +82,16 @@ GPUViewport *GPU_viewport_create(void)
viewport->txl = MEM_callocN(sizeof(TextureList), "TextureList"); viewport->txl = MEM_callocN(sizeof(TextureList), "TextureList");
viewport->psl = MEM_callocN(sizeof(PassList), "PassList"); viewport->psl = MEM_callocN(sizeof(PassList), "PassList");
viewport->stl = MEM_callocN(sizeof(StorageList), "StorageList"); viewport->stl = MEM_callocN(sizeof(StorageList), "StorageList");
viewport->fbl_mode = MEM_callocN(sizeof(FramebufferList), "FramebufferList");
viewport->txl_mode = MEM_callocN(sizeof(TextureList), "TextureList");
viewport->psl_mode = MEM_callocN(sizeof(PassList), "PassList");
viewport->stl_mode = MEM_callocN(sizeof(StorageList), "StorageList");
viewport->size[0] = viewport->size[1] = -1; viewport->size[0] = viewport->size[1] = -1;
return viewport; return viewport;
} }
void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs, void **pss, void **str) void GPU_viewport_get_engine_data(GPUViewport *viewport, FramebufferList **fbs, TextureList **txs, PassList **pss, StorageList **str)
{ {
*fbs = viewport->fbl; *fbs = viewport->fbl;
*txs = viewport->txl; *txs = viewport->txl;
@@ -89,64 +99,85 @@ void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs,
*str = viewport->stl; *str = viewport->stl;
} }
void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine) void GPU_viewport_get_mode_data(GPUViewport *viewport, FramebufferList **fbs, TextureList **txs, PassList **pss, StorageList **str)
{ {
*fbs = viewport->fbl_mode;
*txs = viewport->txl_mode;
*pss = viewport->psl_mode;
*str = viewport->stl_mode;
}
void GPU_viewport_bind(GPUViewport *viewport, const rcti *rect, const char *engine, int mode)
{
DefaultFramebufferList *dfbl = (DefaultFramebufferList *)viewport->fbl;
DefaultTextureList *dtxl = (DefaultTextureList *)viewport->txl;
/* add one pixel because of scissor test */ /* add one pixel because of scissor test */
int rect_w = BLI_rcti_size_x(rect) + 1, rect_h = BLI_rcti_size_y(rect) + 1; int rect_w = BLI_rcti_size_x(rect) + 1, rect_h = BLI_rcti_size_y(rect) + 1;
#ifndef WITH_VIEWPORT_CACHE_TEST #ifndef WITH_VIEWPORT_CACHE_TEST
/* TODO for testing only, we need proper cache invalidation */ /* TODO for testing only, we need proper cache invalidation */
GPU_viewport_passes_free(viewport); GPU_viewport_passes_free(viewport->psl);
GPU_viewport_passes_free(viewport->psl_mode);
#endif #endif
if (!STREQ(engine, viewport->engine_name)) { if (!STREQ(engine, viewport->engine_name)) {
GPU_viewport_storage_free(viewport); GPU_viewport_storage_free(viewport->stl);
GPU_viewport_buffers_free(viewport); GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
BLI_strncpy(viewport->engine_name, engine, 32); BLI_strncpy(viewport->engine_name, engine, 32);
} }
if (viewport->fbl->default_fb) { if (mode != viewport->mode) {
GPU_viewport_buffers_free(viewport->fbl_mode, viewport->txl_mode);
GPU_viewport_passes_free(viewport->psl_mode);
GPU_viewport_storage_free(viewport->stl_mode);
viewport->mode = mode;
}
if (dfbl->default_fb) {
if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) { if (rect_w != viewport->size[0] || rect_h != viewport->size[1]) {
GPU_viewport_buffers_free(viewport); GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
GPU_viewport_buffers_free(viewport->fbl_mode, viewport->txl_mode);
} }
} }
if (!viewport->fbl->default_fb) { if (!dfbl->default_fb) {
bool ok = true; bool ok = true;
viewport->size[0] = rect_w; viewport->size[0] = rect_w;
viewport->size[1] = rect_h; viewport->size[1] = rect_h;
viewport->fbl->default_fb = GPU_framebuffer_create(); dfbl->default_fb = GPU_framebuffer_create();
if (!viewport->fbl->default_fb) { if (!dfbl->default_fb) {
ok = false; ok = false;
goto cleanup; goto cleanup;
} }
/* Color */ /* Color */
/* No multi samples for now */ /* No multi samples for now */
viewport->txl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL); dtxl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL);
if (!viewport->txl->color) { if (!dtxl->color) {
ok = false; ok = false;
goto cleanup; goto cleanup;
} }
if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->color, 0)) { if (!GPU_framebuffer_texture_attach(dfbl->default_fb, dtxl->color, 0)) {
ok = false; ok = false;
goto cleanup; goto cleanup;
} }
/* Depth */ /* Depth */
viewport->txl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL); dtxl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
if (!viewport->txl->depth) { if (!dtxl->depth) {
ok = false; ok = false;
goto cleanup; goto cleanup;
} }
else if (!GPU_framebuffer_texture_attach(viewport->fbl->default_fb, viewport->txl->depth, 0)) { else if (!GPU_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0)) {
ok = false; ok = false;
goto cleanup; goto cleanup;
} }
else if (!GPU_framebuffer_check_valid(viewport->fbl->default_fb, NULL)) { else if (!GPU_framebuffer_check_valid(dfbl->default_fb, NULL)) {
ok = false; ok = false;
goto cleanup; goto cleanup;
} }
@@ -161,12 +192,14 @@ cleanup:
GPU_framebuffer_restore(); GPU_framebuffer_restore();
} }
GPU_framebuffer_slots_bind(viewport->fbl->default_fb, 0); GPU_framebuffer_slots_bind(dfbl->default_fb, 0);
} }
static void draw_ofs_to_screen(GPUViewport *viewport) static void draw_ofs_to_screen(GPUViewport *viewport)
{ {
GPUTexture *color = viewport->txl->color; DefaultTextureList *dtxl = (DefaultTextureList *)viewport->txl;
GPUTexture *color = dtxl->color;
const float w = (float)GPU_texture_width(color); const float w = (float)GPU_texture_width(color);
const float h = (float)GPU_texture_height(color); const float h = (float)GPU_texture_height(color);
@@ -204,7 +237,9 @@ static void draw_ofs_to_screen(GPUViewport *viewport)
void GPU_viewport_unbind(GPUViewport *viewport) void GPU_viewport_unbind(GPUViewport *viewport)
{ {
if (viewport->fbl->default_fb) { DefaultFramebufferList *dfbl = (DefaultFramebufferList *)viewport->fbl;
if (dfbl->default_fb) {
GPU_framebuffer_texture_unbind(NULL, NULL); GPU_framebuffer_texture_unbind(NULL, NULL);
GPU_framebuffer_restore(); GPU_framebuffer_restore();
@@ -215,10 +250,8 @@ void GPU_viewport_unbind(GPUViewport *viewport)
} }
} }
static void GPU_viewport_buffers_free(GPUViewport *viewport) static void GPU_viewport_buffers_free(FramebufferList *fbl, TextureList *txl)
{ {
FramebufferList *fbl = (FramebufferList *)viewport->fbl;
TextureList *txl = (TextureList *)viewport->txl;
int i; int i;
for (i = MAX_BUFFERS - 1; i > -1; --i) { for (i = MAX_BUFFERS - 1; i > -1; --i) {
GPUFrameBuffer *fb = fbl->framebuffers[i]; GPUFrameBuffer *fb = fbl->framebuffers[i];
@@ -236,10 +269,8 @@ static void GPU_viewport_buffers_free(GPUViewport *viewport)
} }
} }
static void GPU_viewport_storage_free(GPUViewport *viewport) static void GPU_viewport_storage_free(StorageList *stl)
{ {
StorageList *stl = (StorageList *)viewport->stl;
for (int i = MAX_STORAGE - 1; i > -1; --i) { for (int i = MAX_STORAGE - 1; i > -1; --i) {
void *storage = stl->storage[i]; void *storage = stl->storage[i];
if (storage) { if (storage) {
@@ -249,12 +280,9 @@ static void GPU_viewport_storage_free(GPUViewport *viewport)
} }
} }
static void GPU_viewport_passes_free(GPUViewport *viewport) static void GPU_viewport_passes_free(PassList *psl)
{ {
PassList *psl = (PassList *)viewport->psl; for (int i = MAX_PASSES - 1; i > -1; --i) {
int i;
for (i = MAX_PASSES - 1; i > -1; --i) {
struct DRWPass *pass = psl->passes[i]; struct DRWPass *pass = psl->passes[i];
if (pass) { if (pass) {
DRW_pass_free(pass); DRW_pass_free(pass);
@@ -267,14 +295,24 @@ static void GPU_viewport_passes_free(GPUViewport *viewport)
void GPU_viewport_free(GPUViewport *viewport) void GPU_viewport_free(GPUViewport *viewport)
{ {
GPU_viewport_debug_depth_free(viewport); GPU_viewport_debug_depth_free(viewport);
GPU_viewport_buffers_free(viewport);
GPU_viewport_passes_free(viewport); GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
GPU_viewport_storage_free(viewport); GPU_viewport_passes_free(viewport->psl);
GPU_viewport_storage_free(viewport->stl);
GPU_viewport_buffers_free(viewport->fbl_mode, viewport->txl_mode);
GPU_viewport_passes_free(viewport->psl_mode);
GPU_viewport_storage_free(viewport->stl_mode);
MEM_freeN(viewport->fbl); MEM_freeN(viewport->fbl);
MEM_freeN(viewport->txl); MEM_freeN(viewport->txl);
MEM_freeN(viewport->psl); MEM_freeN(viewport->psl);
MEM_freeN(viewport->stl); MEM_freeN(viewport->stl);
MEM_freeN(viewport->fbl_mode);
MEM_freeN(viewport->txl_mode);
MEM_freeN(viewport->psl_mode);
MEM_freeN(viewport->stl_mode);
} }
/****************** debug ********************/ /****************** debug ********************/