Blender  V2.93
workbench_opaque.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * Copyright 2020, Blender Foundation.
17  */
18 
32 #include "DRW_render.h"
33 
34 #include "workbench_engine.h"
35 #include "workbench_private.h"
36 
38 {
39  WORKBENCH_FramebufferList *fbl = data->fbl;
40  WORKBENCH_PrivateData *wpd = data->stl->wpd;
43 
44  /* Reused the same textures format for transparent pipeline to share the textures. */
45  const eGPUTextureFormat col_tex_format = GPU_RGBA16F;
47 
48  wpd->material_buffer_tx = DRW_texture_pool_query_fullscreen(col_tex_format, owner);
49  wpd->normal_buffer_tx = DRW_texture_pool_query_fullscreen(nor_tex_format, owner);
50 
51  GPU_framebuffer_ensure_config(&fbl->opaque_fb,
52  {
53  GPU_ATTACHMENT_TEXTURE(dtxl->depth),
54  GPU_ATTACHMENT_TEXTURE(wpd->material_buffer_tx),
55  GPU_ATTACHMENT_TEXTURE(wpd->normal_buffer_tx),
56  GPU_ATTACHMENT_TEXTURE(wpd->object_id_tx),
57  });
58 }
59 
61 {
62  WORKBENCH_PassList *psl = vedata->psl;
63  WORKBENCH_PrivateData *wpd = vedata->stl->wpd;
65  struct GPUShader *sh;
66  DRWShadingGroup *grp;
67 
68  const bool use_matcap = (wpd->shading.light == V3D_LIGHTING_MATCAP);
69 
70  {
72 
73  int opaque = 0;
74  for (int infront = 0; infront < 2; infront++) {
75  DRWPass *pass;
76  if (infront) {
78  pass = psl->opaque_infront_ps;
79  }
80  else {
82  pass = psl->opaque_ps;
83  }
84 
86  wpd->prepass[opaque][infront][data].material_hash = BLI_ghash_ptr_new(__func__);
87 
89 
90  wpd->prepass[opaque][infront][data].common_shgrp = grp = DRW_shgroup_create(sh, pass);
91  DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
92  DRW_shgroup_uniform_int_copy(grp, "materialIndex", -1);
93  DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
94 
95  wpd->prepass[opaque][infront][data].vcol_shgrp = grp = DRW_shgroup_create(sh, pass);
96  DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
97  DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. (uses vcol) */
98  DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
99 
100  sh = workbench_shader_opaque_image_get(wpd, data, false);
101 
102  wpd->prepass[opaque][infront][data].image_shgrp = grp = DRW_shgroup_create(sh, pass);
103  DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
104  DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
105  DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
106 
107  sh = workbench_shader_opaque_image_get(wpd, data, true);
108 
109  wpd->prepass[opaque][infront][data].image_tiled_shgrp = grp = DRW_shgroup_create(sh, pass);
110  DRW_shgroup_uniform_block(grp, "material_block", wpd->material_ubo_curr);
111  DRW_shgroup_uniform_int_copy(grp, "materialIndex", 0); /* Default material. */
112  DRW_shgroup_uniform_bool_copy(grp, "useMatcap", use_matcap);
113  }
114  }
115  }
116  {
118 
120 
122 
123  grp = DRW_shgroup_create(sh, psl->composite_ps);
124  DRW_shgroup_uniform_block(grp, "world_block", wpd->world_ubo);
125  DRW_shgroup_uniform_texture(grp, "materialBuffer", wpd->material_buffer_tx);
126  DRW_shgroup_uniform_texture(grp, "normalBuffer", wpd->normal_buffer_tx);
127  DRW_shgroup_uniform_bool_copy(grp, "forceShadowing", false);
128  DRW_shgroup_stencil_mask(grp, 0x00);
129 
134  struct GPUTexture *diff_tx = wpd->studio_light->matcap_diffuse.gputexture;
135  struct GPUTexture *spec_tx = wpd->studio_light->matcap_specular.gputexture;
136  const bool use_spec = workbench_is_specular_highlight_enabled(wpd);
137  spec_tx = (use_spec && spec_tx) ? spec_tx : diff_tx;
138  DRW_shgroup_uniform_texture(grp, "matcapDiffuseImage", diff_tx);
139  DRW_shgroup_uniform_texture(grp, "matcapSpecularImage", spec_tx);
140  }
142 
143  if (SHADOW_ENABLED(wpd)) {
144  grp = DRW_shgroup_create_sub(grp);
145  DRW_shgroup_uniform_bool_copy(grp, "forceShadowing", true);
148  DRW_shgroup_stencil_mask(grp, 0x00);
150  }
151  }
152  {
155 
157 
159 
160  grp = DRW_shgroup_create(sh, psl->merge_infront_ps);
161  DRW_shgroup_uniform_texture_ref(grp, "depthBuffer", &dtxl->depth_in_front);
162  DRW_shgroup_stencil_mask(grp, 0x00);
164  }
165 }
@ STUDIOLIGHT_MATCAP_SPECULAR_GPUTEXTURE
@ STUDIOLIGHT_MATCAP_DIFFUSE_GPUTEXTURE
void BKE_studiolight_ensure_flag(StudioLight *sl, int flag)
Definition: studiolight.c:1539
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
@ V3D_LIGHTING_MATCAP
DRWState
Definition: DRW_render.h:312
@ DRW_STATE_STENCIL_EQUAL
Definition: DRW_render.h:332
@ DRW_STATE_STENCIL_ALWAYS
Definition: DRW_render.h:331
@ DRW_STATE_WRITE_DEPTH
Definition: DRW_render.h:314
@ DRW_STATE_WRITE_COLOR
Definition: DRW_render.h:315
@ DRW_STATE_DEPTH_LESS_EQUAL
Definition: DRW_render.h:323
@ DRW_STATE_STENCIL_NEQUAL
Definition: DRW_render.h:333
@ DRW_STATE_DEPTH_ALWAYS
Definition: DRW_render.h:321
@ DRW_STATE_DEPTH_GREATER
Definition: DRW_render.h:325
@ DRW_STATE_WRITE_STENCIL
Definition: DRW_render.h:317
#define DRW_PASS_CREATE(pass, state)
Definition: DRW_render.h:593
struct GPUShader GPUShader
Definition: GPU_shader.h:33
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
eGPUTextureFormat
Definition: GPU_texture.h:84
@ GPU_RG16F
Definition: GPU_texture.h:104
@ GPU_RGBA16F
Definition: GPU_texture.h:94
DefaultTextureList * DRW_viewport_texture_list_get(void)
Definition: draw_manager.c:702
void DRW_shgroup_uniform_block(DRWShadingGroup *shgroup, const char *name, const GPUUniformBuf *ubo)
void DRW_shgroup_state_disable(DRWShadingGroup *shgroup, DRWState state)
void DRW_shgroup_uniform_texture(DRWShadingGroup *shgroup, const char *name, const GPUTexture *tex)
void DRW_shgroup_state_enable(DRWShadingGroup *shgroup, DRWState state)
void DRW_shgroup_call_procedural_triangles(DRWShadingGroup *shgroup, Object *ob, uint tri_count)
void DRW_shgroup_uniform_int_copy(DRWShadingGroup *shgroup, const char *name, const int value)
DRWShadingGroup * DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
DRWShadingGroup * DRW_shgroup_create_sub(DRWShadingGroup *shgroup)
void DRW_shgroup_uniform_texture_ref(DRWShadingGroup *shgroup, const char *name, GPUTexture **tex)
void DRW_shgroup_uniform_bool_copy(DRWShadingGroup *shgroup, const char *name, const bool value)
void DRW_shgroup_stencil_mask(DRWShadingGroup *shgroup, uint mask)
GPUTexture * DRW_texture_pool_query_fullscreen(eGPUTextureFormat format, DrawEngineType *engine_type)
static ulong state[N]
struct GPUTexture * depth_in_front
struct GPUTexture * gputexture
StudioLightImage matcap_specular
StudioLightImage matcap_diffuse
WORKBENCH_PassList * psl
WORKBENCH_StorageList * stl
struct GPUFrameBuffer * opaque_fb
struct DRWPass * composite_ps
struct DRWPass * opaque_infront_ps
struct DRWPass * merge_infront_ps
struct DRWPass * opaque_ps
struct DRWShadingGroup * vcol_shgrp
struct DRWShadingGroup * image_tiled_shgrp
struct DRWShadingGroup * common_shgrp
struct GHash * material_hash
struct DRWShadingGroup * image_shgrp
struct GPUUniformBuf * world_ubo
struct GPUUniformBuf * material_ubo_curr
struct GPUTexture * normal_buffer_tx
struct GPUTexture * material_buffer_tx
WORKBENCH_Prepass prepass[2][2][WORKBENCH_DATATYPE_MAX]
struct WORKBENCH_PrivateData * wpd
void workbench_opaque_cache_init(WORKBENCH_Data *vedata)
void workbench_opaque_engine_init(WORKBENCH_Data *data)
#define NORMAL_ENCODING_ENABLED()
GPUShader * workbench_shader_composite_get(WORKBENCH_PrivateData *wpd)
GPUShader * workbench_shader_opaque_image_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType data, bool tiled)
#define STUDIOLIGHT_TYPE_MATCAP_ENABLED(wpd)
GPUShader * workbench_shader_merge_infront_get(WORKBENCH_PrivateData *wpd)
eWORKBENCH_DataType
@ WORKBENCH_DATATYPE_MAX
GPUShader * workbench_shader_opaque_get(WORKBENCH_PrivateData *wpd, eWORKBENCH_DataType data)
#define SHADOW_ENABLED(wpd)
BLI_INLINE bool workbench_is_specular_highlight_enabled(WORKBENCH_PrivateData *wpd)