This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/draw/engines/gpencil/gpencil_engine.h

454 lines
14 KiB
C++

/*
* 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.
*
* Copyright 2017, Blender Foundation.
*/
/** \file
* \ingroup draw
*/
#pragma once
#include "DNA_gpencil_types.h"
#include "DRW_render.h"
#include "BLI_bitmap.h"
#include "GPU_batch.h"
#ifdef __cplusplus
extern "C" {
#endif
extern DrawEngineType draw_engine_gpencil_type;
struct GPENCIL_Data;
struct GPENCIL_StorageList;
struct GPUBatch;
struct GpencilBatchCache;
struct Object;
struct RenderEngine;
struct RenderLayer;
struct View3D;
struct bGPDstroke;
/* used to convert pixel scale. */
#define GPENCIL_PIXEL_FACTOR 2000.0f
/* used to expand VBOs. Size has a big impact in the speed */
#define GPENCIL_VBO_BLOCK_SIZE 128
#define GP_MAX_MASKBITS 256
/* UBO structure. Watch out for padding. Must match GLSL declaration. */
typedef struct gpMaterial {
float stroke_color[4];
float fill_color[4];
float fill_mix_color[4];
float fill_uv_transform[3][2], alignment_rot_cos, alignment_rot_sin;
float stroke_texture_mix;
float stroke_u_scale;
float fill_texture_mix;
int flag;
} gpMaterial;
/* gpMaterial->flag */
/* WATCH Keep in sync with GLSL declaration. */
#define GP_STROKE_ALIGNMENT_STROKE 1
#define GP_STROKE_ALIGNMENT_OBJECT 2
#define GP_STROKE_ALIGNMENT_FIXED 3
#define GP_STROKE_ALIGNMENT 0x3
#define GP_STROKE_OVERLAP (1 << 2)
#define GP_STROKE_TEXTURE_USE (1 << 3)
#define GP_STROKE_TEXTURE_STENCIL (1 << 4)
#define GP_STROKE_TEXTURE_PREMUL (1 << 5)
#define GP_STROKE_DOTS (1 << 6)
#define GP_STROKE_HOLDOUT (1 << 7)
#define GP_FILL_HOLDOUT (1 << 8)
#define GP_FILL_TEXTURE_USE (1 << 10)
#define GP_FILL_TEXTURE_PREMUL (1 << 11)
#define GP_FILL_TEXTURE_CLIP (1 << 12)
#define GP_FILL_GRADIENT_USE (1 << 13)
#define GP_FILL_GRADIENT_RADIAL (1 << 14)
#define GPENCIL_LIGHT_BUFFER_LEN 128
/* UBO structure. Watch out for padding. Must match GLSL declaration. */
typedef struct gpLight {
float color[3], type;
float right[3], spotsize;
float up[3], spotblend;
float forward[4];
float position[4];
} gpLight;
/* gpLight->type */
/* WATCH Keep in sync with GLSL declaration. */
#define GP_LIGHT_TYPE_POINT 0.0
#define GP_LIGHT_TYPE_SPOT 1.0
#define GP_LIGHT_TYPE_SUN 2.0
#define GP_LIGHT_TYPE_AMBIENT 3.0
BLI_STATIC_ASSERT_ALIGN(gpMaterial, 16)
BLI_STATIC_ASSERT_ALIGN(gpLight, 16)
/* *********** Draw Datas *********** */
typedef struct GPENCIL_MaterialPool {
/* Linklist. */
struct GPENCIL_MaterialPool *next;
/* GPU representation of materials. */
gpMaterial mat_data[GP_MATERIAL_BUFFER_LEN];
/* Matching ubo. */
struct GPUUniformBuf *ubo;
/* Texture per material. NULL means none. */
struct GPUTexture *tex_fill[GP_MATERIAL_BUFFER_LEN];
struct GPUTexture *tex_stroke[GP_MATERIAL_BUFFER_LEN];
/* Number of material used in this pool. */
int used_count;
} GPENCIL_MaterialPool;
typedef struct GPENCIL_LightPool {
/* GPU representation of materials. */
gpLight light_data[GPENCIL_LIGHT_BUFFER_LEN];
/* Matching ubo. */
struct GPUUniformBuf *ubo;
/* Number of light in the pool. */
int light_used;
} GPENCIL_LightPool;
typedef struct GPENCIL_ViewLayerData {
/* GPENCIL_tObject */
struct BLI_memblock *gp_object_pool;
/* GPENCIL_tLayer */
struct BLI_memblock *gp_layer_pool;
/* GPENCIL_tVfx */
struct BLI_memblock *gp_vfx_pool;
/* GPENCIL_MaterialPool */
struct BLI_memblock *gp_material_pool;
/* GPENCIL_LightPool */
struct BLI_memblock *gp_light_pool;
/* BLI_bitmap */
struct BLI_memblock *gp_maskbit_pool;
} GPENCIL_ViewLayerData;
/* *********** GPencil *********** */
typedef struct GPENCIL_tVfx {
/** Linklist */
struct GPENCIL_tVfx *next;
DRWPass *vfx_ps;
/* Frame-buffer reference since it may not be allocated yet. */
GPUFrameBuffer **target_fb;
} GPENCIL_tVfx;
typedef struct GPENCIL_tLayer {
/** Linklist */
struct GPENCIL_tLayer *next;
/** Geometry pass (draw all strokes). */
DRWPass *geom_ps;
/** Blend pass to composite onto the target buffer (blends modes). NULL if not needed. */
DRWPass *blend_ps;
/** First shading group created for this layer. Contains all uniforms. */
DRWShadingGroup *base_shgrp;
/** Layer id of the mask. */
BLI_bitmap *mask_bits;
BLI_bitmap *mask_invert_bits;
/** Index in the layer list. Used as id for masking. */
int layer_id;
} GPENCIL_tLayer;
typedef struct GPENCIL_tObject {
/** Linklist */
struct GPENCIL_tObject *next;
struct {
GPENCIL_tLayer *first, *last;
} layers;
struct {
GPENCIL_tVfx *first, *last;
} vfx;
/* Distance to camera. Used for sorting. */
float camera_z;
/* Used for stroke thickness scaling. */
float object_scale;
/* Normal used for shading. Based on view angle. */
float plane_normal[3];
/* Used for drawing depth merge pass. */
float plane_mat[4][4];
bool is_drawmode3d;
/* Use Material Holdout. */
bool do_mat_holdout;
} GPENCIL_tObject;
/* *********** LISTS *********** */
typedef struct GPENCIL_StorageList {
struct GPENCIL_PrivateData *pd;
} GPENCIL_StorageList;
typedef struct GPENCIL_PassList {
/* Composite the main GPencil buffer onto the rendered image. */
struct DRWPass *composite_ps;
/* Composite the object depth to the default depth buffer to occlude overlays. */
struct DRWPass *merge_depth_ps;
/* Invert mask buffer content. */
struct DRWPass *mask_invert_ps;
/* Anti-Aliasing. */
struct DRWPass *smaa_edge_ps;
struct DRWPass *smaa_weight_ps;
struct DRWPass *smaa_resolve_ps;
} GPENCIL_PassList;
typedef struct GPENCIL_FramebufferList {
struct GPUFrameBuffer *render_fb;
struct GPUFrameBuffer *gpencil_fb;
struct GPUFrameBuffer *snapshot_fb;
struct GPUFrameBuffer *layer_fb;
struct GPUFrameBuffer *object_fb;
struct GPUFrameBuffer *mask_fb;
struct GPUFrameBuffer *smaa_edge_fb;
struct GPUFrameBuffer *smaa_weight_fb;
} GPENCIL_FramebufferList;
typedef struct GPENCIL_TextureList {
/* Dummy texture to avoid errors cause by empty sampler. */
struct GPUTexture *dummy_texture;
/* Snapshot for smoother drawing. */
struct GPUTexture *snapshot_depth_tx;
struct GPUTexture *snapshot_color_tx;
struct GPUTexture *snapshot_reveal_tx;
/* Textures used by Antialiasing. */
struct GPUTexture *smaa_area_tx;
struct GPUTexture *smaa_search_tx;
/* Textures used during render. Containing underlying rendered scene. */
struct GPUTexture *render_depth_tx;
struct GPUTexture *render_color_tx;
} GPENCIL_TextureList;
typedef struct GPENCIL_Data {
void *engine_type; /* Required */
struct GPENCIL_FramebufferList *fbl;
struct GPENCIL_TextureList *txl;
struct GPENCIL_PassList *psl;
struct GPENCIL_StorageList *stl;
} GPENCIL_Data;
/* *********** STATIC *********** */
typedef struct GPENCIL_PrivateData {
/* Pointers copied from GPENCIL_ViewLayerData. */
struct BLI_memblock *gp_object_pool;
struct BLI_memblock *gp_layer_pool;
struct BLI_memblock *gp_vfx_pool;
struct BLI_memblock *gp_material_pool;
struct BLI_memblock *gp_light_pool;
struct BLI_memblock *gp_maskbit_pool;
/* Last used material pool. */
GPENCIL_MaterialPool *last_material_pool;
/* Last used light pool. */
GPENCIL_LightPool *last_light_pool;
/* Common lightpool containing all lights in the scene. */
GPENCIL_LightPool *global_light_pool;
/* Common lightpool containing one ambient white light. */
GPENCIL_LightPool *shadeless_light_pool;
/* Linked list of tObjects. */
struct {
GPENCIL_tObject *first, *last;
} tobjects, tobjects_infront;
/* Temp Textures (shared with other engines). */
GPUTexture *depth_tx;
GPUTexture *color_tx;
GPUTexture *color_layer_tx;
GPUTexture *color_object_tx;
/* Revealage is 1 - alpha */
GPUTexture *reveal_tx;
GPUTexture *reveal_layer_tx;
GPUTexture *reveal_object_tx;
/* Mask texture */
GPUTexture *mask_tx;
/* Anti-Aliasing. */
GPUTexture *smaa_edge_tx;
GPUTexture *smaa_weight_tx;
/* Pointer to dtxl->depth */
GPUTexture *scene_depth_tx;
GPUFrameBuffer *scene_fb;
/* Copy of txl->dummy_tx */
GPUTexture *dummy_tx;
/* Copy of v3d->shading.single_color. */
float v3d_single_color[3];
/* Copy of v3d->shading.color_type or -1 to ignore. */
int v3d_color_type;
/* Current frame */
int cfra;
/* If we are rendering for final render (F12). */
bool is_render;
/* If we are in viewport display (used for VFX). */
bool is_viewport;
/* True in selection and auto_depth drawing */
bool draw_depth_only;
/* Is shading set to wireframe. */
bool draw_wireframe;
/* Used by the depth merge step. */
int is_stroke_order_3d;
float object_bound_mat[4][4];
/* Used for computing object distance to camera. */
float camera_z_axis[3], camera_z_offset;
float camera_pos[3];
/* Pseudo depth of field parameter. Used to scale blur radius. */
float dof_params[2];
/* Used for DoF Setup. */
Object *camera;
/* Copy of draw_ctx->view_layer for convenience. */
struct ViewLayer *view_layer;
/* Copy of draw_ctx->scene for convenience. */
struct Scene *scene;
/* Copy of draw_ctx->vie3d for convenience. */
struct View3D *v3d;
/* Active object. */
Object *obact;
/* Object being in draw mode. */
struct bGPdata *sbuffer_gpd;
/* Layer to append the temp stroke to. */
struct bGPDlayer *sbuffer_layer;
/* Temporary stroke currently being drawn. */
struct bGPDstroke *sbuffer_stroke;
/* List of temp objects containing the stroke. */
struct {
GPENCIL_tObject *first, *last;
} sbuffer_tobjects;
/* Batches containing the temp stroke. */
GPUBatch *stroke_batch;
GPUBatch *fill_batch;
bool do_fast_drawing;
bool snapshot_buffer_dirty;
/* Display onion skinning */
bool do_onion;
/* Playing animation */
bool playing;
/* simplify settings */
bool simplify_fill;
bool simplify_fx;
bool simplify_antialias;
/* Use scene lighting or flat shading (global setting). */
bool use_lighting;
/* Use physical lights or just ambient lighting. */
bool use_lights;
/* Do we need additional frame-buffers? */
bool use_layer_fb;
bool use_object_fb;
bool use_mask_fb;
/* Some blend mode needs to add negative values.
* This is only supported if target texture is signed. */
bool use_signed_fb;
/* Use only lines for multiedit and not active frame. */
bool use_multiedit_lines_only;
/* Layer opacity for fading. */
float fade_layer_opacity;
/* Opacity for fading gpencil objects. */
float fade_gp_object_opacity;
/* Opacity for fading 3D objects. */
float fade_3d_object_opacity;
/* Mask opacity uniform. */
float mask_opacity;
/* Xray transparency in solid mode. */
float xray_alpha;
/* Mask invert uniform. */
int mask_invert;
/* Vertex Paint opacity. */
float vertex_paint_opacity;
} GPENCIL_PrivateData;
/* geometry batch cache functions */
struct GpencilBatchCache *gpencil_batch_cache_get(struct Object *ob, int cfra);
GPENCIL_tObject *gpencil_object_cache_add(GPENCIL_PrivateData *pd, Object *ob);
void gpencil_object_cache_sort(GPENCIL_PrivateData *pd);
GPENCIL_tLayer *gpencil_layer_cache_add(GPENCIL_PrivateData *pd,
const Object *ob,
const bGPDlayer *gpl,
const bGPDframe *gpf,
GPENCIL_tObject *tgp_ob);
GPENCIL_tLayer *gpencil_layer_cache_get(GPENCIL_tObject *tgp_ob, int number);
GPENCIL_MaterialPool *gpencil_material_pool_create(GPENCIL_PrivateData *pd, Object *ob, int *ofs);
void gpencil_material_resources_get(GPENCIL_MaterialPool *first_pool,
int mat_id,
struct GPUTexture **r_tex_stroke,
struct GPUTexture **r_tex_fill,
struct GPUUniformBuf **r_ubo_mat);
void gpencil_light_ambient_add(GPENCIL_LightPool *lightpool, const float color[3]);
void gpencil_light_pool_populate(GPENCIL_LightPool *lightpool, Object *ob);
GPENCIL_LightPool *gpencil_light_pool_add(GPENCIL_PrivateData *pd);
GPENCIL_LightPool *gpencil_light_pool_create(GPENCIL_PrivateData *pd, Object *ob);
/* effects */
void gpencil_vfx_cache_populate(GPENCIL_Data *vedata, Object *ob, GPENCIL_tObject *tgp_ob);
/* Shaders */
struct GPUShader *GPENCIL_shader_antialiasing(int stage);
struct GPUShader *GPENCIL_shader_geometry_get(void);
struct GPUShader *GPENCIL_shader_layer_blend_get(void);
struct GPUShader *GPENCIL_shader_mask_invert_get(void);
struct GPUShader *GPENCIL_shader_depth_merge_get(void);
struct GPUShader *GPENCIL_shader_fx_blur_get(void);
struct GPUShader *GPENCIL_shader_fx_colorize_get(void);
struct GPUShader *GPENCIL_shader_fx_composite_get(void);
struct GPUShader *GPENCIL_shader_fx_transform_get(void);
struct GPUShader *GPENCIL_shader_fx_glow_get(void);
struct GPUShader *GPENCIL_shader_fx_pixelize_get(void);
struct GPUShader *GPENCIL_shader_fx_rim_get(void);
struct GPUShader *GPENCIL_shader_fx_shadow_get(void);
void GPENCIL_shader_free(void);
/* Antialiasing */
void GPENCIL_antialiasing_init(struct GPENCIL_Data *vedata);
void GPENCIL_antialiasing_draw(struct GPENCIL_Data *vedata);
/* main functions */
void GPENCIL_engine_init(void *vedata);
void GPENCIL_cache_init(void *vedata);
void GPENCIL_cache_populate(void *vedata, struct Object *ob);
void GPENCIL_cache_finish(void *vedata);
void GPENCIL_draw_scene(void *vedata);
/* render */
void GPENCIL_render_init(struct GPENCIL_Data *ved,
struct RenderEngine *engine,
struct RenderLayer *render_layer,
const struct Depsgraph *depsgraph,
const rcti *rect);
void GPENCIL_render_to_image(void *vedata,
struct RenderEngine *engine,
struct RenderLayer *render_layer,
const rcti *rect);
/* Draw Data. */
void gpencil_light_pool_free(void *storage);
void gpencil_material_pool_free(void *storage);
GPENCIL_ViewLayerData *GPENCIL_view_layer_data_ensure(void);
#ifdef __cplusplus
}
#endif