Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuca Rood <dev@lucarood.com>2017-05-03 19:55:40 +0300
committerLuca Rood <dev@lucarood.com>2017-05-03 19:57:35 +0300
commit20f95de6ba2d32dcff553251ff4de2efd5b76955 (patch)
tree3249c645c766757e18f6231afe4e90ad76b996bb /source/blender/draw/modes/paint_weight_mode.c
parentb9451c04931d228161c1fb212c6c7a09545a86b7 (diff)
Weight painting with draw manager
This implements weight rendering with the draw manager, with all drawing options (Shading, wire, face masking, vertex masking). This is part of T51208 Reviewers: campbellbarton Subscribers: dfelinto Differential Revision: https://developer.blender.org/D2654
Diffstat (limited to 'source/blender/draw/modes/paint_weight_mode.c')
-rw-r--r--source/blender/draw/modes/paint_weight_mode.c244
1 files changed, 103 insertions, 141 deletions
diff --git a/source/blender/draw/modes/paint_weight_mode.c b/source/blender/draw/modes/paint_weight_mode.c
index fe5fdf9ba91..2819dcbc6c5 100644
--- a/source/blender/draw/modes/paint_weight_mode.c
+++ b/source/blender/draw/modes/paint_weight_mode.c
@@ -33,53 +33,34 @@
#include "draw_mode_engines.h"
-/* If needed, contains all global/Theme colors
- * Add needed theme colors / values to DRW_globals_update() and update UBO
- * Not needed for constant color. */
+#include "DNA_mesh_types.h"
+
+#include "BKE_mesh.h"
+
extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */
extern struct GlobalsUboStorage ts; /* draw_common.c */
/* *********** LISTS *********** */
-/* All lists are per viewport specific datas.
- * They are all free when viewport changes engines
- * or is free itself. Use PAINT_WEIGHT_engine_init() to
- * initialize most of them and PAINT_WEIGHT_cache_init()
- * for PAINT_WEIGHT_PassList */
typedef struct PAINT_WEIGHT_PassList {
- /* Declare all passes here and init them in
- * PAINT_WEIGHT_cache_init().
- * Only contains (DRWPass *) */
- struct DRWPass *pass;
+ struct DRWPass *weight_faces;
+ struct DRWPass *wire_overlay;
+ struct DRWPass *face_overlay;
+ struct DRWPass *vert_overlay;
} PAINT_WEIGHT_PassList;
typedef struct PAINT_WEIGHT_FramebufferList {
- /* Contains all framebuffer objects needed by this engine.
- * Only contains (GPUFrameBuffer *) */
- struct GPUFrameBuffer *fb;
} PAINT_WEIGHT_FramebufferList;
typedef struct PAINT_WEIGHT_TextureList {
- /* Contains all framebuffer textures / utility textures
- * needed by this engine. Only viewport specific textures
- * (not per object). Only contains (GPUTexture *) */
- struct GPUTexture *texture;
} PAINT_WEIGHT_TextureList;
typedef struct PAINT_WEIGHT_StorageList {
- /* Contains any other memory block that the engine needs.
- * Only directly MEM_(m/c)allocN'ed blocks because they are
- * free with MEM_freeN() when viewport is freed.
- * (not per object) */
- struct CustomStruct *block;
struct PAINT_WEIGHT_PrivateData *g_data;
} PAINT_WEIGHT_StorageList;
typedef struct PAINT_WEIGHT_Data {
- /* Struct returned by DRW_viewport_engine_data_get.
- * If you don't use one of these, just make it a (void *) */
- // void *fbl;
- void *engine_type; /* Required */
+ void *engine_type;
PAINT_WEIGHT_FramebufferList *fbl;
PAINT_WEIGHT_TextureList *txl;
PAINT_WEIGHT_PassList *psl;
@@ -89,54 +70,46 @@ typedef struct PAINT_WEIGHT_Data {
/* *********** STATIC *********** */
static struct {
- /* Custom shaders :
- * Add sources to source/blender/draw/modes/shaders
- * init in PAINT_WEIGHT_engine_init();
- * free in PAINT_WEIGHT_engine_free(); */
- struct GPUShader *custom_shader;
+ struct GPUShader *weight_face_shader;
+ struct GPUShader *flat_overlay_shader;
+ struct GPUShader *vert_overlay_shader;
+ int actdef;
} e_data = {NULL}; /* Engine data */
typedef struct PAINT_WEIGHT_PrivateData {
- /* This keeps the references of the shading groups for
- * easy access in PAINT_WEIGHT_cache_populate() */
- DRWShadingGroup *group;
+ DRWShadingGroup *fweights_shgrp;
+ DRWShadingGroup *lwire_shgrp;
+ DRWShadingGroup *face_shgrp;
+ DRWShadingGroup *vert_shgrp;
} PAINT_WEIGHT_PrivateData;
/* *********** FUNCTIONS *********** */
-/* Init Textures, Framebuffers, Storage and Shaders.
- * It is called for every frames.
- * (Optional) */
-static void PAINT_WEIGHT_engine_init(void *vedata)
+static void PAINT_WEIGHT_engine_init(void *UNUSED(vedata))
{
- PAINT_WEIGHT_TextureList *txl = ((PAINT_WEIGHT_Data *)vedata)->txl;
- PAINT_WEIGHT_FramebufferList *fbl = ((PAINT_WEIGHT_Data *)vedata)->fbl;
- PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+
+ if (e_data.actdef != draw_ctx->sl->basact->object->actdef) {
+ e_data.actdef = draw_ctx->sl->basact->object->actdef;
+
+ BKE_mesh_batch_cache_dirty(draw_ctx->sl->basact->object->data, BKE_MESH_BATCH_DIRTY_WEIGHT);
+ }
+
+ if (!e_data.weight_face_shader) {
+ e_data.weight_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA);
+ }
+
+ if (!e_data.flat_overlay_shader) {
+ e_data.flat_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_FLAT_COLOR);
+ }
- UNUSED_VARS(txl, fbl, stl);
-
- /* Init Framebuffers like this: order is attachment order (for color texs) */
- /*
- * DRWFboTexture tex[2] = {{&txl->depth, DRW_BUF_DEPTH_24, 0},
- * {&txl->color, DRW_BUF_RGBA_8, DRW_TEX_FILTER}};
- */
-
- /* DRW_framebuffer_init takes care of checking if
- * the framebuffer is valid and has the right size*/
- /*
- * float *viewport_size = DRW_viewport_size_get();
- * DRW_framebuffer_init(&fbl->occlude_wire_fb,
- * (int)viewport_size[0], (int)viewport_size[1],
- * tex, 2);
- */
-
- if (!e_data.custom_shader) {
- e_data.custom_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
+ if (!e_data.vert_overlay_shader) {
+ e_data.vert_overlay_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_FIXED_SIZE_VARYING_COLOR);
}
}
-/* Here init all passes and shading groups
- * Assume that all Passes are NULL */
+static float world_light;
+
static void PAINT_WEIGHT_cache_init(void *vedata)
{
PAINT_WEIGHT_PassList *psl = ((PAINT_WEIGHT_Data *)vedata)->psl;
@@ -149,105 +122,94 @@ static void PAINT_WEIGHT_cache_init(void *vedata)
{
/* Create a pass */
- DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND | DRW_STATE_WIRE;
- psl->pass = DRW_pass_create("My Pass", state);
-
- /* Create a shadingGroup using a function in draw_common.c or custom one */
- /*
- * stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire);
- * -- or --
- * stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
- */
- stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
-
- /* Uniforms need a pointer to it's value so be sure it's accessible at
- * any given time (i.e. use static vars) */
- static float color[4] = {0.2f, 0.5f, 0.3f, 1.0};
- DRW_shgroup_uniform_vec4(stl->g_data->group, "color", color, 1);
+ psl->weight_faces = DRW_pass_create("Weight Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
+
+ stl->g_data->fweights_shgrp = DRW_shgroup_create(e_data.weight_face_shader, psl->weight_faces);
+
+ static float light[3] = {-0.3f, 0.5f, 1.0f};
+ static float alpha = 1.0f;
+ DRW_shgroup_uniform_vec3(stl->g_data->fweights_shgrp, "light", light, 1);
+ DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "alpha", &alpha, 1);
+ DRW_shgroup_uniform_float(stl->g_data->fweights_shgrp, "global", &world_light, 1);
}
-}
+ {
+ psl->wire_overlay = DRW_pass_create("Wire Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
-/* Add geometry to shadingGroups. Execute for each objects */
-static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob)
-{
- PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl;
+ stl->g_data->lwire_shgrp = DRW_shgroup_create(e_data.flat_overlay_shader, psl->wire_overlay);
+ }
- if (ob->type == OB_MESH) {
- /* Get geometry cache */
- struct Batch *geom = DRW_cache_mesh_surface_get(ob);
+ {
+ psl->face_overlay = DRW_pass_create("Wire Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_BLEND);
+
+ stl->g_data->face_shgrp = DRW_shgroup_create(e_data.flat_overlay_shader, psl->face_overlay);
+ }
+
+ {
+ psl->vert_overlay = DRW_pass_create("Wire Pass", DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS);
- /* Add geom to a shading group */
- DRW_shgroup_call_add(stl->g_data->group, geom, ob->obmat);
+ stl->g_data->vert_shgrp = DRW_shgroup_create(e_data.vert_overlay_shader, psl->vert_overlay);
}
}
-/* Optional: Post-cache_populate callback */
-static void PAINT_WEIGHT_cache_finish(void *vedata)
+static void PAINT_WEIGHT_cache_populate(void *vedata, Object *ob)
{
- PAINT_WEIGHT_PassList *psl = ((PAINT_WEIGHT_Data *)vedata)->psl;
PAINT_WEIGHT_StorageList *stl = ((PAINT_WEIGHT_Data *)vedata)->stl;
-
- /* Do something here! dependant on the objects gathered */
- UNUSED_VARS(psl, stl);
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ SceneLayer *sl = draw_ctx->sl;
+
+ if (ob->type == OB_MESH && ob == sl->basact->object) {
+ IDProperty *ces_mode_pw = BKE_object_collection_engine_get(ob, COLLECTION_MODE_PAINT_WEIGHT, "");
+ bool use_wire = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_wire");
+ char flag = ((Mesh *)ob->data)->editflag;
+ struct Batch *geom;
+
+ world_light = BKE_collection_engine_property_value_get_bool(ces_mode_pw, "use_shading") ? 0.5f : 1.0f;
+
+ geom = DRW_cache_mesh_surface_weights_get(ob);
+ DRW_shgroup_call_add(stl->g_data->fweights_shgrp, geom, ob->obmat);
+
+ if (flag & ME_EDIT_PAINT_FACE_SEL || use_wire) {
+ geom = DRW_cache_mesh_edges_weight_overlay_get(ob, use_wire, flag & ME_EDIT_PAINT_FACE_SEL);
+ DRW_shgroup_call_add(stl->g_data->lwire_shgrp, geom, ob->obmat);
+ }
+
+ if (flag & ME_EDIT_PAINT_FACE_SEL) {
+ geom = DRW_cache_mesh_faces_weight_overlay_get(ob);
+ DRW_shgroup_call_add(stl->g_data->face_shgrp, geom, ob->obmat);
+ }
+
+ if (flag & ME_EDIT_PAINT_VERT_SEL) {
+ geom = DRW_cache_mesh_verts_weight_overlay_get(ob);
+ DRW_shgroup_call_add(stl->g_data->vert_shgrp, geom, ob->obmat);
+ }
+ }
}
-/* Draw time ! Control rendering pipeline from here */
static void PAINT_WEIGHT_draw_scene(void *vedata)
{
PAINT_WEIGHT_PassList *psl = ((PAINT_WEIGHT_Data *)vedata)->psl;
- PAINT_WEIGHT_FramebufferList *fbl = ((PAINT_WEIGHT_Data *)vedata)->fbl;
- /* Default framebuffer and texture */
- DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
- DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
-
- UNUSED_VARS(fbl, dfbl, dtxl);
-
- /* Show / hide entire passes, swap framebuffers ... whatever you fancy */
- /*
- * DRW_framebuffer_texture_detach(dtxl->depth);
- * DRW_framebuffer_bind(fbl->custom_fb);
- * DRW_draw_pass(psl->pass);
- * DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
- * DRW_framebuffer_bind(dfbl->default_fb);
- */
-
- /* ... or just render passes on default framebuffer. */
- DRW_draw_pass(psl->pass);
-
- /* If you changed framebuffer, double check you rebind
- * the default one with its textures attached before finishing */
+ DRW_draw_pass(psl->weight_faces);
+ DRW_draw_pass(psl->face_overlay);
+ DRW_draw_pass(psl->wire_overlay);
+ DRW_draw_pass(psl->vert_overlay);
}
-/* Cleanup when destroying the engine.
- * This is not per viewport ! only when quitting blender.
- * Mostly used for freeing shaders */
static void PAINT_WEIGHT_engine_free(void)
{
- // DRW_SHADER_FREE_SAFE(custom_shader);
}
-/* Create collection settings here.
- *
- * Be sure to add this function there :
- * source/blender/draw/DRW_engine.h
- * source/blender/blenkernel/intern/layer.c
- * source/blenderplayer/bad_level_call_stubs/stubs.c
- *
- * And relevant collection settings to :
- * source/blender/makesrna/intern/rna_scene.c
- * source/blender/blenkernel/intern/layer.c
- */
-#if 0
-void PAINT_WEIGHT_collection_settings_create(CollectionEngineSettings *ces)
+void PAINT_WEIGHT_collection_settings_create(IDProperty *properties)
{
- BLI_assert(ces);
- // BKE_collection_engine_property_add_int(ces, "my_bool_prop", false);
- // BKE_collection_engine_property_add_int(ces, "my_int_prop", 0);
- // BKE_collection_engine_property_add_float(ces, "my_float_prop", 0.0f);
+ BLI_assert(properties &&
+ properties->type == IDP_GROUP &&
+ properties->subtype == IDP_GROUP_SUB_MODE_PAINT_WEIGHT);
+
+ BKE_collection_engine_property_add_bool(properties, "use_shading", true);
+ BKE_collection_engine_property_add_bool(properties, "use_wire", false);
}
-#endif
+
static const DrawEngineDataSize PAINT_WEIGHT_data_size = DRW_VIEWPORT_DATA_SIZE(PAINT_WEIGHT_Data);
@@ -259,7 +221,7 @@ DrawEngineType draw_engine_paint_weight_type = {
&PAINT_WEIGHT_engine_free,
&PAINT_WEIGHT_cache_init,
&PAINT_WEIGHT_cache_populate,
- &PAINT_WEIGHT_cache_finish,
- NULL, /* draw_background but not needed by mode engines */
+ NULL,
+ NULL,
&PAINT_WEIGHT_draw_scene
};