1024 lines
41 KiB
C
1024 lines
41 KiB
C
/* SPDX-FileCopyrightText: 2016 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup draw
|
|
*/
|
|
|
|
/* This is the Render Functions used by Realtime engines to draw with OpenGL */
|
|
|
|
#pragma once
|
|
|
|
#include "BLI_listbase.h"
|
|
#include "BLI_math_matrix.h"
|
|
#include "BLI_math_vector.h"
|
|
#include "BLI_string.h"
|
|
|
|
#include "BKE_context.hh"
|
|
#include "BKE_layer.h"
|
|
#include "BKE_material.h"
|
|
#include "BKE_pbvh.hh"
|
|
#include "BKE_scene.h"
|
|
|
|
#include "BLT_translation.h"
|
|
|
|
#include "DNA_light_types.h"
|
|
#include "DNA_material_types.h"
|
|
#include "DNA_object_types.h"
|
|
#include "DNA_scene_types.h"
|
|
#include "DNA_world_types.h"
|
|
|
|
#include "GPU_framebuffer.h"
|
|
#include "GPU_material.h"
|
|
#include "GPU_primitive.h"
|
|
#include "GPU_shader.h"
|
|
#include "GPU_storage_buffer.h"
|
|
#include "GPU_texture.h"
|
|
#include "GPU_uniform_buffer.h"
|
|
|
|
#include "draw_cache.h"
|
|
#include "draw_common.h"
|
|
#include "draw_view.h"
|
|
|
|
#include "draw_debug.h"
|
|
#include "draw_manager_profiling.hh"
|
|
#include "draw_state.h"
|
|
#include "draw_view_data.h"
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "RE_engine.h"
|
|
|
|
#include "DEG_depsgraph.hh"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Uncomment to track unused resource bindings. */
|
|
// #define DRW_UNUSED_RESOURCE_TRACKING
|
|
|
|
#ifdef DRW_UNUSED_RESOURCE_TRACKING
|
|
# define DRW_DEBUG_FILE_LINE_ARGS , const char *file, int line
|
|
#else
|
|
# define DRW_DEBUG_FILE_LINE_ARGS
|
|
#endif
|
|
|
|
struct GPUBatch;
|
|
struct GPUMaterial;
|
|
struct GPUShader;
|
|
struct GPUTexture;
|
|
struct GPUUniformBuf;
|
|
struct Object;
|
|
struct ParticleSystem;
|
|
struct RenderEngineType;
|
|
struct bContext;
|
|
struct rcti;
|
|
|
|
typedef struct DRWCallBuffer DRWCallBuffer;
|
|
typedef struct DRWInterface DRWInterface;
|
|
typedef struct DRWPass DRWPass;
|
|
typedef struct DRWShaderLibrary DRWShaderLibrary;
|
|
typedef struct DRWShadingGroup DRWShadingGroup;
|
|
typedef struct DRWUniform DRWUniform;
|
|
typedef struct DRWView DRWView;
|
|
|
|
/* TODO: Put it somewhere else? */
|
|
typedef struct BoundSphere {
|
|
float center[3], radius;
|
|
} BoundSphere;
|
|
|
|
/* declare members as empty (unused) */
|
|
typedef char DRWViewportEmptyList;
|
|
|
|
#define DRW_VIEWPORT_LIST_SIZE(list) \
|
|
(sizeof(list) == sizeof(DRWViewportEmptyList) ? 0 : (sizeof(list) / sizeof(void *)))
|
|
|
|
/* Unused members must be either pass list or 'char *' when not used. */
|
|
#define DRW_VIEWPORT_DATA_SIZE(ty) \
|
|
{ \
|
|
DRW_VIEWPORT_LIST_SIZE(*(((ty *)NULL)->fbl)), DRW_VIEWPORT_LIST_SIZE(*(((ty *)NULL)->txl)), \
|
|
DRW_VIEWPORT_LIST_SIZE(*(((ty *)NULL)->psl)), \
|
|
DRW_VIEWPORT_LIST_SIZE(*(((ty *)NULL)->stl)), \
|
|
}
|
|
|
|
typedef struct DrawEngineDataSize {
|
|
int fbl_len;
|
|
int txl_len;
|
|
int psl_len;
|
|
int stl_len;
|
|
} DrawEngineDataSize;
|
|
|
|
typedef struct DrawEngineType {
|
|
struct DrawEngineType *next, *prev;
|
|
|
|
char idname[32];
|
|
|
|
const DrawEngineDataSize *vedata_size;
|
|
|
|
void (*engine_init)(void *vedata);
|
|
void (*engine_free)(void);
|
|
|
|
void (*instance_free)(void *instance_data);
|
|
|
|
void (*cache_init)(void *vedata);
|
|
void (*cache_populate)(void *vedata, struct Object *ob);
|
|
void (*cache_finish)(void *vedata);
|
|
|
|
void (*draw_scene)(void *vedata);
|
|
|
|
void (*view_update)(void *vedata);
|
|
void (*id_update)(void *vedata, struct ID *id);
|
|
|
|
void (*render_to_image)(void *vedata,
|
|
struct RenderEngine *engine,
|
|
struct RenderLayer *layer,
|
|
const struct rcti *rect);
|
|
void (*store_metadata)(void *vedata, struct RenderResult *render_result);
|
|
} DrawEngineType;
|
|
|
|
/* Textures */
|
|
typedef enum {
|
|
DRW_TEX_FILTER = (1 << 0),
|
|
DRW_TEX_WRAP = (1 << 1),
|
|
DRW_TEX_COMPARE = (1 << 2),
|
|
DRW_TEX_MIPMAP = (1 << 3),
|
|
} DRWTextureFlag;
|
|
|
|
/**
|
|
* Textures from `DRW_texture_pool_query_*` have the options
|
|
* #DRW_TEX_FILTER for color float textures, and no options
|
|
* for depth textures and integer textures.
|
|
*/
|
|
struct GPUTexture *DRW_texture_pool_query_2d(int w,
|
|
int h,
|
|
eGPUTextureFormat format,
|
|
DrawEngineType *engine_type);
|
|
struct GPUTexture *DRW_texture_pool_query_fullscreen(eGPUTextureFormat format,
|
|
DrawEngineType *engine_type);
|
|
|
|
struct GPUTexture *DRW_texture_create_1d(int w,
|
|
eGPUTextureFormat format,
|
|
DRWTextureFlag flags,
|
|
const float *fpixels);
|
|
struct GPUTexture *DRW_texture_create_2d(
|
|
int w, int h, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels);
|
|
struct GPUTexture *DRW_texture_create_2d_array(
|
|
int w, int h, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels);
|
|
struct GPUTexture *DRW_texture_create_3d(
|
|
int w, int h, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels);
|
|
struct GPUTexture *DRW_texture_create_cube(int w,
|
|
eGPUTextureFormat format,
|
|
DRWTextureFlag flags,
|
|
const float *fpixels);
|
|
struct GPUTexture *DRW_texture_create_cube_array(
|
|
int w, int d, eGPUTextureFormat format, DRWTextureFlag flags, const float *fpixels);
|
|
|
|
void DRW_texture_ensure_fullscreen_2d(struct GPUTexture **tex,
|
|
eGPUTextureFormat format,
|
|
DRWTextureFlag flags);
|
|
void DRW_texture_ensure_2d(
|
|
struct GPUTexture **tex, int w, int h, eGPUTextureFormat format, DRWTextureFlag flags);
|
|
|
|
/* Explicit parameter variants. */
|
|
struct GPUTexture *DRW_texture_pool_query_2d_ex(
|
|
int w, int h, eGPUTextureFormat format, eGPUTextureUsage usage, DrawEngineType *engine_type);
|
|
struct GPUTexture *DRW_texture_pool_query_fullscreen_ex(eGPUTextureFormat format,
|
|
eGPUTextureUsage usage,
|
|
DrawEngineType *engine_type);
|
|
|
|
struct GPUTexture *DRW_texture_create_1d_ex(int w,
|
|
eGPUTextureFormat format,
|
|
eGPUTextureUsage usage_flags,
|
|
DRWTextureFlag flags,
|
|
const float *fpixels);
|
|
struct GPUTexture *DRW_texture_create_2d_ex(int w,
|
|
int h,
|
|
eGPUTextureFormat format,
|
|
eGPUTextureUsage usage_flags,
|
|
DRWTextureFlag flags,
|
|
const float *fpixels);
|
|
struct GPUTexture *DRW_texture_create_2d_array_ex(int w,
|
|
int h,
|
|
int d,
|
|
eGPUTextureFormat format,
|
|
eGPUTextureUsage usage_flags,
|
|
DRWTextureFlag flags,
|
|
const float *fpixels);
|
|
struct GPUTexture *DRW_texture_create_3d_ex(int w,
|
|
int h,
|
|
int d,
|
|
eGPUTextureFormat format,
|
|
eGPUTextureUsage usage_flags,
|
|
DRWTextureFlag flags,
|
|
const float *fpixels);
|
|
struct GPUTexture *DRW_texture_create_cube_ex(int w,
|
|
eGPUTextureFormat format,
|
|
eGPUTextureUsage usage_flags,
|
|
DRWTextureFlag flags,
|
|
const float *fpixels);
|
|
struct GPUTexture *DRW_texture_create_cube_array_ex(int w,
|
|
int d,
|
|
eGPUTextureFormat format,
|
|
eGPUTextureUsage usage_flags,
|
|
DRWTextureFlag flags,
|
|
const float *fpixels);
|
|
|
|
void DRW_texture_ensure_fullscreen_2d_ex(struct GPUTexture **tex,
|
|
eGPUTextureFormat format,
|
|
eGPUTextureUsage usage,
|
|
DRWTextureFlag flags);
|
|
void DRW_texture_ensure_2d_ex(struct GPUTexture **tex,
|
|
int w,
|
|
int h,
|
|
eGPUTextureFormat format,
|
|
eGPUTextureUsage usage,
|
|
DRWTextureFlag flags);
|
|
|
|
void DRW_texture_generate_mipmaps(struct GPUTexture *tex);
|
|
void DRW_texture_free(struct GPUTexture *tex);
|
|
#define DRW_TEXTURE_FREE_SAFE(tex) \
|
|
do { \
|
|
if (tex != NULL) { \
|
|
DRW_texture_free(tex); \
|
|
tex = NULL; \
|
|
} \
|
|
} while (0)
|
|
|
|
#define DRW_UBO_FREE_SAFE(ubo) \
|
|
do { \
|
|
if (ubo != NULL) { \
|
|
GPU_uniformbuf_free(ubo); \
|
|
ubo = NULL; \
|
|
} \
|
|
} while (0)
|
|
|
|
/* Shaders */
|
|
struct GPUShader *DRW_shader_create_from_info_name(const char *info_name);
|
|
struct GPUShader *DRW_shader_create_ex(
|
|
const char *vert, const char *geom, const char *frag, const char *defines, const char *name);
|
|
struct GPUShader *DRW_shader_create_with_lib_ex(const char *vert,
|
|
const char *geom,
|
|
const char *frag,
|
|
const char *lib,
|
|
const char *defines,
|
|
const char *name);
|
|
struct GPUShader *DRW_shader_create_with_shaderlib_ex(const char *vert,
|
|
const char *geom,
|
|
const char *frag,
|
|
const DRWShaderLibrary *lib,
|
|
const char *defines,
|
|
const char *name);
|
|
struct GPUShader *DRW_shader_create_with_transform_feedback(const char *vert,
|
|
const char *geom,
|
|
const char *defines,
|
|
eGPUShaderTFBType prim_type,
|
|
const char **varying_names,
|
|
int varying_count);
|
|
struct GPUShader *DRW_shader_create_fullscreen_ex(const char *frag,
|
|
const char *defines,
|
|
const char *name);
|
|
struct GPUShader *DRW_shader_create_fullscreen_with_shaderlib_ex(const char *frag,
|
|
const DRWShaderLibrary *lib,
|
|
const char *defines,
|
|
const char *name);
|
|
#define DRW_shader_create(vert, geom, frag, defines) \
|
|
DRW_shader_create_ex(vert, geom, frag, defines, __func__)
|
|
#define DRW_shader_create_with_lib(vert, geom, frag, lib, defines) \
|
|
DRW_shader_create_with_lib_ex(vert, geom, frag, lib, defines, __func__)
|
|
#define DRW_shader_create_with_shaderlib(vert, geom, frag, lib, defines) \
|
|
DRW_shader_create_with_shaderlib_ex(vert, geom, frag, lib, defines, __func__)
|
|
#define DRW_shader_create_fullscreen(frag, defines) \
|
|
DRW_shader_create_fullscreen_ex(frag, defines, __func__)
|
|
#define DRW_shader_create_fullscreen_with_shaderlib(frag, lib, defines) \
|
|
DRW_shader_create_fullscreen_with_shaderlib_ex(frag, lib, defines, __func__)
|
|
|
|
struct GPUMaterial *DRW_shader_from_world(struct World *wo,
|
|
struct bNodeTree *ntree,
|
|
const uint64_t shader_id,
|
|
const bool is_volume_shader,
|
|
bool deferred,
|
|
GPUCodegenCallbackFn callback,
|
|
void *thunk);
|
|
struct GPUMaterial *DRW_shader_from_material(struct Material *ma,
|
|
struct bNodeTree *ntree,
|
|
const uint64_t shader_id,
|
|
const bool is_volume_shader,
|
|
bool deferred,
|
|
GPUCodegenCallbackFn callback,
|
|
void *thunk);
|
|
void DRW_shader_queue_optimize_material(struct GPUMaterial *mat);
|
|
void DRW_shader_free(struct GPUShader *shader);
|
|
#define DRW_SHADER_FREE_SAFE(shader) \
|
|
do { \
|
|
if (shader != NULL) { \
|
|
DRW_shader_free(shader); \
|
|
shader = NULL; \
|
|
} \
|
|
} while (0)
|
|
|
|
DRWShaderLibrary *DRW_shader_library_create(void);
|
|
|
|
/**
|
|
* \warning Each library must be added after all its dependencies.
|
|
*/
|
|
void DRW_shader_library_add_file(DRWShaderLibrary *lib,
|
|
const char *lib_code,
|
|
const char *lib_name);
|
|
#define DRW_SHADER_LIB_ADD(lib, lib_name) \
|
|
DRW_shader_library_add_file(lib, datatoc_##lib_name##_glsl, STRINGIFY(lib_name) ".glsl")
|
|
|
|
#define DRW_SHADER_LIB_ADD_SHARED(lib, lib_name) \
|
|
DRW_shader_library_add_file(lib, datatoc_##lib_name##_h, STRINGIFY(lib_name) ".h")
|
|
|
|
/**
|
|
* \return an allocN'ed string containing the shader code with its dependencies prepended.
|
|
* Caller must free the string with #MEM_freeN after use.
|
|
*/
|
|
char *DRW_shader_library_create_shader_string(const DRWShaderLibrary *lib,
|
|
const char *shader_code);
|
|
|
|
void DRW_shader_library_free(DRWShaderLibrary *lib);
|
|
#define DRW_SHADER_LIB_FREE_SAFE(lib) \
|
|
do { \
|
|
if (lib != NULL) { \
|
|
DRW_shader_library_free(lib); \
|
|
lib = NULL; \
|
|
} \
|
|
} while (0)
|
|
|
|
/* Batches */
|
|
|
|
typedef enum {
|
|
DRW_ATTR_INT,
|
|
DRW_ATTR_FLOAT,
|
|
} eDRWAttrType;
|
|
|
|
typedef struct DRWInstanceAttrFormat {
|
|
char name[32];
|
|
eDRWAttrType type;
|
|
int components;
|
|
} DRWInstanceAttrFormat;
|
|
|
|
struct GPUVertFormat *DRW_shgroup_instance_format_array(const DRWInstanceAttrFormat attrs[],
|
|
int arraysize);
|
|
#define DRW_shgroup_instance_format(format, ...) \
|
|
do { \
|
|
if (format == NULL) { \
|
|
DRWInstanceAttrFormat drw_format[] = __VA_ARGS__; \
|
|
format = DRW_shgroup_instance_format_array( \
|
|
drw_format, (sizeof(drw_format) / sizeof(DRWInstanceAttrFormat))); \
|
|
} \
|
|
} while (0)
|
|
|
|
DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass);
|
|
DRWShadingGroup *DRW_shgroup_create_sub(DRWShadingGroup *shgroup);
|
|
DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass);
|
|
DRWShadingGroup *DRW_shgroup_transform_feedback_create(struct GPUShader *shader,
|
|
DRWPass *pass,
|
|
struct GPUVertBuf *tf_target);
|
|
|
|
void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial *material);
|
|
|
|
/**
|
|
* Return final visibility.
|
|
*/
|
|
typedef bool(DRWCallVisibilityFn)(bool vis_in, void *user_data);
|
|
|
|
void DRW_shgroup_call_ex(DRWShadingGroup *shgroup,
|
|
Object *ob,
|
|
float (*obmat)[4],
|
|
struct GPUBatch *geom,
|
|
bool bypass_culling,
|
|
void *user_data);
|
|
|
|
/**
|
|
* If ob is NULL, unit model-matrix is assumed and culling is bypassed.
|
|
*/
|
|
#define DRW_shgroup_call(shgroup, geom, ob) \
|
|
DRW_shgroup_call_ex(shgroup, ob, NULL, geom, false, NULL)
|
|
|
|
/**
|
|
* Same as #DRW_shgroup_call but override the `obmat`. Not culled.
|
|
*/
|
|
#define DRW_shgroup_call_obmat(shgroup, geom, obmat) \
|
|
DRW_shgroup_call_ex(shgroup, NULL, obmat, geom, false, NULL)
|
|
|
|
/* TODO(fclem): remove this when we have #DRWView */
|
|
/* user_data is used by #DRWCallVisibilityFn defined in #DRWView. */
|
|
#define DRW_shgroup_call_with_callback(shgroup, geom, ob, user_data) \
|
|
DRW_shgroup_call_ex(shgroup, ob, NULL, geom, false, user_data)
|
|
|
|
/**
|
|
* Same as #DRW_shgroup_call but bypass culling even if ob is not NULL.
|
|
*/
|
|
#define DRW_shgroup_call_no_cull(shgroup, geom, ob) \
|
|
DRW_shgroup_call_ex(shgroup, ob, NULL, geom, true, NULL)
|
|
|
|
void DRW_shgroup_call_range(
|
|
DRWShadingGroup *shgroup, Object *ob, struct GPUBatch *geom, uint v_sta, uint v_num);
|
|
/**
|
|
* A count of 0 instance will use the default number of instance in the batch.
|
|
*/
|
|
void DRW_shgroup_call_instance_range(
|
|
DRWShadingGroup *shgroup, Object *ob, struct GPUBatch *geom, uint i_sta, uint i_num);
|
|
|
|
void DRW_shgroup_call_compute(DRWShadingGroup *shgroup,
|
|
int groups_x_len,
|
|
int groups_y_len,
|
|
int groups_z_len);
|
|
/**
|
|
* \warning this keeps the ref to groups_ref until it actually dispatch.
|
|
*/
|
|
void DRW_shgroup_call_compute_ref(DRWShadingGroup *shgroup, int groups_ref[3]);
|
|
/**
|
|
* \note No need for a barrier. \a indirect_buf is internally synchronized.
|
|
*/
|
|
void DRW_shgroup_call_compute_indirect(DRWShadingGroup *shgroup, GPUStorageBuf *indirect_buf);
|
|
void DRW_shgroup_call_procedural_points(DRWShadingGroup *sh, Object *ob, uint point_count);
|
|
void DRW_shgroup_call_procedural_lines(DRWShadingGroup *sh, Object *ob, uint line_count);
|
|
void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *sh, Object *ob, uint tri_count);
|
|
void DRW_shgroup_call_procedural_indirect(DRWShadingGroup *shgroup,
|
|
GPUPrimType primitive_type,
|
|
Object *ob,
|
|
GPUStorageBuf *indirect_buf);
|
|
/**
|
|
* \warning Only use with Shaders that have `IN_PLACE_INSTANCES` defined.
|
|
* TODO: Should be removed.
|
|
*/
|
|
void DRW_shgroup_call_instances(DRWShadingGroup *shgroup,
|
|
Object *ob,
|
|
struct GPUBatch *geom,
|
|
uint count);
|
|
/**
|
|
* \warning Only use with Shaders that have INSTANCED_ATTR defined.
|
|
*/
|
|
void DRW_shgroup_call_instances_with_attrs(DRWShadingGroup *shgroup,
|
|
Object *ob,
|
|
struct GPUBatch *geom,
|
|
struct GPUBatch *inst_attributes);
|
|
|
|
void DRW_shgroup_call_sculpt(DRWShadingGroup *shgroup,
|
|
Object *ob,
|
|
bool use_wire,
|
|
bool use_mask,
|
|
bool use_fset,
|
|
bool use_color,
|
|
bool use_uv);
|
|
|
|
void DRW_shgroup_call_sculpt_with_materials(DRWShadingGroup **shgroups,
|
|
struct GPUMaterial **gpumats,
|
|
int num_shgroups,
|
|
Object *ob);
|
|
|
|
DRWCallBuffer *DRW_shgroup_call_buffer(DRWShadingGroup *shgroup,
|
|
struct GPUVertFormat *format,
|
|
GPUPrimType prim_type);
|
|
DRWCallBuffer *DRW_shgroup_call_buffer_instance(DRWShadingGroup *shgroup,
|
|
struct GPUVertFormat *format,
|
|
struct GPUBatch *geom);
|
|
|
|
void DRW_buffer_add_entry_struct(DRWCallBuffer *callbuf, const void *data);
|
|
void DRW_buffer_add_entry_array(DRWCallBuffer *callbuf, const void *attr[], uint attr_len);
|
|
|
|
#define DRW_buffer_add_entry(buffer, ...) \
|
|
do { \
|
|
const void *array[] = {__VA_ARGS__}; \
|
|
DRW_buffer_add_entry_array(buffer, array, (sizeof(array) / sizeof(*array))); \
|
|
} while (0)
|
|
|
|
/**
|
|
* Can only be called during iteration phase.
|
|
*/
|
|
uint32_t DRW_object_resource_id_get(Object *ob);
|
|
|
|
/**
|
|
* State is added to #Pass.state while drawing.
|
|
* Use to temporarily enable draw options.
|
|
*/
|
|
void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state);
|
|
void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state);
|
|
|
|
/**
|
|
* Reminders:
|
|
* - (compare_mask & reference) is what is tested against (compare_mask & stencil_value)
|
|
* stencil_value being the value stored in the stencil buffer.
|
|
* - (write-mask & reference) is what gets written if the test condition is fulfilled.
|
|
*/
|
|
void DRW_shgroup_stencil_set(DRWShadingGroup *shgroup,
|
|
uint write_mask,
|
|
uint reference,
|
|
uint compare_mask);
|
|
/**
|
|
* TODO: remove this function. Obsolete version. mask is actually reference value.
|
|
*/
|
|
void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, uint mask);
|
|
|
|
/**
|
|
* Issue a barrier command.
|
|
*/
|
|
void DRW_shgroup_barrier(DRWShadingGroup *shgroup, eGPUBarrier type);
|
|
|
|
/**
|
|
* Issue a clear command.
|
|
*/
|
|
void DRW_shgroup_clear_framebuffer(DRWShadingGroup *shgroup,
|
|
eGPUFrameBufferBits channels,
|
|
uchar r,
|
|
uchar g,
|
|
uchar b,
|
|
uchar a,
|
|
float depth,
|
|
uchar stencil);
|
|
|
|
void DRW_shgroup_uniform_texture_ex(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const struct GPUTexture *tex,
|
|
GPUSamplerState sampler_state);
|
|
void DRW_shgroup_uniform_texture_ref_ex(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
GPUTexture **tex,
|
|
GPUSamplerState sampler_state);
|
|
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const struct GPUTexture *tex);
|
|
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
struct GPUTexture **tex);
|
|
void DRW_shgroup_uniform_block_ex(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const struct GPUUniformBuf *ubo DRW_DEBUG_FILE_LINE_ARGS);
|
|
void DRW_shgroup_uniform_block_ref_ex(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
struct GPUUniformBuf **ubo DRW_DEBUG_FILE_LINE_ARGS);
|
|
void DRW_shgroup_storage_block_ex(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const struct GPUStorageBuf *ssbo DRW_DEBUG_FILE_LINE_ARGS);
|
|
void DRW_shgroup_storage_block_ref_ex(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
struct GPUStorageBuf **ssbo DRW_DEBUG_FILE_LINE_ARGS);
|
|
void DRW_shgroup_uniform_float(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const float *value,
|
|
int arraysize);
|
|
void DRW_shgroup_uniform_vec2(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const float *value,
|
|
int arraysize);
|
|
void DRW_shgroup_uniform_vec3(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const float *value,
|
|
int arraysize);
|
|
void DRW_shgroup_uniform_vec4(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const float *value,
|
|
int arraysize);
|
|
void DRW_shgroup_uniform_bool(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const int *value,
|
|
int arraysize);
|
|
void DRW_shgroup_uniform_int(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const int *value,
|
|
int arraysize);
|
|
void DRW_shgroup_uniform_ivec2(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const int *value,
|
|
int arraysize);
|
|
void DRW_shgroup_uniform_ivec3(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const int *value,
|
|
int arraysize);
|
|
void DRW_shgroup_uniform_ivec4(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const int *value,
|
|
int arraysize);
|
|
void DRW_shgroup_uniform_mat3(DRWShadingGroup *shgroup, const char *name, const float (*value)[3]);
|
|
void DRW_shgroup_uniform_mat4(DRWShadingGroup *shgroup, const char *name, const float (*value)[4]);
|
|
/**
|
|
* Only to be used when image load store is supported (#GPU_shader_image_load_store_support()).
|
|
*/
|
|
void DRW_shgroup_uniform_image(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex);
|
|
void DRW_shgroup_uniform_image_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex);
|
|
|
|
/* Store value instead of referencing it. */
|
|
|
|
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, int value);
|
|
void DRW_shgroup_uniform_ivec2_copy(DRWShadingGroup *shgroup, const char *name, const int *value);
|
|
void DRW_shgroup_uniform_ivec3_copy(DRWShadingGroup *shgroup, const char *name, const int *value);
|
|
void DRW_shgroup_uniform_ivec4_copy(DRWShadingGroup *shgroup, const char *name, const int *value);
|
|
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, bool value);
|
|
void DRW_shgroup_uniform_float_copy(DRWShadingGroup *shgroup, const char *name, float value);
|
|
void DRW_shgroup_uniform_vec2_copy(DRWShadingGroup *shgroup, const char *name, const float *value);
|
|
void DRW_shgroup_uniform_vec3_copy(DRWShadingGroup *shgroup, const char *name, const float *value);
|
|
void DRW_shgroup_uniform_vec4_copy(DRWShadingGroup *shgroup, const char *name, const float *value);
|
|
void DRW_shgroup_uniform_mat4_copy(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
const float (*value)[4]);
|
|
void DRW_shgroup_vertex_buffer_ex(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
struct GPUVertBuf *vertex_buffer DRW_DEBUG_FILE_LINE_ARGS);
|
|
void DRW_shgroup_vertex_buffer_ref_ex(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
struct GPUVertBuf **vertex_buffer DRW_DEBUG_FILE_LINE_ARGS);
|
|
void DRW_shgroup_buffer_texture(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
struct GPUVertBuf *vertex_buffer);
|
|
void DRW_shgroup_buffer_texture_ref(DRWShadingGroup *shgroup,
|
|
const char *name,
|
|
struct GPUVertBuf **vertex_buffer);
|
|
|
|
#ifdef DRW_UNUSED_RESOURCE_TRACKING
|
|
# define DRW_shgroup_vertex_buffer(shgroup, name, vert) \
|
|
DRW_shgroup_vertex_buffer_ex(shgroup, name, vert, __FILE__, __LINE__)
|
|
# define DRW_shgroup_vertex_buffer_ref(shgroup, name, vert) \
|
|
DRW_shgroup_vertex_buffer_ref_ex(shgroup, name, vert, __FILE__, __LINE__)
|
|
# define DRW_shgroup_uniform_block(shgroup, name, ubo) \
|
|
DRW_shgroup_uniform_block_ex(shgroup, name, ubo, __FILE__, __LINE__)
|
|
# define DRW_shgroup_uniform_block_ref(shgroup, name, ubo) \
|
|
DRW_shgroup_uniform_block_ref_ex(shgroup, name, ubo, __FILE__, __LINE__)
|
|
# define DRW_shgroup_storage_block(shgroup, name, ssbo) \
|
|
DRW_shgroup_storage_block_ex(shgroup, name, ssbo, __FILE__, __LINE__)
|
|
# define DRW_shgroup_storage_block_ref(shgroup, name, ssbo) \
|
|
DRW_shgroup_storage_block_ref_ex(shgroup, name, ssbo, __FILE__, __LINE__)
|
|
#else
|
|
# define DRW_shgroup_vertex_buffer(shgroup, name, vert) \
|
|
DRW_shgroup_vertex_buffer_ex(shgroup, name, vert)
|
|
# define DRW_shgroup_vertex_buffer_ref(shgroup, name, vert) \
|
|
DRW_shgroup_vertex_buffer_ref_ex(shgroup, name, vert)
|
|
# define DRW_shgroup_uniform_block(shgroup, name, ubo) \
|
|
DRW_shgroup_uniform_block_ex(shgroup, name, ubo)
|
|
# define DRW_shgroup_uniform_block_ref(shgroup, name, ubo) \
|
|
DRW_shgroup_uniform_block_ref_ex(shgroup, name, ubo)
|
|
# define DRW_shgroup_storage_block(shgroup, name, ssbo) \
|
|
DRW_shgroup_storage_block_ex(shgroup, name, ssbo)
|
|
# define DRW_shgroup_storage_block_ref(shgroup, name, ssbo) \
|
|
DRW_shgroup_storage_block_ref_ex(shgroup, name, ssbo)
|
|
#endif
|
|
|
|
bool DRW_shgroup_is_empty(DRWShadingGroup *shgroup);
|
|
|
|
/* Passes. */
|
|
|
|
DRWPass *DRW_pass_create(const char *name, DRWState state);
|
|
/**
|
|
* Create an instance of the original pass that will execute the same drawcalls but with its own
|
|
* #DRWState.
|
|
*/
|
|
DRWPass *DRW_pass_create_instance(const char *name, DRWPass *original, DRWState state);
|
|
/**
|
|
* Link two passes so that they are both rendered if the first one is being drawn.
|
|
*/
|
|
void DRW_pass_link(DRWPass *first, DRWPass *second);
|
|
void DRW_pass_foreach_shgroup(DRWPass *pass,
|
|
void (*callback)(void *user_data, DRWShadingGroup *shgroup),
|
|
void *user_data);
|
|
/**
|
|
* Sort Shading groups by decreasing Z of their first draw call.
|
|
* This is useful for order dependent effect such as alpha-blending.
|
|
*/
|
|
void DRW_pass_sort_shgroup_z(DRWPass *pass);
|
|
/**
|
|
* Reverse Shading group submission order.
|
|
*/
|
|
void DRW_pass_sort_shgroup_reverse(DRWPass *pass);
|
|
|
|
bool DRW_pass_is_empty(DRWPass *pass);
|
|
|
|
#define DRW_PASS_CREATE(pass, state) (pass = DRW_pass_create(#pass, state))
|
|
#define DRW_PASS_INSTANCE_CREATE(pass, original, state) \
|
|
(pass = DRW_pass_create_instance(#pass, (original), state))
|
|
|
|
/* Views. */
|
|
|
|
/**
|
|
* Create a view with culling.
|
|
*/
|
|
DRWView *DRW_view_create(const float viewmat[4][4],
|
|
const float winmat[4][4],
|
|
const float (*culling_viewmat)[4],
|
|
const float (*culling_winmat)[4],
|
|
DRWCallVisibilityFn *visibility_fn);
|
|
/**
|
|
* Create a view with culling done by another view.
|
|
*/
|
|
DRWView *DRW_view_create_sub(const DRWView *parent_view,
|
|
const float viewmat[4][4],
|
|
const float winmat[4][4]);
|
|
|
|
/**
|
|
* Update matrices of a view created with #DRW_view_create.
|
|
*/
|
|
void DRW_view_update(DRWView *view,
|
|
const float viewmat[4][4],
|
|
const float winmat[4][4],
|
|
const float (*culling_viewmat)[4],
|
|
const float (*culling_winmat)[4]);
|
|
/**
|
|
* Update matrices of a view created with #DRW_view_create_sub.
|
|
*/
|
|
void DRW_view_update_sub(DRWView *view, const float viewmat[4][4], const float winmat[4][4]);
|
|
|
|
/**
|
|
* \return default view if it is a viewport render.
|
|
*/
|
|
const DRWView *DRW_view_default_get(void);
|
|
/**
|
|
* MUST only be called once per render and only in render mode. Sets default view.
|
|
*/
|
|
void DRW_view_default_set(const DRWView *view);
|
|
/**
|
|
* \warning Only use in render AND only if you are going to set view_default again.
|
|
*/
|
|
void DRW_view_reset(void);
|
|
/**
|
|
* Set active view for rendering.
|
|
*/
|
|
void DRW_view_set_active(const DRWView *view);
|
|
const DRWView *DRW_view_get_active(void);
|
|
|
|
/**
|
|
* This only works if DRWPasses have been tagged with DRW_STATE_CLIP_PLANES,
|
|
* and if the shaders have support for it (see usage of gl_ClipDistance).
|
|
* \note planes must be in world space.
|
|
*/
|
|
void DRW_view_clip_planes_set(DRWView *view, float (*planes)[4], int plane_len);
|
|
|
|
/* For all getters, if view is NULL, default view is assumed. */
|
|
|
|
void DRW_view_winmat_get(const DRWView *view, float mat[4][4], bool inverse);
|
|
void DRW_view_viewmat_get(const DRWView *view, float mat[4][4], bool inverse);
|
|
void DRW_view_persmat_get(const DRWView *view, float mat[4][4], bool inverse);
|
|
|
|
/**
|
|
* \return world space frustum corners.
|
|
*/
|
|
void DRW_view_frustum_corners_get(const DRWView *view, BoundBox *corners);
|
|
/**
|
|
* \return world space frustum sides as planes.
|
|
* See #draw_frustum_culling_planes_calc() for the plane order.
|
|
*/
|
|
void DRW_view_frustum_planes_get(const DRWView *view, float planes[6][4]);
|
|
|
|
/**
|
|
* These are in view-space, so negative if in perspective.
|
|
* Extract near and far clip distance from the projection matrix.
|
|
*/
|
|
float DRW_view_near_distance_get(const DRWView *view);
|
|
float DRW_view_far_distance_get(const DRWView *view);
|
|
bool DRW_view_is_persp_get(const DRWView *view);
|
|
|
|
/* Culling, return true if object is inside view frustum. */
|
|
|
|
/**
|
|
* \return True if the given BoundSphere intersect the current view frustum.
|
|
* bsphere must be in world space.
|
|
*/
|
|
bool DRW_culling_sphere_test(const DRWView *view, const BoundSphere *bsphere);
|
|
/**
|
|
* \return True if the given BoundBox intersect the current view frustum.
|
|
* bbox must be in world space.
|
|
*/
|
|
bool DRW_culling_box_test(const DRWView *view, const BoundBox *bbox);
|
|
/**
|
|
* \return True if the view frustum is inside or intersect the given plane.
|
|
* plane must be in world space.
|
|
*/
|
|
bool DRW_culling_plane_test(const DRWView *view, const float plane[4]);
|
|
/**
|
|
* Return True if the given box intersect the current view frustum.
|
|
* This function will have to be replaced when world space bounding-box per objects is implemented.
|
|
*/
|
|
bool DRW_culling_min_max_test(const DRWView *view, float obmat[4][4], float min[3], float max[3]);
|
|
|
|
void DRW_culling_frustum_corners_get(const DRWView *view, BoundBox *corners);
|
|
void DRW_culling_frustum_planes_get(const DRWView *view, float planes[6][4]);
|
|
|
|
/* Viewport. */
|
|
|
|
const float *DRW_viewport_size_get(void);
|
|
const float *DRW_viewport_invert_size_get(void);
|
|
const float *DRW_viewport_pixelsize_get(void);
|
|
|
|
struct DefaultFramebufferList *DRW_viewport_framebuffer_list_get(void);
|
|
struct DefaultTextureList *DRW_viewport_texture_list_get(void);
|
|
|
|
void DRW_viewport_request_redraw(void);
|
|
|
|
void DRW_render_to_image(struct RenderEngine *engine, struct Depsgraph *depsgraph);
|
|
void DRW_render_object_iter(void *vedata,
|
|
struct RenderEngine *engine,
|
|
struct Depsgraph *depsgraph,
|
|
void (*callback)(void *vedata,
|
|
struct Object *ob,
|
|
struct RenderEngine *engine,
|
|
struct Depsgraph *depsgraph));
|
|
/**
|
|
* Must run after all instance datas have been added.
|
|
*/
|
|
void DRW_render_instance_buffer_finish(void);
|
|
/**
|
|
* \warning Changing frame might free the #ViewLayerEngineData.
|
|
*/
|
|
void DRW_render_set_time(struct RenderEngine *engine,
|
|
struct Depsgraph *depsgraph,
|
|
int frame,
|
|
float subframe);
|
|
/**
|
|
* \warning only use for custom pipeline. 99% of the time, you don't want to use this.
|
|
*/
|
|
void DRW_render_viewport_size_set(const int size[2]);
|
|
|
|
/**
|
|
* Assume a valid GL context is bound (and that the gl_context_mutex has been acquired).
|
|
* This function only setup DST and execute the given function.
|
|
* \warning similar to DRW_render_to_image you cannot use default lists (`dfbl` & `dtxl`).
|
|
*/
|
|
void DRW_custom_pipeline(DrawEngineType *draw_engine_type,
|
|
struct Depsgraph *depsgraph,
|
|
void (*callback)(void *vedata, void *user_data),
|
|
void *user_data);
|
|
/**
|
|
* Same as `DRW_custom_pipeline` but allow better code-flow than a callback.
|
|
*/
|
|
void DRW_custom_pipeline_begin(DrawEngineType *draw_engine_type, struct Depsgraph *depsgraph);
|
|
void DRW_custom_pipeline_end(void);
|
|
|
|
/**
|
|
* Used when the render engine want to redo another cache populate inside the same render frame.
|
|
*/
|
|
void DRW_cache_restart(void);
|
|
|
|
/* ViewLayers */
|
|
|
|
void *DRW_view_layer_engine_data_get(DrawEngineType *engine_type);
|
|
void **DRW_view_layer_engine_data_ensure_ex(struct ViewLayer *view_layer,
|
|
DrawEngineType *engine_type,
|
|
void (*callback)(void *storage));
|
|
void **DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type,
|
|
void (*callback)(void *storage));
|
|
|
|
/* DrawData */
|
|
|
|
DrawData *DRW_drawdata_get(ID *id, DrawEngineType *engine_type);
|
|
DrawData *DRW_drawdata_ensure(ID *id,
|
|
DrawEngineType *engine_type,
|
|
size_t size,
|
|
DrawDataInitCb init_cb,
|
|
DrawDataFreeCb free_cb);
|
|
/**
|
|
* Return NULL if not a dupli or a pointer of pointer to the engine data.
|
|
*/
|
|
void **DRW_duplidata_get(void *vedata);
|
|
|
|
/* Settings. */
|
|
|
|
bool DRW_object_is_renderable(const struct Object *ob);
|
|
/**
|
|
* Does `ob` needs to be rendered in edit mode.
|
|
*
|
|
* When using duplicate linked meshes, objects that are not in edit-mode will be drawn as
|
|
* it is in edit mode, when another object with the same mesh is in edit mode.
|
|
* This will not be the case when one of the objects are influenced by modifiers.
|
|
*/
|
|
bool DRW_object_is_in_edit_mode(const struct Object *ob);
|
|
/**
|
|
* Return whether this object is visible depending if
|
|
* we are rendering or drawing in the viewport.
|
|
*/
|
|
int DRW_object_visibility_in_active_context(const struct Object *ob);
|
|
bool DRW_object_use_hide_faces(const struct Object *ob);
|
|
|
|
bool DRW_object_is_visible_psys_in_active_context(const struct Object *object,
|
|
const struct ParticleSystem *psys);
|
|
|
|
struct Object *DRW_object_get_dupli_parent(const struct Object *ob);
|
|
struct DupliObject *DRW_object_get_dupli(const struct Object *ob);
|
|
|
|
/* Draw commands */
|
|
|
|
void DRW_draw_pass(DRWPass *pass);
|
|
/**
|
|
* Draw only a subset of shgroups. Used in special situations as grease pencil strokes.
|
|
*/
|
|
void DRW_draw_pass_subset(DRWPass *pass, DRWShadingGroup *start_group, DRWShadingGroup *end_group);
|
|
|
|
void DRW_draw_callbacks_pre_scene(void);
|
|
void DRW_draw_callbacks_post_scene(void);
|
|
|
|
/**
|
|
* Reset state to not interfere with other UI draw-call.
|
|
*/
|
|
void DRW_state_reset_ex(DRWState state);
|
|
void DRW_state_reset(void);
|
|
/**
|
|
* Use with care, intended so selection code can override passes depth settings,
|
|
* which is important for selection to work properly.
|
|
*
|
|
* Should be set in main draw loop, cleared afterwards
|
|
*/
|
|
void DRW_state_lock(DRWState state);
|
|
|
|
/* Selection. */
|
|
|
|
void DRW_select_load_id(uint id);
|
|
|
|
/* Draw State. */
|
|
|
|
/**
|
|
* When false, drawing doesn't output to a pixel buffer
|
|
* eg: Occlusion queries, or when we have setup a context to draw in already.
|
|
*/
|
|
bool DRW_state_is_fbo(void);
|
|
/**
|
|
* For when engines need to know if this is drawing for selection or not.
|
|
*/
|
|
bool DRW_state_is_select(void);
|
|
bool DRW_state_is_material_select(void);
|
|
bool DRW_state_is_depth(void);
|
|
/**
|
|
* Whether we are rendering for an image
|
|
*/
|
|
bool DRW_state_is_image_render(void);
|
|
/**
|
|
* Whether we are rendering only the render engine,
|
|
* or if we should also render the mode engines.
|
|
*/
|
|
bool DRW_state_is_scene_render(void);
|
|
/**
|
|
* Whether we are rendering simple opengl render
|
|
*/
|
|
bool DRW_state_is_viewport_image_render(void);
|
|
bool DRW_state_is_playback(void);
|
|
/**
|
|
* Is the user navigating the region.
|
|
*/
|
|
bool DRW_state_is_navigating(void);
|
|
/**
|
|
* Should text draw in this mode?
|
|
*/
|
|
bool DRW_state_show_text(void);
|
|
/**
|
|
* Should draw support elements
|
|
* Objects center, selection outline, probe data, ...
|
|
*/
|
|
bool DRW_state_draw_support(void);
|
|
/**
|
|
* Whether we should render the background
|
|
*/
|
|
bool DRW_state_draw_background(void);
|
|
|
|
/* Avoid too many lookups while drawing */
|
|
typedef struct DRWContextState {
|
|
|
|
struct ARegion *region; /* 'CTX_wm_region(C)' */
|
|
struct RegionView3D *rv3d; /* 'CTX_wm_region_view3d(C)' */
|
|
struct View3D *v3d; /* 'CTX_wm_view3d(C)' */
|
|
struct SpaceLink *space_data; /* 'CTX_wm_space_data(C)' */
|
|
|
|
struct Scene *scene; /* 'CTX_data_scene(C)' */
|
|
struct ViewLayer *view_layer; /* 'CTX_data_view_layer(C)' */
|
|
|
|
/* Use 'object_edit' for edit-mode */
|
|
struct Object *obact;
|
|
|
|
struct RenderEngineType *engine_type;
|
|
|
|
struct Depsgraph *depsgraph;
|
|
|
|
struct TaskGraph *task_graph;
|
|
|
|
eObjectMode object_mode;
|
|
|
|
eGPUShaderConfig sh_cfg;
|
|
|
|
/** Last resort (some functions take this as an arg so we can't easily avoid).
|
|
* May be NULL when used for selection or depth buffer. */
|
|
const struct bContext *evil_C;
|
|
|
|
/* ---- */
|
|
|
|
/* Cache: initialized by 'drw_context_state_init'. */
|
|
struct Object *object_pose;
|
|
struct Object *object_edit;
|
|
|
|
} DRWContextState;
|
|
|
|
const DRWContextState *DRW_context_state_get(void);
|
|
|
|
struct DRW_Attributes;
|
|
struct DRW_MeshCDMask;
|
|
|
|
void DRW_mesh_batch_cache_get_attributes(struct Object *object,
|
|
struct Mesh *me,
|
|
struct DRW_Attributes **r_attrs,
|
|
struct DRW_MeshCDMask **r_cd_needed);
|
|
|
|
void DRW_sculpt_debug_cb(
|
|
PBVHNode *node, void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|