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
engines/clay
modes/
../blenkernel
../blenlib
@@ -55,12 +56,16 @@ set(SRC
intern/draw_cache.c
intern/draw_view.c
engines/clay/clay.c
modes/edit_mode.c
modes/object_mode.c
intern/DRW_render.h
intern/draw_mode_pass.h
intern/draw_cache.h
intern/draw_view.h
engines/clay/clay.h
modes/edit_mode.h
modes/object_mode.h
./DRW_engine.h
)

View File

@@ -126,17 +126,9 @@ enum {
/* keep it under MAX_PASSES */
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_cull;
struct DRWPass *depth_pass_hidden_wire;
struct DRWPass *clay_pass;
struct DRWPass *wire_overlay_pass;
struct DRWPass *wire_outline_pass;
struct DRWPass *wire_outline_pass_hidden_wire;
} CLAY_PassList;
//#define GTAO
@@ -286,8 +278,12 @@ MaterialEngineSettings *CLAY_material_settings_create(void)
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 */
if (!data.matcap_array) {
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],
&tex, 1);
}
}
static void CLAY_ssao_setup(void)
{
float invproj[4][4];
float dfdyfacs[2];
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 */
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}
};
int i;
float *size = DRW_viewport_size_get();
RenderEngineSettingsClay *settings = DRW_render_settings_get(NULL, RE_engine_id_BLENDER_CLAY);
/* SSAO setup */
{
float invproj[4][4];
float dfdyfacs[2];
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 */
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}
};
int i;
float *size = DRW_viewport_size_get();
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[1] = size[0] / 64.0;
data.ssao_params[2] = size[1] / 64.0;
data.ssao_params[3] = dfdyfacs[1]; /* dfdy sign for offscreen */
data.ssao_params[0] = settings->ssao_samples;
data.ssao_params[1] = size[0] / 64.0;
data.ssao_params[2] = size[1] / 64.0;
data.ssao_params[3] = dfdyfacs[1]; /* dfdy sign for offscreen */
/* invert the view matrix */
DRW_viewport_matrix_get(data.winmat, DRW_MAT_WIN);
invert_m4_m4(invproj, data.winmat);
/* invert the view matrix */
DRW_viewport_matrix_get(data.winmat, DRW_MAT_WIN);
invert_m4_m4(invproj, data.winmat);
/* convert the view vectors to view space */
for (i = 0; i < 3; i++) {
mul_m4_v4(invproj, viewvecs[i]);
/* 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]);
if (is_persp)
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
viewvecs[i][3] = 1.0;
/* convert the view vectors to view space */
for (i = 0; i < 3; i++) {
mul_m4_v4(invproj, viewvecs[i]);
/* 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]);
if (is_persp)
mul_v3_fl(viewvecs[i], 1.0f / viewvecs[i][2]);
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 */
data.viewvecs[1][0] -= data.viewvecs[0][0];
data.viewvecs[1][1] = data.viewvecs[2][1] - data.viewvecs[0][1];
/* we need to store the differences */
data.viewvecs[1][0] -= data.viewvecs[0][0];
data.viewvecs[1][1] = data.viewvecs[2][1] - data.viewvecs[0][1];
/* calculate a depth offset as well */
if (!is_persp) {
float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
mul_m4_v4(invproj, vec_far);
mul_v3_fl(vec_far, 1.0f / vec_far[3]);
data.viewvecs[1][2] = vec_far[2] - data.viewvecs[0][2];
/* calculate a depth offset as well */
if (!is_persp) {
float vec_far[] = {-1.0f, -1.0f, 1.0f, 1.0f};
mul_m4_v4(invproj, vec_far);
mul_v3_fl(vec_far, 1.0f / vec_far[3]);
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];
}
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);
DRWShadingGroup *clay_shgrp;
DRWShadingGroup *depth_shgrp;
DRWShadingGroup *depth_shgrp_cull;
DRWShadingGroup *depth_shgrp_hidden_wire;
CLAY_PassList *psl = DRW_engine_pass_list_get();
CLAY_StorageList *stl = DRW_engine_storage_list_get();
/* Depth Pass */
{
passes->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);
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);
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_hidden_wire = DRW_shgroup_create(data.depth_sh, passes->depth_pass_hidden_wire);
psl->depth_pass_cull = DRW_pass_create("Depth Pass Cull", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK);
psl->depth_pass = DRW_pass_create("Depth Pass", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
depth_shgrp_cull = DRW_shgroup_create(data.depth_sh, psl->depth_pass_cull);
depth_shgrp = DRW_shgroup_create(data.depth_sh, psl->depth_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;
memset(stl->storage->shgrps, 0, sizeof(DRWShadingGroup *) * MAX_CLAY_MAT);
}
}
/* Object Mode */
{
DRW_pass_setup_common(&passes->wire_overlay_pass,
&passes->wire_outline_pass,
&passes->wire_outline_pass_hidden_wire,
&passes->non_meshes_pass,
&passes->ob_center_pass);
static void CLAY_cache_populate(Object *ob)
{
const bContext *C = DRW_get_context();
int mode = CTX_data_mode_enum(C);
CLAY_StorageList *stl = DRW_engine_storage_list_get();
CLAY_PassList *psl = DRW_engine_pass_list_get();
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*/
DEG_OBJECT_ITER(sl, ob);
{
if ((ob->base_flag & BASE_VISIBLED) == 0) {
continue;
}
if (do_occlude_wire)
return;
CollectionEngineSettings *ces_mode_ob = BKE_object_collection_engine_get(ob, COLLECTION_MODE_OBJECT, "");
CollectionEngineSettings *ces_mode_ed = BKE_object_collection_engine_get(ob, COLLECTION_MODE_EDIT, "");
switch (ob->type) {
case OB_MESH:
geom = DRW_cache_surface_get(ob);
struct Batch *geom;
bool do_wire = BKE_collection_engine_property_value_get_bool(ces_mode_ob, "show_wire");
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;
/* Depth Prepass */
DRW_shgroup_call_add((do_cull) ? depth_shgrp_cull : depth_shgrp, geom, ob->obmat);
switch (ob->type) {
case OB_MESH:
geom = DRW_cache_surface_get(ob);
/* 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);
/* Shading */
clay_shgrp = CLAY_object_shgrp_get(ob, stl, psl);
DRW_shgroup_call_add(clay_shgrp, geom, ob->obmat);
break;
}
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);
}
static void CLAY_view_draw(RenderEngine *UNUSED(engine), const bContext *context)
{
DRW_viewport_init(context);
/* This function may run for multiple viewports
* so get the current viewport buffers */
CLAY_FramebufferList *buffers = NULL;
CLAY_TextureList *textures = NULL;
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_PassList *psl = DRW_engine_pass_list_get();
CLAY_FramebufferList *fbl = DRW_engine_framebuffer_list_get();
CLAY_engine_init();
/* TODO : tag to refresh by the deps graph */
/* 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
once = true;
#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 */
DRW_draw_background();
/* Pass 1 : Depth pre-pass */
DRW_draw_pass(passes->depth_pass);
DRW_draw_pass(passes->depth_pass_cull);
DRW_draw_pass(psl->depth_pass);
DRW_draw_pass(psl->depth_pass_cull);
/* Pass 2 : Duplicate depth */
/* 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 */
CLAY_ssao_setup();
DRW_draw_pass(passes->clay_pass);
DRW_draw_pass(psl->clay_pass);
/* Pass 4 : Overlays */
DRW_draw_grid();
//DRW_draw_pass(passes->wire_overlay_pass);
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();
/* At this point all shaded geometry should have been rendered and their depth written */
DRW_draw_mode_overlays();
/* Always finish by this */
DRW_state_reset();

View File

@@ -197,7 +197,7 @@ typedef enum {
DRW_MAT_WIN,
} 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);
float *DRW_viewport_size_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);
#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 */
void DRW_draw_pass(DRWPass *pass);
void DRW_draw_mode_overlays(void);
void DRW_state_reset(void);
/* Other */
void DRW_get_dfdy_factors(float dfdyfac[2]);
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__ */

View File

@@ -53,6 +53,8 @@
#include "UI_resources.h"
#include "object_mode.h"
#include "edit_mode.h"
#include "clay.h"
#define MAX_ATTRIB_NAME 32
@@ -159,9 +161,10 @@ enum {
static struct DRWGlobalState{
GPUShader *shader;
struct GPUFrameBuffer *default_framebuffer;
FramebufferList *current_fbl;
TextureList *current_txl;
PassList *current_psl;
FramebufferList *fbl, *fbl_mode;
TextureList *txl, *txl_mode;
PassList *psl, *psl_mode;
StorageList *stl, *stl_mode;
ListBase bound_texs;
int tex_bind_id;
float size[2];
@@ -852,15 +855,15 @@ static void draw_shgroup(DRWShadingGroup *shgroup)
break;
case DRW_UNIFORM_BUFFER:
/* restore index from lenght we abused */
GPU_texture_bind(DST.current_txl->textures[uni->length], uni->bindloc);
GPU_texture_compare_mode(DST.current_txl->textures[uni->length], false);
GPU_texture_filter_mode(DST.current_txl->textures[uni->length], false);
GPU_texture_bind(DST.txl->textures[uni->length], uni->bindloc);
GPU_texture_compare_mode(DST.txl->textures[uni->length], false);
GPU_texture_filter_mode(DST.txl->textures[uni->length], false);
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);
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;
case DRW_UNIFORM_BLOCK:
GPU_uniformbuffer_bind((GPUUniformBuffer *)uni->value, uni->bindloc);
@@ -1013,7 +1016,74 @@ void DRW_state_reset(void)
state |= DRW_STATE_DEPTH_LESS;
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
/* ******************************************* 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 ******************************************/
void *DRW_material_settings_get(Material *ma, const char *engine_name)
{
@@ -1155,25 +1225,22 @@ float *DRW_viewport_pixelsize_get(void)
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);
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 */
DefaultTextureList *txl = (DefaultTextureList *)*textures;
DefaultTextureList *txl = (DefaultTextureList *)DST.txl;
DST.size[0] = (float)GPU_texture_width(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.current_txl = (TextureList *)*textures;
DST.current_fbl = (FramebufferList *)*buffers;
DST.current_psl = (PassList *)*passes;
/* Refresh DST.screenvecs */
copy_v3_v3(DST.screenvecs[0], rv3d->viewinv[0]);
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)
{
/* TODO Use a dirty flag */
return (DST.current_psl->passes[0] == NULL);
return (DST.psl->passes[0] == NULL);
}
/* ****************************************** OTHER ***************************************** */
@@ -1218,6 +1285,46 @@ const bContext *DRW_get_context(void)
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 ***************************************** */
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 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])
{
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.
* The passes are populated by the rendering engine using the DRW_shgroup_* functions. */
void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPass **wire_outline_pass_hidden_wire,
DRWPass **non_meshes, DRWPass **ob_center)
* The passes are populated by the rendering engines using the DRW_shgroup_* functions.
* If a pass is not needed use NULL instead of the pass pointer */
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_EDIT, colorWireEdit);
@@ -179,67 +190,65 @@ void DRW_pass_setup_common(DRWPass **wire_overlay, DRWPass **wire_outline, DRWPa
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 */
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 */
/* 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 = DRW_pass_create("Wire + Outlines Pass", state);
*psl_wire_outline = DRW_pass_create("Wire + Outlines Pass", state);
}
if (wire_outline_pass_hidden_wire) {
/* 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) {
if (psl_non_meshes) {
/* Non Meshes Pass (Camera, empties, lamps ...) */
struct Batch *geom;
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND;
state |= DRW_STATE_WIRE;
*non_meshes = DRW_pass_create("Non Meshes Pass", state);
*psl_non_meshes = DRW_pass_create("Non Meshes Pass", state);
/* Empties */
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();
cube = shgroup_instance(*non_meshes, geom);
cube = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_circle_get();
circle = shgroup_instance(*non_meshes, geom);
circle = shgroup_instance(*psl_non_meshes, geom);
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();
cone = shgroup_instance(*non_meshes, geom);
cone = shgroup_instance(*psl_non_meshes, geom);
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();
single_arrow_line = shgroup_instance(*non_meshes, geom);
single_arrow_line = shgroup_instance(*psl_non_meshes, geom);
geom = DRW_cache_arrows_get();
arrows = shgroup_instance(*non_meshes, geom);
arrows = shgroup_instance(*psl_non_meshes, geom);
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 */
geom = DRW_cache_speaker_get();
speaker = shgroup_instance(*non_meshes, geom);
speaker = shgroup_instance(*psl_non_meshes, geom);
/* Lamps */
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
* for now we create 3 times the same VBO with only lamp center coordinates
* but ideally we would only create it once */
lamp_center = shgroup_dynpoints_uniform_color(*non_meshes, colorLampNoAlpha, &lampCenterSize);
lamp_center_group = shgroup_dynpoints_uniform_color(*non_meshes, colorGroup, &lampCenterSize);
lamp_center = shgroup_dynpoints_uniform_color(*psl_non_meshes, colorLampNoAlpha, &lampCenterSize);
lamp_center_group = shgroup_dynpoints_uniform_color(*psl_non_meshes, colorGroup, &lampCenterSize);
geom = DRW_cache_lamp_get();
lamp_circle = shgroup_instance_screenspace(*non_meshes, geom, &lampCircleRad);
lamp_circle_shadow = shgroup_instance_screenspace(*non_meshes, geom, &lampCircleShadowRad);
lamp_circle = shgroup_instance_screenspace(*psl_non_meshes, geom, &lampCircleRad);
lamp_circle_shadow = shgroup_instance_screenspace(*psl_non_meshes, geom, &lampCircleShadowRad);
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_groundpoint = shgroup_groundpoints_uniform_color(*non_meshes, colorLamp);
lamp_groundline = shgroup_groundlines_uniform_color(*psl_non_meshes, colorLamp);
lamp_groundpoint = shgroup_groundpoints_uniform_color(*psl_non_meshes, colorLamp);
/* 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);
}
if (ob_center) {
if (psl_ob_center) {
/* Object Center pass grouped by State */
DRWShadingGroup *grp;
static float colorDeselect[4], outlineColor[4];
static float outlineWidth, size;
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;
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);
/* 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, "outlineWidth", &outlineWidth, 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;
/* 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);
center_selected = grp;
/* 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);
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 *********************************************** */
@@ -373,7 +389,7 @@ static int draw_object_wire_theme(Object *ob, float **color)
return theme_id;
}
void DRW_shgroup_wire_overlay(DRWPass *wire_overlay, Object *ob)
void DRW_shgroup_wire_overlay(Object *ob)
{
#if 1
struct Batch *geom = DRW_cache_wire_overlay_get(ob);
@@ -395,8 +411,7 @@ void DRW_shgroup_wire_overlay(DRWPass *wire_overlay, Object *ob)
#endif
}
void DRW_shgroup_wire_outline(DRWPass *wire_outline, Object *ob,
const bool do_front, const bool do_back, const bool do_outline)
void DRW_shgroup_wire_outline(Object *ob, const bool do_front, const bool do_back, const bool do_outline)
{
GPUShader *sh;
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 ********************** */
static void DRW_draw_lamp(Object *ob)
void DRW_shgroup_lamp(Object *ob)
{
Lamp *la = ob->data;
float *color;
@@ -489,7 +504,7 @@ static void DRW_draw_lamp(Object *ob)
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;
draw_object_wire_theme(ob, &color);
@@ -517,12 +532,11 @@ static void DRW_draw_empty(Object *ob)
case OB_ARROWS:
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);
/* TODO Missing axes names */
break;
}
}
static void DRW_draw_speaker(Object *ob)
void DRW_shgroup_speaker(Object *ob)
{
float *color;
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);
}
void DRW_shgroup_non_meshes(DRWPass *UNUSED(non_meshes), 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)
void DRW_shgroup_relationship_lines(Object *ob)
{
if (ob->parent) {
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 **************************** */
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) {
DRW_shgroup_dynamic_call_add(center_selected, ob->obmat[3]);

View File

@@ -30,15 +30,18 @@ struct DRWPass;
struct Batch;
struct Object;
void DRW_pass_setup_common(struct DRWPass **wire_overlay, struct DRWPass **wire_outline, struct DRWPass **wire_outline_pass_hidden_wire,
struct DRWPass **non_meshes, struct DRWPass **ob_center);
void DRW_mode_passes_setup(struct DRWPass **psl_wire_overlay,
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_outline(
struct DRWPass *wire_outline, struct Object *ob, const bool do_front, const bool do_back, const bool do_outline);
void DRW_shgroup_non_meshes(struct DRWPass *non_meshes, struct Object *ob);
void DRW_shgroup_relationship_lines(struct DRWPass *non_meshes, struct Object *ob);
void DRW_shgroup_object_center(struct DRWPass *ob_center, struct Object *ob);
void DRW_shgroup_wire_overlay(struct Object *ob);
void DRW_shgroup_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_speaker(struct Object *ob);
void DRW_shgroup_relationship_lines(struct Object *ob);
void DRW_shgroup_object_center(struct Object *ob);
#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);
View3D *v3d = CTX_wm_view3d(C);
int mode = CTX_data_mode_enum(C);
RegionView3D *rv3d = ar->regiondata;
/* TODO layers - In the future we should get RE from Layers */
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)
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
* 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;
typedef struct PassList {
struct DRWPass *passes[MAX_TEXTURES];
struct DRWPass *passes[MAX_PASSES];
} PassList;
typedef struct StorageList {
@@ -79,11 +79,12 @@ typedef struct DefaultPassList {
} DefaultPassList;
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_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 */
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];
/* Viewport Buffer Storage */
/* TODO indentify to what engine conf are theses buffers */
DefaultFramebufferList *fbl;
DefaultTextureList *txl;
DefaultPassList *psl;
FramebufferList *fbl;
TextureList *txl;
PassList *psl;
StorageList *stl;
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_passes_free(GPUViewport *viewport);
static void GPU_viewport_storage_free(GPUViewport *viewport);
static void GPU_viewport_buffers_free(FramebufferList *fbl, TextureList *txl);
static void GPU_viewport_storage_free(StorageList *stl);
static void GPU_viewport_passes_free(PassList *psl);
GPUViewport *GPU_viewport_create(void)
{
@@ -76,12 +82,16 @@ GPUViewport *GPU_viewport_create(void)
viewport->txl = MEM_callocN(sizeof(TextureList), "TextureList");
viewport->psl = MEM_callocN(sizeof(PassList), "PassList");
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;
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;
*txs = viewport->txl;
@@ -89,64 +99,85 @@ void GPU_viewport_get_engine_data(GPUViewport *viewport, void **fbs, void **txs,
*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 */
int rect_w = BLI_rcti_size_x(rect) + 1, rect_h = BLI_rcti_size_y(rect) + 1;
#ifndef WITH_VIEWPORT_CACHE_TEST
/* 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
if (!STREQ(engine, viewport->engine_name)) {
GPU_viewport_storage_free(viewport);
GPU_viewport_buffers_free(viewport);
GPU_viewport_storage_free(viewport->stl);
GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
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]) {
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;
viewport->size[0] = rect_w;
viewport->size[1] = rect_h;
viewport->fbl->default_fb = GPU_framebuffer_create();
if (!viewport->fbl->default_fb) {
dfbl->default_fb = GPU_framebuffer_create();
if (!dfbl->default_fb) {
ok = false;
goto cleanup;
}
/* Color */
/* No multi samples for now */
viewport->txl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL);
if (!viewport->txl->color) {
dtxl->color = GPU_texture_create_2D(rect_w, rect_h, NULL, NULL);
if (!dtxl->color) {
ok = false;
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;
goto cleanup;
}
/* Depth */
viewport->txl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
if (!viewport->txl->depth) {
dtxl->depth = GPU_texture_create_depth(rect_w, rect_h, NULL);
if (!dtxl->depth) {
ok = false;
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;
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;
goto cleanup;
}
@@ -161,12 +192,14 @@ cleanup:
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)
{
GPUTexture *color = viewport->txl->color;
DefaultTextureList *dtxl = (DefaultTextureList *)viewport->txl;
GPUTexture *color = dtxl->color;
const float w = (float)GPU_texture_width(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)
{
if (viewport->fbl->default_fb) {
DefaultFramebufferList *dfbl = (DefaultFramebufferList *)viewport->fbl;
if (dfbl->default_fb) {
GPU_framebuffer_texture_unbind(NULL, NULL);
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;
for (i = MAX_BUFFERS - 1; i > -1; --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) {
void *storage = stl->storage[i];
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;
int i;
for (i = MAX_PASSES - 1; i > -1; --i) {
for (int i = MAX_PASSES - 1; i > -1; --i) {
struct DRWPass *pass = psl->passes[i];
if (pass) {
DRW_pass_free(pass);
@@ -267,14 +295,24 @@ static void GPU_viewport_passes_free(GPUViewport *viewport)
void GPU_viewport_free(GPUViewport *viewport)
{
GPU_viewport_debug_depth_free(viewport);
GPU_viewport_buffers_free(viewport);
GPU_viewport_passes_free(viewport);
GPU_viewport_storage_free(viewport);
GPU_viewport_buffers_free(viewport->fbl, viewport->txl);
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->txl);
MEM_freeN(viewport->psl);
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 ********************/